Skip to content

部署 Nginx

Nginx 是最常用的 Web 服务器和反向代理,本节介绍在 Docker 中部署 Nginx 的各种方式。

快速启动

bash
# 启动 Nginx,映射 80 端口
docker run -d --name nginx -p 80:80 nginx

# 访问测试
curl http://localhost

挂载自定义静态文件

bash
# 创建静态文件目录
mkdir -p ./html
echo "<h1>Hello Docker Nginx!</h1>" > ./html/index.html

# 挂载自定义文件
docker run -d \
  --name nginx \
  --restart unless-stopped \
  -p 80:80 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  nginx:alpine

挂载自定义配置

bash
# 先从容器中复制默认配置
docker run --rm nginx cat /etc/nginx/conf.d/default.conf > ./nginx.conf

# 或直接创建配置文件
cat > ./nginx.conf <<'EOF'
server {
    listen 80;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # 开启 gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    # 前端 SPA 路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
}
EOF

# 启动 Nginx
docker run -d \
  --name nginx \
  --restart unless-stopped \
  -p 80:80 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
  nginx:alpine

反向代理配置

Nginx 最常见的用途是反向代理后端服务:

bash
# 创建网络
docker network create app-net

# 启动后端服务
docker run -d \
  --name api \
  --network app-net \
  myapi:latest

# 创建反向代理配置
cat > ./proxy.conf <<'EOF'
upstream api_backend {
    server api:3000;
    # 多个后端实现负载均衡
    # server api2:3000;
    # server api3:3000;
}

server {
    listen 80;

    # 静态文件
    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    # API 代理
    location /api/ {
        proxy_pass http://api_backend/;
        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_connect_timeout 60s;
        proxy_read_timeout 60s;
    }
}
EOF

# 启动 Nginx 反向代理
docker run -d \
  --name nginx \
  --network app-net \
  --restart unless-stopped \
  -p 80:80 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/proxy.conf:/etc/nginx/conf.d/default.conf:ro \
  nginx:alpine

HTTPS 配置

bash
# 创建证书目录
mkdir -p ./ssl

# 自签名证书(开发测试用)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ./ssl/nginx.key \
  -out ./ssl/nginx.crt \
  -subj "/CN=localhost"

# HTTPS 配置
cat > ./nginx-ssl.conf <<'EOF'
server {
    listen 80;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name localhost;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    root /usr/share/nginx/html;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}
EOF

# 启动 HTTPS Nginx
docker run -d \
  --name nginx-ssl \
  --restart unless-stopped \
  -p 80:80 \
  -p 443:443 \
  -v $(pwd)/html:/usr/share/nginx/html:ro \
  -v $(pwd)/nginx-ssl.conf:/etc/nginx/conf.d/default.conf:ro \
  -v $(pwd)/ssl:/etc/nginx/ssl:ro \
  nginx:alpine

使用 Docker Compose

yaml
# docker-compose.yml
services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./ssl:/etc/nginx/ssl:ro
      - nginx-logs:/var/log/nginx
    networks:
      - web

  api:
    image: myapi:latest
    networks:
      - web
    expose:
      - "3000"

volumes:
  nginx-logs:

networks:
  web:

常用运维命令

bash
# 测试 Nginx 配置语法
docker exec nginx nginx -t

# 重新加载配置(不停机)
docker exec nginx nginx -s reload

# 查看访问日志
docker logs nginx

# 查看访问日志(实时)
docker logs -f nginx

# 进入容器调试
docker exec -it nginx sh

# 查看 Nginx 版本
docker exec nginx nginx -v

总结

使用场景配置要点
静态文件服务挂载 html 目录到 /usr/share/nginx/html
反向代理配置 proxy_pass 到后端容器名
HTTPS挂载 SSL 证书,配置 443 监听
负载均衡配置 upstream 多个后端
SPA 前端try_files $uri /index.html