跳到主要内容

Docker 部署 Nginx

Nginx 可作为静态文件服务器、反向代理和 TLS 终止层。本页使用通用的 app:8080 作为后端服务,不依赖任何具体项目。

目录结构

nginx-demo/
├── compose.yaml
└── nginx/
└── default.conf

反向代理配置

创建 nginx/default.conf

nginx/default.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

upstream backend {
server app:8080;
}

server {
listen 80;
server_name _;

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;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}

这里的 app 是同一 Compose 网络中的服务名。若后端在 Docker 外部,应换成容器能够访问的实际主机名或地址,不能直接假设容器内的 localhost 指向宿主机。

Compose 配置

compose.yaml
services:
nginx:
image: nginx:1-alpine
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app

app:
image: <backend-image>:<tag>
expose:
- "8080"

depends_on 只负责启动顺序,不等于后端已经可用。后端应用仍应提供健康检查和重试机制。

启动前先校验最终配置和 Nginx 语法:

docker compose config
docker compose run --rm nginx nginx -t
docker compose up -d

验证与查看日志:

curl --fail http://localhost:8080/
docker compose logs --tail 200 -f nginx

修改 default.conf 后重新检查并平滑加载:

docker compose exec nginx nginx -t
docker compose exec nginx nginx -s reload

静态文件服务

如果只需要托管静态文件,可把站点目录只读挂载到默认文档根目录:

compose.yaml
services:
nginx:
image: nginx:1-alpine
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./public:/usr/share/nginx/html:ro

单页应用需要把未知路由回退到 index.html

location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}

路径转发语义

proxy_pass 是否带结尾 / 会影响转发路径:

# 保留完整请求路径,例如 /api/users 仍转发为 /api/users
location /api/ {
proxy_pass http://backend;
}

# 去掉匹配到的 /api/ 前缀,例如 /api/users 转发为 /users
location /api/ {
proxy_pass http://backend/;
}

路由出现 404 时,应同时检查 locationproxy_pass 结尾斜杠以及后端应用自身的 PathBase / Base Path。

HTTPS

生产环境应使用受信任证书并建立自动续期流程。证书和私钥应在运行时只读挂载或由部署平台管理,不要复制进镜像或提交到 Git。

server {
listen 443 ssl;
server_name api.example.com;

ssl_certificate /etc/nginx/tls/fullchain.pem;
ssl_certificate_key /etc/nginx/tls/privkey.pem;

location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

挂载目录时保持只读:

volumes:
- ./tls:/etc/nginx/tls:ro

故障排查

现象检查项
502 Bad Gateway后端容器是否运行、服务名和端口是否正确、双方是否在同一网络
404 Not Foundlocationproxy_pass 的路径改写是否符合预期
WebSocket 失败是否使用 HTTP/1.1,并转发 UpgradeConnection 请求头
配置加载失败先运行 nginx -t,再查看容器日志中的具体文件和行号
客户端 IP 或协议错误是否正确设置并由应用安全地处理 X-Forwarded-* 请求头

官方参考