Your site runs fine on Nginx, the DNS points where it should, port 80 is open, and yet the browser still slaps a “Not secure” label right next to your domain. Visitors see it, you see it, it judges you. Back in the day, fixing this meant buying a certificate from some authority and wiring it up by hand. This post gets HTTPS running on app1.domain.com for free, in about two minutes, using Certbot.
TL;DR: Install Certbot, issue a free SSL certificate for a domain, and let Nginx serve it over HTTPS with auto renewal.
Stack: Ubuntu, Nginx, Certbot, Let’s Encrypt, ACME
Level: Beginner
Reading time: ~4 min
I used to treat HTTPS as a chore I postponed until launch day, then spent the launch morning fighting OpenSSL flags instead of shipping. The first time I ran Certbot and watched it edit my Nginx config and add the redirect on its own, I felt slightly robbed of a struggle I had grown attached to. Good riddance.
Know the two roles first
Before any command, get this straight, because people mix them up constantly. Let’s Encrypt is the certificate authority: it actually issues and signs the certificate. Certbot is the client running on your server: it asks for the certificate, proves you control the domain, installs it, and configures Nginx. One is the notary, the other is the assistant standing in line for you.
The two of them talk over a protocol called ACME. Certbot drops a specific file on your domain, Let’s Encrypt tries to fetch it over the internet, and if it succeeds, it confirms you own the place and issues the certificate. That is exactly why your DNS has to resolve correctly and port 80 has to be open before you start. The acronym stands for Automatic Certificate Management Environment and is a real internet standard (RFC 8555), the Looney Tunes pun fully intended.
Install on Ubuntu
Install Certbot together with its Nginx plugin. The plugin is the piece that reads and rewrites your Nginx config for you, so you are not editing server blocks by candlelight.
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
Confirm Nginx already answers for the domain
Certbot validates the live domain, so app1.domain.com must already resolve to this server and have a server block listening on port 80. Quick sanity check:
sudo nginx -t
curl -I http://app1.domain.com
If nginx -t is happy and the curl returns a response from this box, you are ready.
Issue the certificate
One command does the whole dance: validation, issuing, and config rewrite.
sudo certbot --nginx -d app1.domain.com
It will ask for an email (for expiry warnings), the terms, and whether to redirect HTTP to HTTPS. Say yes to the redirect. Behind the scenes Certbot runs the ACME challenge, gets the signed certificate, edits your server block to listen on 443, and wires up the 301 from HTTP. The certificate files land in /etc/letsencrypt.
The 90-day catch, and why you don’t care
Let’s Encrypt certificates expire after 90 days, far shorter than the year-plus paid ones. This is deliberate: short lifetimes limit the blast radius if a key ever leaks, and they force everyone to automate instead of hand-renewing once a year and forgetting. Certbot installs a systemd timer that renews quietly before expiry. Confirm it works without touching anything real:
sudo certbot renew --dry-run
If that passes, you are done. The renewal runs on its own from here.
What you have done
You installed Certbot and its Nginx plugin, confirmed Nginx was serving app1.domain.com on port 80, issued a free Let’s Encrypt certificate through the ACME challenge, and let Certbot rewrite the config to serve HTTPS with an automatic redirect. The padlock is up, and the renewal timer means future-you never has to think about it again. The browser stopped judging you.
Next steps
- Add more domains: Pass extra -d flags (-d app1.domain.com -d www.app1.domain.com) to cover several names on one certificate.
- Inspect what you got: Run sudo certbot certificates to list issued certs, their domains, and expiry dates.
- Harden the TLS config: Tune ciphers and enable HSTS in Nginx once the basics work, then test the result on SSL Labs.
Questions or feedback? Find me on LinkedIn or GitHub.