DevOps
Free SSL with Certbot and Nginx on Ubuntu
Install Certbot with the Nginx plugin, walk through Let's Encrypt HTTP validation, turn on HTTPS redirects, and prove renewals with certbot renew --dry-run—the same checklist I use before calling a VPS production-ready.

If you are wiring HTTPS on a fresh Ubuntu box, Certbot plus the Nginx plugin is still the fastest honest path to a trusted certificate—no manual CSR drama, no paid CA unless you truly need OV or EV.
Before you run Certbot
Your domain's DNS A/AAAA records must point at this server, and something needs to answer on port 80 (usually Nginx) while Let's Encrypt completes HTTP validation.
What you will set up
- Issue a Let's Encrypt certificate through Certbot using the nginx plugin.
- Let Certbot rewrite server blocks so visitors land on HTTPS automatically.
- Prove auto-renewal works with
certbot renew --dry-runbefore you forget about the box for six months.
Before you start
- Ubuntu Server with sudo access.
- Nginx installed and serving your domain on HTTP—walk through how to install and configure Nginx on Ubuntu if you still need the baseline.
- DNS propagation finished so
yourdomain.comresolves to this machine's public IP. - When you want copy-ready
aptplus UFW ordering without prose, keep the nginx install and firewall snippet beside this tab.
Install Certbot and request a certificate
Update apt and install packages
Notice how the meta package pulls both Certbot and the Nginx integration shim:
# Refresh package indexes
sudo apt update
# Install Certbot plus the nginx automation plugin
sudo apt install certbot python3-certbot-nginx
Obtain certificates with certbot --nginx
Swap in every hostname that must appear on the certificate:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot walks through a short interview:
- Email — used for expiry notices; keep it current.
- Terms — type
Ato agree when prompted. - EFF mailing list — optional; I usually decline.
- HTTP → HTTPS redirect — choose the option that enables the redirect (typically
2).
Confirm HTTPS in the browser
Load https://yourdomain.com and confirm the padlock or TLS chip your browser shows—then spot-check http:// to verify the redirect fires.
Verify auto-renewal with certbot renew --dry-run
Ubuntu wires renewal hooks for you, but proof beats optimism:
sudo certbot renew --dry-run
Clean output here means renewals should succeed silently until Let's Encrypt changes something upstream—then you adjust once, not during an outage.
Troubleshooting common failures
Certbot fails validation or throws a vague error
sudo systemctl status nginx— confirm the daemon is active.sudo nginx -t— catch syntax issues before reload loops waste time.dig +short yourdomain.com— verify DNS matches this server's address.
Unable to bind to port 80
Something else is already listening—often another web stack or a stray apache2 instance:
sudo ss -lntp | grep ':80 '
Stop or re-home the conflicting service, reload Nginx, then rerun Certbot.
Pro tips for long-running servers
- Rotate the contact email with
sudo certbot update_accountwhen your inbox changes. - Peek at
sudo certbot certificatesquarterly—it lists expiry timelines without touching disks. - After major nginx upgrades, rerun
sudo certbot renew --dry-runjust like you would after editing TLS cipher suites.
Frequently asked questions
Do I need DNS pointing at my server first
Yes. Let's Encrypt must reach your server using the public hostname you pass to Certbot, so the domain's A or AAAA records should resolve to this machine before you run sudo certbot --nginx.
Why HTTP validation expects port 80
The default nginx plugin completes HTTP-01 challenges by serving temporary tokens over plain HTTP on port 80. If another process binds that port or your perimeter blocks it, validation fails even when HTTPS already looks fine in manual tests.
How certbot renew dry run proves renewal works
sudo certbot renew --dry-run walks the renewal hooks without swapping certificates. Errors surface DNS drift, nginx regressions, or stale firewall rules weeks before a certificate actually expires.
What to check when Certbot cannot bind to port 80
Identify the conflicting listener with sudo lsof -i :80 or sudo ss -lntp, stop the stray service, and reload nginx. Until port 80 answers for your hostname, HTTP validation cannot finish.
How automatic renewal is scheduled on Ubuntu
Ubuntu packages register systemd timers or cron hooks that call certbot renew quietly. You still validate behavior once with certbot renew --dry-run and read /var/log/letsencrypt/letsencrypt.log when notifications hint at failures.
Next steps
- Layer smarter routing with the nginx reverse proxy setup guide once upstream apps move off localhost sockets.
- Keep paste-ready nginx apt and UFW sequencing in the same toolbox—it's the fastest way to stay consistent when TLS work sits beside database hardening posts on this site.
- Prefer upstream answers? The Certbot documentation stays authoritative when plugin flags change between distro releases.
SSL surprises everyone once—grab coffee, fix DNS or port 80, rerun certbot --nginx, and you are back on track.
Written by Shashikant Dwivedi
Engineer, occasional writer, full-time noticer. Based in Prayagraj, India. New essays land roughly twice a month.
Keep reading
Adjacent essays.
The newsletter
New articles in your inbox.
Occasional articles on engineering, tooling, and software development practices. No marketing, no fluff — just the article, when it's ready.
Unsubscribe with one click. Your email never leaves the list.


