How to Set Up Nginx Reverse Proxy with Ssl Termination Using Docker and Let’s Encrypt Certbot
Learning how to set up Nginx reverse proxy with SSL termination using Docker and Let’s Encrypt Certbot is essential for modern web infrastructure. This configuration provides secure HTTPS connections while efficiently managing multiple backend services through containerized deployment.
A reverse proxy sits between clients and your backend servers, forwarding requests and responses. When combined with SSL termination, it handles encryption and decryption, reducing the computational load on your application servers. Docker containerization makes this setup portable and scalable, while Let’s Encrypt provides free SSL certificates.
This tutorial covers creating a complete Nginx reverse proxy setup with automatic SSL certificate management. You’ll learn to configure Docker containers, implement SSL termination, and automate certificate renewal. The result is a production-ready infrastructure that handles HTTPS traffic securely and efficiently.
The setup includes multiple containers working together: an Nginx proxy container, a Certbot container for certificate management, and your application containers. This architecture provides better security, easier maintenance, and improved performance for your web applications.
Prerequisites and Requirements for Nginx Reverse Proxy with SSL Termination
Before starting this tutorial on how to set up Nginx reverse proxy with SSL termination using Docker and Let’s Encrypt Certbot, ensure you have the following requirements in place.
You need a Linux server with root access and Docker installed. Ubuntu 20.04 or newer is recommended for this setup. Your server should have at least 1GB of RAM and 10GB of storage space available.
A registered domain name pointing to your server’s IP address is essential. The domain must resolve correctly before obtaining SSL certificates from Let’s Encrypt. You can verify this using the dig or nslookup command.
Install Docker and Docker Compose on your system. Most Linux distributions provide these packages through their package managers. You’ll also need basic knowledge of Docker containers, networking concepts, and command-line operations.
Ensure ports 80 and 443 are open in your firewall settings. Port 80 is required for Let’s Encrypt certificate validation, while port 443 handles HTTPS traffic. Close any existing web servers that might conflict with these ports.
The estimated time to complete this tutorial is 30-45 minutes, depending on your familiarity with Docker and server administration. Having a test application ready to proxy is helpful but not required, as we’ll include a simple example.
Step-by-Step Guide to Configure Nginx Reverse Proxy with Docker and SSL
Related article: How to Containerize a Node.js Web Application with Docker
Follow these numbered steps to implement how to set up Nginx reverse proxy with SSL termination using Docker and Let’s Encrypt Certbot effectively.
Step 1: Create the Project Directory Structure
Create a dedicated directory for your reverse proxy setup and organize the necessary configuration files:
mkdir -p ~/nginx-proxy/{nginx,certbot,html}
cd ~/nginx-proxy
touch docker-compose.yml
mkdir -p nginx/conf.d
This structure separates Nginx configurations, certificate storage, and static files. The organized approach makes maintenance easier and follows Docker best practices.
Step 2: Create the Docker Compose Configuration
Create the main docker-compose.yml file that defines all containers and their relationships:
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
- ./html:/var/www/html
depends_on:
- app
restart: unless-stopped
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
command: certonly --webroot --webroot-path=/var/www/certbot --email [email protected] --agree-tos --no-eff-email -d your-domain.com
app:
image: nginx:alpine
container_name: backend-app
volumes:
- ./html:/usr/share/nginx/html
expose:
- "80"
Replace [email protected] and your-domain.com with your actual email and domain name. The configuration creates three containers: the main Nginx proxy, Certbot for certificates, and a sample backend application.
Step 3: Configure Initial Nginx Settings
Create the initial Nginx configuration file at nginx/conf.d/default.conf:
server {
listen 80;
server_name your-domain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://app:80;
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;
}
}
This configuration handles both HTTP and HTTPS traffic. HTTP requests redirect to HTTPS, while HTTPS requests proxy to the backend application with proper headers.
Step 4: Create Sample Content and Obtain SSL Certificates
Create a simple HTML file for testing in the html directory:
echo "Hello from Nginx Reverse Proxy!
SSL termination is working correctly.
" > html/index.html
Start the containers to obtain SSL certificates. First, comment out the SSL-related lines in your Nginx config temporarily, then run:
docker-compose up -d nginx app
docker-compose run --rm certbot
docker-compose down
After obtaining certificates successfully, uncomment the SSL lines in your Nginx configuration and restart the containers.
Step 5: Implement Automatic Certificate Renewal
Create a renewal script and add it to your system’s cron jobs for automatic certificate renewal:
#!/bin/bash
cd ~/nginx-proxy
docker-compose run --rm certbot renew
docker-compose exec nginx nginx -s reload
Save this as renew-certs.sh, make it executable, and add to crontab:
chmod +x renew-certs.sh
echo "0 12 ~/nginx-proxy/renew-certs.sh" | crontab -
This setup checks for certificate renewal twice daily and reloads Nginx when certificates are renewed.
Troubleshooting Common Issues with Nginx Reverse Proxy SSL Setup
When implementing how to set up Nginx reverse proxy with SSL termination using Docker and Let’s Encrypt Certbot, several common issues may arise that require troubleshooting.
Certificate Validation Failures
If Let’s Encrypt fails to validate your domain, verify that your domain resolves to the correct IP address. Use dig your-domain.com to check DNS resolution. Ensure port 80 is accessible from the internet, as Let’s Encrypt needs to reach the /.well-known/acme-challenge/ path for validation.
Check your firewall settings and ensure no other services are binding to port 80. Sometimes, existing Apache or Nginx installations conflict with the containerized setup. Stop these services before running your Docker containers.
SSL Certificate Path Issues
If Nginx fails to start due to missing SSL certificates, you might be trying to use HTTPS configuration before obtaining certificates. Always obtain certificates first with HTTP-only configuration, then enable HTTPS settings.
Verify certificate file permissions and paths within the containers. The certificates should be readable by the Nginx process inside the container. Check volume mounts in your Docker Compose file to ensure proper path mapping.
Proxy Connection Problems
Backend connection failures often result from incorrect container networking. Ensure your backend containers are on the same Docker network as the Nginx proxy. Use container names (like app:80) instead of localhost for proxy_pass directives.
Check that backend containers expose the correct ports and are running properly. Use docker-compose logs to examine container logs for specific error messages that can guide your troubleshooting efforts.
Performance and Security Considerations
For production environments, consider implementing additional security headers and optimizing SSL settings. The official Nginx documentation provides comprehensive guidance on advanced configuration options.
Monitor certificate expiration dates and renewal processes regularly. Set up monitoring alerts to notify you of any renewal failures or SSL certificate issues before they affect your users.
Conclusion and Next Steps
You’ve successfully learned how to set up Nginx reverse proxy with SSL termination using Docker and Let’s Encrypt Certbot. This configuration provides a secure, scalable foundation for hosting web applications with automatic HTTPS encryption.
The setup includes automatic certificate renewal, proper SSL termination, and efficient request proxying to backend services. Your infrastructure now handles HTTPS traffic securely
