Linux Admin

Install Certbot for Let’s Encrypt

Practical Linux guide: install Certbot for Let’s Encrypt without the usual guesswork.

14 min read Intermediate Updated 9 Jun 2026

Step-by-step guide

Work through each section in order. Stop when your issue is resolved — you do not need every step for every situation.

What you will achieve

Free TLS certificates from Let's Encrypt on Ubuntu with Certbot — Apache or Nginx plugin, auto-renewal via systemd timer.

1) Install Certbot

sudo apt install certbot python3-certbot-nginx
# or python3-certbot-apache

2) Obtain certificate

sudo certbot --nginx -d example.com -d www.example.com

DNS must point to this server; ports 80/443 open in UFW.

3) Dry run renewal

sudo certbot renew --dry-run

4) Timer

systemctl list-timers | grep certbot

Verify

sudo certbot certificates
curl -vI https://example.com 2>&1 | grep expire

5) Standalone mode (no web server yet)

sudo certbot certonly --standalone -d example.com

Stops port 80 binding — schedule during maintenance if Apache/nginx running.

6) DNS challenge (wildcard)

sudo apt install python3-certbot-dns-cloudflare
# credentials in /root/.secrets/cloudflare.ini

7) Post-renewal hook

# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
#!/bin/bash
systemctl reload nginx

Rate limits

Let's Encrypt limits certificates per registered domain per week — use staging server (--staging) when testing automation.

8) EFF certbot terms

Automated renewals need port 80 or DNS API reachable — firewall changes breaking renewals expire certs silently until browsers complain.

Prerequisites

Public DNS pointing to server. Ports 80 and/or 443 reachable from internet. nginx or apache vhost with server_name matching cert domain. Email for expiry notices.

webroot mode with running server

sudo certbot certonly --webroot -w /var/www/html -d example.com

certbot renew hook

sudo certbot renew --deploy-hook 'systemctl reload nginx'

Reload only when cert actually renewed — avoids unnecessary nginx reloads twice daily.

wildcard and internal names

Let's Encrypt won't issue for .local — use real domain or internal CA for lab. Wildcard needs DNS challenge — HTTP-01 cannot prove *.example.com ownership.

ACME v2 staging rate limits

Hitting failed validation rate limit blocks production attempts — always dry-run staging when automating new host pattern.

multi-domain san cert

One certbot invocation with -d app -d api -d www covers SAN cert — nginx server_name blocks can share single cert path in ssl_certificate directive.

certbot certificates renewal hook

Deploy hook reloads nginx only when cert within 30 days expiry renewed — check certbot logs in /var/log/letsencrypt for auth failure patterns after firewall change.

ipv6 AAAA record

Certbot validates all resolved addresses — broken AAAA pointing nowhere causes intermittent renewal failure — fix DNS or remove AAAA.

nginx plugin vs standalone

Plugin preferred on live site — standalone requires stopping nginx briefly on port 80 conflict.

Certificate transparency

After issuance verify cert appears in crt.sh for your domain — confirms legitimate CA path not mis-issued test cert left from staging botched run.

Related guides

certbot encrypt install lets linux