Every modern website needs HTTPS, and thanks to Let's Encrypt, a trusted SSL certificate now costs exactly zero. If you already run a site on Nginx, the certbot Nginx plugin can fetch a certificate, install it, and configure the HTTPS redirect for you in a couple of commands. This guide walks you through the whole process on Ubuntu 24.04 (it works the same on 22.04), from DNS to automatic renewal.
Prerequisites
Before you start, make sure you have these in place:
- A server running Ubuntu 24.04 or 22.04 with Nginx already installed and serving your site.
- sudo access (or a root shell) on the server.
- A registered domain name whose
A(orAAAA) record points to your server's public IP. Bothexample.comandwww.example.comshould resolve if you plan to cover both. - Port 80 and 443 open in your firewall (and in your cloud provider's security group, if you use one).
Let's Encrypt validates that you control the domain by reaching your server over HTTP, so the DNS record must be live and pointing at this machine before you run Certbot.
Step 1: Confirm your domain resolves to the server
Check that the domain's DNS is actually pointing at your server. Run this from your local machine or the server:
dig +short example.com
dig queries the DNS and prints just the answer — the IP address the domain resolves to. Compare it with your server's public IP. If it shows the wrong IP (or nothing), fix the DNS A record at your registrar first, then wait for propagation before continuing.
While you're at it, verify Nginx answers on port 80:
curl -I http://example.com
A 200 response (or a 301 to your site) means Nginx is serving the domain over plain HTTP, which is exactly what the Let's Encrypt validation needs.
Step 2: Install Certbot and the Nginx plugin
On Ubuntu 24.04, Certbot ships in the default repositories and stays current enough that you no longer need the snap package. Install it together with the Nginx plugin:
sudo apt update
sudo apt install -y certbot python3-certbot-nginx
The first command refreshes the package index so you get the latest versions. The second installs certbot itself plus python3-certbot-nginx, the plugin that reads your Nginx server blocks, issues certificates, and edits your Nginx configuration automatically.
Confirm the install:
certbot --version
Any recent version (2.x or newer) works fine.
Step 3: Make sure your Nginx server_name is correct
The Nginx plugin reads your existing server blocks to figure out which domains to certify. Open your site's server block and check that server_name matches the domain exactly:
sudo nginx -t
nginx -t tests the configuration syntax without restarting anything. If it reports syntax is ok and test is successful, your config is valid. Now open your site's server block (usually in /etc/nginx/sites-available/) and look for:
server {
listen 80;
server_name example.com www.example.com;
...
}
If server_name is missing or set to a placeholder like _, set it to your real domain and reload Nginx with sudo systemctl reload nginx. Certbot will use these names as the certificate's domains.
Step 4: Obtain and install the certificate
Now run Certbot with the Nginx plugin. The simplest interactive form is:
sudo certbot --nginx -d example.com -d www.example.com
The -d flags list every domain the certificate should cover. Certbot will ask for an email address (used for expiry warnings and account recovery), ask you to agree to the terms of service, and then ask whether you want to redirect all HTTP traffic to HTTPS. Choose the redirect — there's almost no reason to keep serving plain HTTP.
If you prefer a fully non-interactive command (handy for scripts), pass everything up front:
sudo certbot --nginx --agree-tos --redirect -m admin@example.com \
-d example.com -d www.example.com
Here --agree-tos accepts the Let's Encrypt subscriber agreement, --redirect installs the HTTP-to-HTTPS redirect automatically, and -m supplies the contact email. Certbot performs the HTTP-01 challenge (it temporarily serves a token from your web root to prove you own the domain), downloads the certificate chain, and rewrites your Nginx server block to use it.
When it finishes, you'll see a "Congratulations!" message with the certificate paths — typically /etc/letsencrypt/live/example.com/fullchain.pem and /etc/letsencrypt/live/example.com/privkey.pem.
Step 5: Verify HTTPS is working
Check the redirect and the certificate from the command line:
curl -vI https://example.com 2>&1 | grep -E "SSL|subject|start date"
You should see SSL connection details and a subject line showing your domain. A cleaner end-to-end test:
curl -I http://example.com
This should return HTTP/1.1 301 Moved Permanently with a Location: https://example.com/ header — proof that all plain-HTTP traffic is being pushed to HTTPS.
Then open https://example.com in a browser and confirm the padlock icon. For a deeper check, run the domain through Qualys SSL Labs — with Certbot's default settings you should land at an A or A+ rating.
Step 6: Set up automatic renewal
Let's Encrypt certificates expire after 90 days, so renewal must be automatic. The Ubuntu package ships a systemd timer that already handles this. Confirm it's active:
sudo systemctl status certbot.timer
You want to see active (waiting). The timer runs certbot -q renew twice a day, and it only contacts Let's Encrypt when a certificate is within 30 days of expiry.
Test the renewal logic without actually renewing (a dry run):
sudo certbot renew --dry-run
A successful dry run ends with "The dry run was successful." Since renewal rewrites the same Nginx configuration Certbot already set up, it works silently in the background. If you want renewal notifications, keep an eye on the email address you registered.
Common issues & fixes
1. "Failed authorization" — DNS problem
The most common failure. Certbot says the domain could not be validated because the challenge token was unreachable. Causes: the DNS A record points at the wrong server, propagation hasn't finished, or you're certifying www.example.com while only the bare domain resolves. Fix the DNS, wait, and rerun with exactly the domains that resolve.
2. Port 80 is blocked
The HTTP-01 challenge requires inbound port 80, even if you only ever serve HTTPS. If Certbot times out, open port 80 in UFW and in your cloud firewall:
sudo ufw allow 'Nginx Full'
Nginx Full opens both port 80 (HTTP) and port 443 (HTTPS) in one step.
3. "Too many certificates already issued" — rate limits
Let's Encrypt allows 50 certificates per registered domain per week, and only 5 duplicate certificates per week for the same set of domains. If you were testing repeatedly and hit the limit, wait a week before retrying, or use --staging to test against the staging server:
sudo certbot --nginx --staging -d example.com
The staging server issues untrusted certificates but doesn't count against your limits — perfect for practice.
4. Redirect loop after enabling HTTPS
If your app also forces HTTPS internally (a CMS setting, or a X-Forwarded-Proto check behind a proxy), the browser can bounce between HTTP and HTTPS forever. Certbot's redirect looks like this — don't duplicate it elsewhere:
if ($host = example.com) {
return 301 https://$host$request_uri;
}
Remove the duplicate redirect from your application or proxy config and keep just this one.
5. Renewal silently fails
If a renewal stops working months later, the usual culprit is a firewall change that closed port 80, or a manually edited Nginx block that broke the plugin's expectations. Run sudo certbot renew --dry-run now and then (or monitor the timer with systemctl list-timers certbot.timer) so a problem surfaces before the certificate actually expires.
Verify it worked
curl -I https://example.comreturns200 OKover HTTPS.curl -I http://example.comreturns a301redirect tohttps://.- Your browser shows the padlock, and SSL Labs rates the site A or better.
sudo certbot renew --dry-runsucceeds, andcertbot.timeris active.
Conclusion
You now have a free, trusted SSL certificate on Nginx, an automatic HTTP-to-HTTPS redirect, and a renewal timer that keeps it valid forever with no further work. The total time investment is under ten minutes — there's no excuse left for a production site to run on plain HTTP.
If you'd rather not touch server configs yourself, XpertBees sets up and hardens Nginx, SSL, and full LEMP/LAMP stacks for clients — reach out and we'll have your site on HTTPS the same day.



