🔧 Nginx Reverse Proxy Guide

Configuration best practices for Docker & Kubernetes environments

Overview

Nginx is a high-performance HTTP server and reverse proxy, widely used in containerized environments. This guide covers essential configurations for production deployments.

💡 Tip: Always use the official Nginx image from Docker Hub: nginx:alpine for minimal footprint.

Key Features

Docker Docker Configuration

Basic docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
      - ./html:/usr/share/nginx/html:ro
    restart: unless-stopped
    networks:
      - proxy-network

  app:
    image: your-app:latest
    expose:
      - "3000"
    networks:
      - proxy-network

networks:
  proxy-network:
    driver: bridge

Reverse Proxy Configuration

upstream backend {
    server app:3000;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate     /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key /etc/nginx/certs/privkey.pem;
    
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        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;
    }
}

K8s Kubernetes Ingress

Nginx Ingress Controller

# Install via Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install nginx-ingress ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace

Ingress Resource

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: app-tls-secret
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: app-service
                port:
                  number: 80
⚠️ Warning: Always set resource limits for the Ingress Controller in production to prevent resource exhaustion.

SSL SSL/TLS Configuration

Recommended SSL Settings

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;

# Security Headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;

Let's Encrypt with Certbot

# Install Certbot
apt install certbot python3-certbot-nginx

# Obtain certificate
certbot --nginx -d example.com -d www.example.com

# Auto-renewal (cron)
0 0 * * * certbot renew --quiet

Performance Tuning

Directive Recommended Value Description
worker_processes auto Match CPU cores
worker_connections 4096 Max connections per worker
keepalive_timeout 65 Keep-alive connection timeout
gzip on Enable compression
gzip_comp_level 5 Compression level (1-9)

Caching Configuration

proxy_cache_path /var/cache/nginx levels=1:2 
                 keys_zone=my_cache:10m 
                 max_size=1g 
                 inactive=60m 
                 use_temp_path=off;

server {
    location / {
        proxy_cache my_cache;
        proxy_cache_valid 200 1h;
        proxy_cache_use_stale error timeout updating;
        add_header X-Cache-Status $upstream_cache_status;
    }
}