Step-by-step Certbot + Nginx setup. Follow this on your server after reading the lesson. DigitalOcean →
Certbot is the official ACME client for Let's Encrypt. It requests a certificate, validates your domain ownership, and automatically edits your Nginx config to add SSL.
# 1. Install Certbot (Ubuntu)
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# 2. Your Nginx must already have a server block for your domain
# and port 80 must be open in your firewall
# 3. Get certificate + auto-configure Nginx
sudo certbot --nginx -d yourapp.com -d www.yourapp.com
# Certbot will:
# - Prove domain ownership via HTTP challenge
# - Issue certificate from Let's Encrypt
# - Modify your Nginx config to add ssl_certificate lines
# - Set up HTTP→HTTPS redirect
# - Schedule automatic renewal
# 4. Test renewal (won't actually renew)
sudo certbot renew --dry-run
# 5. List your certificates
sudo certbot certificates
Certbot validates domain ownership by making an HTTP request to your domain. Your A record must point to the server you're running Certbot on, or the challenge will fail. Let's Encrypt also supports a DNS challenge for wildcard certs.
For *.yourapp.com (covering api, cdn, admin, etc.), use the DNS challenge:
# Get wildcard cert via DNS challenge
sudo certbot certonly \
--manual \
--preferred-challenges dns \
-d yourapp.com \
-d "*.yourapp.com"
# Certbot will ask you to add a TXT record to your DNS:
# _acme-challenge.yourapp.com → "some-token-value"
# Add it in Cloudflare/Route53, wait 30-60s for propagation, then press Enter
Certbot installs a systemd timer (or cron job) that runs twice daily and renews certs expiring within 30 days. Check it:
# Check the renewal timer
sudo systemctl status certbot.timer
# Manually trigger renewal (without --dry-run)
sudo certbot renew
# Certbot also runs a post-renewal hook to reload Nginx
# Usually auto-configured at: /etc/letsencrypt/renewal-hooks/deploy/
# After running certbot --nginx, your config gains:
ssl_certificate /etc/letsencrypt/live/yourapp.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourapp.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# And an HTTP redirect block:
server {
listen 80;
server_name yourapp.com www.yourapp.com;
return 301 https://$host$request_uri;
}
Certbot marks sections of your Nginx config with comments. Editing between these markers may break renewal. Put your custom SSL settings outside the managed sections.
If you're using AWS CloudFront or an ALB, use ACM for free certificates — no Certbot needed. ACM handles renewal automatically.
# Via AWS CLI — request a certificate
aws acm request-certificate \
--domain-name yourapp.com \
--subject-alternative-names "*.yourapp.com" \
--validation-method DNS \
--region us-east-1
# ACM gives you CNAME records to add to DNS for validation
# Once validated, use the certificate ARN in CloudFront/ALB