Certbot — Automate Let's Encrypt TLS Certificates
Practical guide to Certbot — issue, auto-renew and manage Let's Encrypt TLS certificates, with plugins for Apache, NGINX and DNS challenges.
Certbot is the EFF's official ACME client and the standard way to obtain free TLS certificates from Let's Encrypt. A single command lets you issue certificates, install them straight into Apache or NGINX and set up automatic renewal. Plugins for webroot, standalone and DNS challenges cover every server setup – including wildcard certificates via DNS-01. This guide walks you through the key commands, from your first certificate to unattended renewal via a systemd timer.
Obtaining Certificates
certbot certonly --webroot -w <webroot> -d <domain> — Obtain a certificate using the webroot method (no server restart needed).
certbot certonly --webroot -w /var/www/html -d example.com -d www.example.comcertbot certonly --standalone -d <domain> — Obtain a certificate using a temporary standalone server (requires port 80 free).
certbot certonly --standalone -d example.comcertbot certonly --nginx -d <domain> — Obtain a certificate using the NGINX plugin (auto-configures NGINX).
certbot certonly --nginx -d example.com -d www.example.comcertbot certonly --apache -d <domain> — Obtain a certificate using the Apache plugin (auto-configures Apache).
certbot certonly --apache -d example.comcertbot certonly --dns-<provider> -d <domain> — Obtain a certificate using DNS-01 challenge (for wildcards and internal servers).
certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/cloudflare.ini -d '*.example.com'certbot certonly --manual -d <domain> — Obtain a certificate with manual challenge steps (interactive).
certbot certonly --manual -d example.com --preferred-challenges dnscertbot --preferred-challenges http — Specify the preferred challenge type (http-01 or dns-01).
certbot certonly --standalone --preferred-challenges http -d example.comAuto-Install (Server Plugins)
certbot --nginx — Obtain and automatically install a certificate for NGINX.
certbot --nginx -d example.com -d www.example.comcertbot --apache — Obtain and automatically install a certificate for Apache.
certbot --apache -d example.com -d www.example.comcertbot --nginx --redirect — Install certificate and automatically add HTTP to HTTPS redirect.
certbot --nginx --redirect -d example.comcertbot --nginx --no-redirect — Install certificate without adding a redirect.
certbot --nginx --no-redirect -d example.comcertbot install --cert-name <name> — Install a previously obtained certificate into the web server.
certbot install --nginx --cert-name example.comCertificate Management
certbot certificates — List all certificates managed by Certbot with their details.
certbot certificatescertbot renew — Renew all certificates that are due for renewal.
certbot renewcertbot renew --dry-run — Test the renewal process without actually renewing.
certbot renew --dry-runcertbot renew --force-renewal — Force renewal of all certificates regardless of expiry.
certbot renew --force-renewalcertbot renew --cert-name <name> — Renew a specific certificate by name.
certbot renew --cert-name example.comcertbot delete --cert-name <name> — Delete a certificate and its associated files.
certbot delete --cert-name old.example.comcertbot update_symlinks — Fix broken symlinks in the live directory.
certbot update_symlinksRenewal Hooks
certbot renew --pre-hook "<command>" — Run a command before attempting renewal (e.g., stop a service).
certbot renew --pre-hook "systemctl stop nginx"certbot renew --post-hook "<command>" — Run a command after a renewal attempt (whether successful or not).
certbot renew --post-hook "systemctl start nginx"certbot renew --deploy-hook "<command>" — Run a command only after a successful renewal.
certbot renew --deploy-hook "systemctl reload nginx"/etc/letsencrypt/renewal-hooks/deploy/ — Place executable scripts here to run automatically after successful renewals.
#!/bin/bash
systemctl reload nginx/etc/letsencrypt/renewal-hooks/pre/ — Scripts run before each renewal attempt.
ls /etc/letsencrypt/renewal-hooks/pre//etc/letsencrypt/renewal-hooks/post/ — Scripts run after each renewal attempt.
ls /etc/letsencrypt/renewal-hooks/post/Certificate Options
certbot --key-type ecdsa — Request an ECDSA certificate (smaller, faster than RSA).
certbot certonly --nginx --key-type ecdsa -d example.comcertbot --rsa-key-size <bits> — Set the RSA key size (default: 2048).
certbot certonly --nginx --rsa-key-size 4096 -d example.comcertbot --email <email> — Set the email for urgent renewal and security notices.
certbot --email admin@example.com -d example.comcertbot --agree-tos — Agree to the Let's Encrypt Terms of Service non-interactively.
certbot --agree-tos --email admin@example.com -d example.comcertbot --non-interactive — Run in non-interactive mode (fail rather than prompt).
certbot certonly --non-interactive --webroot -w /var/www/html -d example.comcertbot --expand -d <domains> — Add domains to an existing certificate.
certbot --expand -d example.com -d blog.example.com -d shop.example.comcertbot --cert-name <name> -d <new-domains> — Replace the domain list for an existing certificate.
certbot --cert-name example.com -d example.com -d www.example.com -d api.example.comFile Locations
/etc/letsencrypt/live/<domain>/fullchain.pem — The full certificate chain (cert + intermediate). Use this for ssl_certificate in NGINX.
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;/etc/letsencrypt/live/<domain>/privkey.pem — The private key. Use this for ssl_certificate_key in NGINX.
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;/etc/letsencrypt/live/<domain>/cert.pem — The server certificate only (without chain).
cat /etc/letsencrypt/live/example.com/cert.pem/etc/letsencrypt/live/<domain>/chain.pem — The intermediate certificate(s) only.
cat /etc/letsencrypt/live/example.com/chain.pem/etc/letsencrypt/renewal/<domain>.conf — Renewal configuration file for a certificate.
cat /etc/letsencrypt/renewal/example.com.conf/var/log/letsencrypt/letsencrypt.log — Certbot log file for troubleshooting.
tail -100 /var/log/letsencrypt/letsencrypt.logAutomation & Cron
0 0,12 * * * certbot renew --quiet — Recommended cron job: attempt renewal twice daily (only renews if due).
0 0,12 * * * /usr/bin/certbot renew --quietsystemctl list-timers | grep certbot — Check if systemd auto-renewal timer is active.
systemctl list-timers | grep certbotsystemctl status certbot.timer — Check the status of the certbot systemd timer.
systemctl status certbot.timercertbot renew --quiet --deploy-hook "systemctl reload nginx" — Auto-renewal with automatic NGINX reload on success.
0 3 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"Testing & Staging
certbot --staging — Use the Let's Encrypt staging server (higher rate limits, untrusted certs).
certbot certonly --staging --nginx -d test.example.comcertbot --dry-run — Simulate the certificate request without saving anything.
certbot certonly --dry-run --webroot -w /var/www/html -d example.comcertbot revoke --cert-path <path> — Revoke a certificate (e.g., if the private key was compromised).
certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pemcertbot revoke --cert-path <path> --reason keycompromise — Revoke with a specific reason code.
certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem --reason keycompromise Conclusion
Certbot takes the entire certificate lifecycle off your hands: once configured, your certificates renew unattended through the systemd timer or a cron job. When setting things up and testing, mind the Let's Encrypt rate limits and use --dry-run or --staging instead of spending real requests. Reach for --force-renewal only when you truly need it – every forced renewal counts against your rate limit. Verify automatic renewal regularly with certbot renew --dry-run.
Further Reading
- Certbot – official documentation – reference and guides
- certbot.eff.org – the EFF's interactive setup instructions
- Let's Encrypt – background, rate limits and documentation