How to Set Up Nginx as a Reverse Proxy with Ssl for Docker Containers

Learning how to set up Nginx as a reverse proxy with SSL for Docker containers is essential for modern web deployment. This configuration allows you to route traffic securely to multiple containerized applications while maintaining SSL encryption. You’ll create a scalable infrastructure that handles multiple services behind a single entry point.

Nginx reverse proxy configurations provide several benefits for Docker environments. You can load balance traffic across multiple container instances. SSL termination happens at the proxy level, reducing computational overhead on your application containers. This setup also enables you to serve multiple domains or subdomains from a single server.

This tutorial covers the complete process from initial Nginx installation to SSL certificate configuration. You’ll learn to create Docker networks, configure proxy settings, and implement SSL certificates using Let’s Encrypt. By the end, you’ll have a production-ready reverse proxy setup that can scale with your application needs.

The configuration we’ll build supports both HTTP and HTTPS traffic. It automatically redirects HTTP requests to HTTPS for security. You’ll also learn to handle WebSocket connections and static file serving through the proxy.

Prerequisites and Requirements for Setting Up Nginx as a Reverse Proxy with SSL for Docker Containers

Before you begin this tutorial, ensure you have the necessary components installed and configured. You’ll need a Ubuntu 20.04 or 22.04 server with root access. Docker and Docker Compose must be installed and running on your system.

Your server should have a public IP address with domain names pointing to it. You’ll need at least two domains or subdomains for testing the reverse proxy functionality. Ensure ports 80 and 443 are open in your firewall configuration.

Basic knowledge of Docker containers and networking concepts is helpful. You should understand how to create and manage Docker containers. Familiarity with Nginx configuration files will make this tutorial easier to follow.

The estimated completion time is 45-60 minutes. This includes downloading certificates and testing the configuration. Make sure you have administrative access to your domain’s DNS settings for certificate validation.

Install Docker if you haven’t already:

sudo apt update
sudo apt install docker.io docker-compose -y
sudo systemctl enable docker
sudo systemctl start docker
sudo usermod -aG docker $USER

Step-by-Step Guide to Configure Nginx Reverse Proxy with SSL for Docker Containers

Another fascinating historical case is: How to Configure Opnsense Firewall Rules for Network Segmentation

Step 1: Create the project directory structure and Docker network

First, create a dedicated directory for your reverse proxy configuration. This keeps all related files organized and makes management easier.

mkdir ~/nginx-proxy
cd ~/nginx-proxy
mkdir nginx-config ssl-certs docker-apps

Create a custom Docker network for container communication. This network allows your Nginx container to communicate with application containers using container names as hostnames.

docker network create nginx-proxy-network

Step 2: Create sample application containers

Create two simple web applications to demonstrate the reverse proxy functionality. These containers will serve different content on different domains.

Create the first application:

mkdir docker-apps/app1
cat > docker-apps/app1/index.html << 'EOF'


App 1

    

Welcome to Application 1

This is served through Nginx reverse proxy The How to Set Up Nginx as a Reverse Proxy with Ssl for Docker Containers stands as a significant historical event.

EOF

Create the second application:

mkdir docker-apps/app2
cat > docker-apps/app2/index.html << 'EOF'


App 2

    

Welcome to Application 2

This is also served through Nginx reverse proxy

EOF

Step 3: Configure Nginx reverse proxy settings

Create the main Nginx configuration file. This configuration handles SSL termination and routes traffic to appropriate backend containers.

cat > nginx-config/nginx.conf << 'EOF'
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # SSL Configuration
    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;

    # Gzip Settings
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;

    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

    include /etc/nginx/conf.d/.conf;
}
EOF

Create virtual host configurations for each application:

cat > nginx-config/app1.conf << 'EOF'
server {
    listen 80;
    server_name app1.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name app1.yourdomain.com;

    ssl_certificate /etc/ssl/certs/app1.yourdomain.com.crt;
    ssl_certificate_key /etc/ssl/private/app1.yourdomain.com.key;

    location / {
        proxy_pass http://app1: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;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }
}
EOF
cat > nginx-config/app2.conf << 'EOF'
server {
    listen 80;
    server_name app2.yourdomain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name app2.yourdomain.com;

    ssl_certificate /etc/ssl/certs/app2.yourdomain.com.crt;
    ssl_certificate_key /etc/ssl/private/app2.yourdomain.com.key;

    location / {
        proxy_pass http://app2: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;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;
    }
}
EOF

Step 4: Generate SSL certificates using Let’s Encrypt

Install Certbot for SSL certificate generation. The official Certbot documentation provides detailed installation instructions for various systems.

sudo apt install certbot -y

Generate certificates for your domains. Replace the domain names with your actual domains:

sudo certbot certonly --standalone --preferred-challenges http -d app1.yourdomain.com
sudo certbot certonly --standalone --preferred-challenges http -d app2.yourdomain.com

Copy the certificates to your project directory:

sudo cp /etc/letsencrypt/live/app1.yourdomain.com/fullchain.pem ssl-certs/app1.yourdomain.com.crt
sudo cp /etc/letsencrypt/live/app1.yourdomain.com/privkey.pem ssl-certs/app1.yourdomain.com.key
sudo cp /etc/letsencrypt/live/app2.yourdomain.com/fullchain.pem ssl-certs/app2.yourdomain.com.crt
sudo cp /etc/letsencrypt/live/app2.yourdomain.com/privkey.pem ssl-certs/app2.yourdomain.com.key
sudo chown $USER:$USER ssl-certs/

Step 5: Create Docker Compose configuration

Create a comprehensive Docker Compose file that defines all services and their relationships:

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
nginx:
image: nginx:alpine
container_name: nginx-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx-config/nginx.conf:/etc/nginx/nginx.conf:ro
- ./nginx-config/app1.conf:/etc/nginx/conf.d/app1.conf:ro
- ./nginx-config/app2.conf:/etc/nginx/conf.d/app2.conf:ro
- ./ssl-certs:/etc/ssl/certs:ro
- ./ssl-certs:/etc/ssl/private:ro
networks:
- nginx-proxy-network
restart: unless-stopped
depends_on:
- app1
- app2

app1:
image: nginx:alpine
container_name: app1
volumes:
- ./docker-apps/app1:/usr/share/nginx/html:ro
networks:
- nginx-proxy-network

Similar Posts