Docker 部署 Nginx:从入门到生产级配置实战
1. 引言
Nginx 作为高性能的 HTTP 服务器和反向代理服务器,在 Web 架构中占据着核心地位。传统部署方式需要手动安装、配置环境、管理进程,而 Docker 容器化部署则将这些复杂性封装起来,让我们能够快速启动、隔离运行、轻松迁移。
本文将带你从零开始,掌握 Docker 部署 Nginx 的全流程:
- ✅ 快速启动 Nginx 容器并验证
- ✅ 深入理解 Nginx 配置文件结构
- ✅ 挂载自定义配置、静态文件、日志
- ✅ 配置静态站点、反向代理、负载均衡
- ✅ 使用 Docker Compose 编排完整服务栈
- ✅ 生产环境优化与常见问题排查
2. 快速部署:第一个 Nginx 容器
2.1 拉取镜像并运行
bash
# 拉取官方最新镜像
docker pull nginx
# 运行容器,映射端口 80
docker run -d --name my-nginx -p 80:80 nginx
参数说明:
-d:后台运行--name my-nginx:指定容器名-p 80:80:将宿主机 80 端口映射到容器 80 端口
2.2 验证访问
打开浏览器访问 http://localhost,应看到 Nginx 欢迎页面。或者使用 curl:
bash
curl http://localhost
3. Nginx 配置文件结构概述
在深入自定义配置之前,先了解 Nginx 的配置文件体系:
/etc/nginx/nginx.conf
主配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;(传统)
conf.d/default.conf
默认 server 块
server { listen 80; server_name localhost; location / {...} }
核心要点:
nginx.conf是主配置文件,定义全局、事件、http 块。http块内通常包含include conf.d/*.conf;,将具体站点配置分离。- 每个站点(虚拟主机)对应一个
server块,定义监听端口、域名、路由规则。
Docker 官方镜像的默认配置文件位于容器内 /etc/nginx/nginx.conf,它已经包含了 include /etc/nginx/conf.d/*.conf;。因此我们只需在 conf.d 目录下添加自定义 *.conf 文件即可扩展配置。
4. 自定义配置:挂载文件与目录
Docker 部署的核心思想:将配置和静态文件放在宿主机,通过挂载覆盖容器内的对应路径。
4.1 准备宿主机目录结构
假设我们在宿主机上创建如下目录:
~/nginx/
├── conf.d/
│ └── my-site.conf
├── html/
│ └── index.html
├── logs/
└── nginx.conf (可选,一般不覆盖主配置)
4.2 编写自定义 server 配置
创建 ~/nginx/conf.d/my-site.conf:
nginx
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
4.3 启动容器并挂载
bash
docker run -d --name my-nginx \
-p 80:80 \
-v ~/nginx/conf.d:/etc/nginx/conf.d \
-v ~/nginx/html:/usr/share/nginx/html \
-v ~/nginx/logs:/var/log/nginx \
nginx
-v ~/nginx/conf.d:/etc/nginx/conf.d:覆盖默认的 conf.d 目录,里面可以放多个.conf文件。-v ~/nginx/html:/usr/share/nginx/html:挂载静态文件目录。-v ~/nginx/logs:/var/log/nginx:挂载日志目录,方便查看访问和错误日志。
4.4 验证自定义页面
在 ~/nginx/html/index.html 中写入:
html
<h1>Hello from Docker Nginx!</h1>
刷新浏览器,即可看到自定义内容。
5. 进阶配置:反向代理与负载均衡
Nginx 最常见的用途是作为反向代理,将请求转发给后端服务(如 Spring Boot、Node.js)。
5.1 反向代理配置示例
修改 ~/nginx/conf.d/my-site.conf:
nginx
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://host.docker.internal:8080; # 转发到宿主机 8080 端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
注意:在 Linux 容器中访问宿主机服务,可以使用
host.docker.internal(Docker 18.03+),或者使用宿主机的实际 IP。
5.2 负载均衡配置
使用 upstream 定义后端服务器组:
nginx
upstream backend {
server backend1:8080 weight=3;
server backend2:8080;
server backend3:8080 backup;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
weight 表示权重,backup 表示备用服务器。
6. Docker Compose 一站式部署
当 Nginx 作为前端网关,需要与后端服务(如 API、数据库)配合时,使用 Docker Compose 可以一键启动整个栈。
6.1 示例:Nginx + 两个后端服务
创建 docker-compose.yml:
yaml
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/html:/usr/share/nginx/html
- ./nginx/logs:/var/log/nginx
depends_on:
- backend1
- backend2
networks:
- app-network
backend1:
image: your-backend:latest # 替换为实际后端镜像
environment:
- PORT=8080
networks:
- app-network
backend2:
image: your-backend:latest
environment:
- PORT=8080
networks:
- app-network
networks:
app-network:
driver: bridge
6.2 Nginx 配置文件(使用服务名)
在 nginx/conf.d/default.conf 中:
nginx
upstream backend {
server backend1:8080;
server backend2:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
关键点 :Docker Compose 会自动为服务创建网络别名,因此可以直接用服务名 backend1 作为主机名。
6.3 启动
bash
docker-compose up -d
7. 生产环境优化与安全
7.1 限制 CPU 和内存
bash
docker run -d --name nginx \
--cpus="0.5" \
--memory="512m" \
-p 80:80 \
nginx
或在 Compose 中:
yaml
services:
nginx:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
7.2 配置 HTTPS(SSL)
- 将证书文件放在宿主机目录,例如
~/nginx/certs/。 - 挂载证书目录:
bash
-v ~/nginx/certs:/etc/nginx/certs
- 修改配置文件,添加 SSL 监听和证书路径:
nginx
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/nginx/certs/example.crt;
ssl_certificate_key /etc/nginx/certs/example.key;
# ... 其他配置
}
7.3 日志轮转
容器内 Nginx 日志输出到 /var/log/nginx,挂载到宿主机后,可以使用宿主机的 logrotate 进行轮转。或者配置 Nginx 直接输出到 stdout/stderr,由 Docker 日志驱动管理:
nginx
access_log /dev/stdout;
error_log /dev/stderr;
这样 docker logs nginx 就能看到日志。
7.4 健康检查
在 docker-compose.yml 中添加:
yaml
services:
nginx:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
8. 常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 访问 Nginx 得到 403 Forbidden | 静态文件目录权限不足 | 确保宿主机挂载目录有读取权限,或使用 -u 指定用户 |
| 修改配置后不生效 | 容器未重载配置 | docker exec nginx nginx -s reload |
| 端口被占用 | 宿主机 80 端口已被其他进程占用 | 更换映射端口,如 -p 8080:80 |
容器内无法解析 host.docker.internal |
Docker 版本过低或未启用 | 升级 Docker,或在 Linux 下使用 --add-host host.docker.internal:host-gateway |
| 反向代理到后端服务返回 502 | 后端服务未启动或网络不通 | 检查后端容器是否运行,是否在同一网络 |
9. 部署流程全景图
是
否
是
否
拉取 Nginx 镜像
是否自定义配置
编写宿主机配置文件和静态文件
使用 -v 挂载文件/目录
直接运行默认镜像
运行容器并映射端口
是否需要多服务编排
编写 docker-compose.yml
包含 Nginx + 后端服务
docker-compose up -d
docker run ...
验证访问
生产优化:资源限制、SSL、日志
10. 总结与最佳实践
通过 Docker 部署 Nginx,我们获得了:
- 环境一致性:开发、测试、生产使用相同的镜像和配置。
- 快速扩展:通过 Compose 或 Swarm 轻松增加实例。
- 隔离性:配置和日志挂载到宿主机,方便管理。
最佳实践总结:
- ✅ 永远使用官方镜像,并指定版本标签(如
nginx:1.26)避免意外升级。 - ✅ 将配置文件分离到
conf.d目录,保持主配置干净。 - ✅ 静态文件、配置、日志均通过卷挂载,实现持久化和热更新。
- ✅ 生产环境启用 HTTPS 和资源限制。
- ✅ 使用
nginx -s reload热加载配置,无需重启容器。 - ✅ 配合 Docker Compose 管理多容器依赖,使用服务名进行内部通信。