SKDBLOG

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.

Shashikant Dwivedi
5 min read
Free SSL with Certbot and Nginx on Ubuntu
DevOps05 MIN

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-run before you forget about the box for six months.

Before you start

Install Certbot and request a certificate

Update apt and install packages

Notice how the meta package pulls both Certbot and the Nginx integration shim:

bash
# 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:

bash
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 A to 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:

bash
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:

bash
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_account when your inbox changes.
  • Peek at sudo certbot certificates quarterly—it lists expiry timelines without touching disks.
  • After major nginx upgrades, rerun sudo certbot renew --dry-run just 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

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.

All writing →

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.