Running Nginx in Docker

Learn how to run an Nginx web server in Docker with proper port mapping, configuration mounting, and SSL setup. Covers reverse proxy configuration and static file serving patterns.

Real-World Stacks

Detailed Explanation

Production-Ready Nginx in Docker

Nginx is one of the most commonly dockerized services. A basic Nginx container with port mapping takes one command:

docker run -d --name nginx -p 80:80 nginx:alpine

This serves the default Nginx welcome page. Let's build up to a production configuration.

Serving Static Files

Mount your static website files into the container:

docker run -d \
  --name webserver \
  -p 80:80 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  nginx:alpine

The :ro flag makes the mount read-only, preventing the container from modifying your files.

Custom Nginx Configuration

Mount a custom nginx.conf to override the default configuration:

docker run -d \
  --name webserver \
  -p 80:80 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  nginx:alpine

Or mount additional server block configurations:

docker run -d \
  --name webserver \
  -p 80:80 -p 443:443 \
  -v $(pwd)/conf.d:/etc/nginx/conf.d:ro \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  nginx:alpine

Reverse Proxy Configuration

A common pattern is using Nginx as a reverse proxy in front of application containers:

docker network create web-tier

docker run -d --name api --network web-tier my-api-image
docker run -d --name nginx \
  --network web-tier \
  -p 80:80 \
  -v $(pwd)/proxy.conf:/etc/nginx/conf.d/default.conf:ro \
  nginx:alpine

Where proxy.conf contains:

server {
    listen 80;
    location / {
        proxy_pass http://api:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

SSL/TLS Termination

docker run -d \
  --name nginx \
  -p 80:80 -p 443:443 \
  -v $(pwd)/certs:/etc/nginx/certs:ro \
  -v $(pwd)/conf.d:/etc/nginx/conf.d:ro \
  nginx:alpine

Production Docker Run Command

docker run -d \
  --name nginx \
  --restart unless-stopped \
  --memory 256m \
  --cpus 1 \
  -p 80:80 \
  -p 443:443 \
  -v nginx-logs:/var/log/nginx \
  -v $(pwd)/conf.d:/etc/nginx/conf.d:ro \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/certs:/etc/nginx/certs:ro \
  nginx:alpine

This includes restart policy, resource limits, log persistence, read-only config mounts, and both HTTP and HTTPS ports.

Why nginx:alpine?

The Alpine-based image is significantly smaller (~40 MB vs ~140 MB for Debian-based), reducing pull times and attack surface. Use the Debian-based nginx:latest if you need additional system packages.

Use Case

Deploying a production web server that serves static files and acts as a reverse proxy for a backend API, with custom configuration, SSL certificates, and proper resource limits.

Try It — Docker Run Command Builder

Open full tool