Objective
Use certbot to obtain a Let’s Encrypt certificate, configure nginx to terminate TLS with it, and verify a renewal.
Tasks
Task 1: Install certbot
sudo apt-get update
sudo apt-get install -y certbot
Task 2: Issue a certificate
sudo certbot certonly --standalone -d lab.example.com \
--agree-tos -m ops@example.com --no-eff-email
The cert is at /etc/letsencrypt/live/lab.example.com/.
Task 3: Run nginx with the certificate
mkdir -p ~/tls-lab && cd ~/tls-lab
cat > nginx.conf <<EOF
events {}
http {
server {
listen 443 ssl;
server_name lab.example.com;
ssl_certificate /etc/letsencrypt/live/lab.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lab.example.com/privkey.pem;
location / { return 200 "ok\\n"; }
}
}
EOF
docker run -d --name nginx-tls -p 443:443 \
-v $PWD/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /etc/letsencrypt:/etc/letsencrypt:ro \
nginx:1.27
Task 4: Verify the certificate is live
echo | openssl s_client -connect lab.example.com:443 -servername lab.example.com 2>/dev/null | \
openssl x509 -noout -dates -subject
You should see notAfter ~90 days in the future and the subject
matching lab.example.com.
Task 5: Simulate renewal (staging)
sudo certbot renew --dry-run
Task 6: Real renewal
sudo certbot renew --force-renewal
sudo docker exec nginx-tls nginx -s reload
Task 7: Verify the new cert is live
echo | openssl s_client -connect lab.example.com:443 -servername lab.example.com 2>/dev/null | \
openssl x509 -noout -dates -serial
A new serial number confirms the cert was rotated.
Task 8: Cleanup
docker rm -f nginx-tls