Lets Encrypt SSL Setup with Nginx
This guide shows how to obtain SSL certificates using Nginx, then remove Nginx while keeping the certificates and auto-renewal for use with Docker containers.
Prerequisites
- Ubuntu 24.04 LTS (or similar Debian-based system)
- Root access to the server
- Domain pointing to your server's IP address
- Ports 80 and 443 accessible from the internet
Step 1: System Update and Package Installation
Update your system and install required packages:
# Update package list
apt update
# Install Certbot, Nginx, and the Certbot Nginx plugin
apt install -y certbot python3-certbot-nginx nginx
Step 2: Verify Nginx is Running
Check that Nginx started successfully:
systemctl status nginx
You should see Active: active (running)
in the output.
Step 3: Create Basic Nginx Configuration
Create a basic configuration for your domain (replace your-domain.com
with your actual domain):
cat > /etc/nginx/sites-available/your-domain.com << 'NGINXEOF'
server {
listen 80;
server_name your-domain.com;
location / {
return 200 'Hello from your-domain.com - SSL setup in progress';
add_header Content-Type text/plain;
}
# For Let's Encrypt verification
location /.well-known/acme-challenge/ {
root /var/www/html;
}
}
NGINXEOF
Enable the site:
# Create symbolic link to enable the site
ln -s /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/
# Test Nginx configuration
nginx -t
# Reload Nginx
systemctl reload nginx
Step 4: Verify DNS Configuration
Make sure your domain points to your server:
# Check your server's public IP
curl -4 ifconfig.me
# Check if domain resolves to your IP
nslookup your-domain.com
# Alternative: Check with Google DNS
nslookup your-domain.com 8.8.8.8
Test HTTP access:
# Test with domain (if DNS has propagated)
curl http://your-domain.com
# Alternative: Test with IP and Host header
curl -H "Host: your-domain.com" http://YOUR_SERVER_IP
Step 5: Obtain SSL Certificate
Use Certbot to obtain and install the SSL certificate:
certbot --nginx -d your-domain.com --agree-tos --no-eff-email --email your-email@domain.com
Important notes:
- Replace
your-domain.com
with your actual domain - Replace
your-email@domain.com
with your actual email - The
--agree-tos
flag accepts Let's Encrypt's Terms of Service - The
--no-eff-email
flag opts out of EFF communications
Step 6: Verify SSL Certificate Installation
Check that the certificate was installed successfully:
# List all certificates
certbot certificates
# View the updated Nginx configuration
cat /etc/nginx/sites-available/your-domain.com
You should see SSL configuration has been automatically added by Certbot.
Test HTTPS access:
# Test HTTPS (if DNS has propagated)
curl https://your-domain.com
# Alternative: Test with IP and Host header
curl -H "Host: your-domain.com" https://YOUR_SERVER_IP --insecure
Step 7: Verify Auto-Renewal Setup
Check that automatic renewal is configured:
# Check Certbot timer status
systemctl status certbot.timer
# Test renewal process (dry run)
certbot renew --dry-run
Step 8: Remove Nginx (Keep Certificates)
Now that we have the certificates, we can remove Nginx while preserving the certificates and renewal system:
8.1 Stop and Disable Nginx
# Stop Nginx service
systemctl stop nginx
# Disable Nginx from starting at boot
systemctl disable nginx
8.2 Remove Nginx Packages
# Remove Nginx and related packages (keep Certbot)
apt remove --purge -y nginx nginx-common python3-certbot-nginx
# Clean up Nginx configuration directory
rm -rf /etc/nginx
8.3 Re-enable Certbot Auto-Renewal
Since removing the Nginx plugin may have disabled the timer, re-enable it:
# Enable and start Certbot timer
systemctl enable certbot.timer
systemctl start certbot.timer
# Verify timer is active
systemctl status certbot.timer
Step 9: Verify Final Setup
9.1 Check Certificate Location
# List certificates
certbot certificates
# Check certificate files
ls -la /etc/letsencrypt/live/your-domain.com/
9.2 Verify Ports are Free
# Check that ports 80 and 443 are free for Docker
ss -tlnp | grep -E ':80|:443'
No output means the ports are free.
9.3 Test Certificate Renewal
# Test renewal (this won't actually renew unless close to expiry)
certbot renew --dry-run
Step 10: Using Certificates with Docker
Now you can use the certificates in your Docker containers:
Docker Compose Example
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro # Mount certificates
restart: unless-stopped
Nginx Configuration for Docker
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Include SSL security settings
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
# Proxy to your application
proxy_pass http://your-app:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Certificate Information
- Certificate Path:
/etc/letsencrypt/live/your-domain.com/fullchain.pem
- Private Key Path:
/etc/letsencrypt/live/your-domain.com/privkey.pem
- Certificate Type: ECDSA (modern and secure)
- Validity: 90 days (auto-renewed)
- Auto-Renewal: Runs twice daily via systemd timer
Troubleshooting
DNS Issues
# Check DNS propagation
dig +short your-domain.com
nslookup your-domain.com 8.8.8.8
Certificate Issues
# Check certificate details
openssl x509 -in /etc/letsencrypt/live/your-domain.com/fullchain.pem -text -noout
# Check certificate expiry
certbot certificates
Renewal Issues
# Check renewal logs
tail -f /var/log/letsencrypt/letsencrypt.log
# Manual renewal test
certbot renew --dry-run
Security Notes
- Certificate Files Permissions: The private key is only readable by root
- Auto-Renewal: Certificates are automatically renewed 30 days before expiry
- Docker Access: Mount certificates as read-only in containers
- Backup: Consider backing up
/etc/letsencrypt/
directory
Summary
After following this guide, you will have:
✅ SSL certificates installed for your domain ✅ Automatic certificate renewal configured ✅ Nginx removed from the system ✅ Ports 80 and 443 free for Docker containers ✅ Certificates ready to use in Docker/containerized applications
The certificates will automatically renew every 60 days, ensuring your SSL setup remains valid without manual intervention.