写这篇文章的直接原因:网上搜 Docker 装 Nginx 的教程,十篇有九篇都是
docker run一下就完事,看起来简单,真到生产环境一用全是坑 ------ 配置文件丢了、日志没持久化、证书挂了、升级容器把站点搞没了。
这篇是我自己踩过坑之后整理的完整生产级部署方案,从基础启动到 Compose 编排,从 HTTP 到 HTTPS,从反向代理到性能调优,从常用命令到排错指南,一条线拉通。
你能从这篇文章得到什么:
- 三种部署方式的完整命令,复制就能用
- 生产环境目录结构规范,照着搭就行
- HTTPS + HTTP/2 完整配置,含证书自动续期
- 反向代理 + WebSocket 支持的标准写法
- 常见问题排查清单,遇到问题直接查
适合谁看:
- 刚接触 Docker,想把 Nginx 跑起来的新手
- 一直在裸机装 Nginx,想容器化迁移的运维
- 会基础用法,但想搞清楚生产环境最佳实践的开发者
不废话,直接上干货。
一、环境准备
1.1 系统要求
bash
# 检查 Docker 版本
docker --version
# Docker version 24.0.7, build afdd53b
# 检查 Docker Compose 版本
docker compose version
# Docker Compose version v2.21.0
注意:本文基于 Docker 24.x + Compose v2 编写,低于 20.10 版本部分命令可能不兼容。
1.2 前置检查
bash
# 确认 Docker 服务正常运行
systemctl status docker
# 确认 80/443 端口未被占用
netstat -tlnp | grep -E ':(80|443)\s'
# 或
ss -tlnp | grep -E ':(80|443)\s'
如果端口被占用,要么停掉占用进程,要么换端口映射。
二、方式一:基础快速启动(适合测试)
2.1 拉取官方镜像
bash
# 拉取最新稳定版
docker pull nginx:latest
# 推荐:指定明确版本,生产环境不要用 latest
docker pull nginx:1.27-alpine
# 查看本地镜像
docker images | grep nginx
选型建议:
nginx:alpine--- 体积小(~40MB),适合生产nginx:latest--- 基于 Debian,体积大(~140MB),调试工具全nginx:stable-alpine--- 稳定分支 + alpine,生产首选
2.2 启动容器
bash
docker run -d \
--name nginx \
-p 80:80 \
--restart=always \
nginx:1.27-alpine
参数说明:
| 参数 | 作用 |
|---|---|
-d |
后台运行 |
--name nginx |
容器命名为 nginx |
-p 80:80 |
宿主机 80 端口映射到容器 80 端口 |
--restart=always |
Docker 重启后容器自动启动 |
2.3 验证
bash
# 查看容器状态
docker ps | grep nginx
# 浏览器访问或 curl 测试
curl -I http://localhost
# HTTP/1.1 200 OK
# Server: nginx/1.27.0
看到 Welcome to nginx! 就说明跑通了。
三、方式二:挂载配置 + 数据卷(生产标准姿势)
基础启动只能用默认配置,生产环境必须挂载配置文件和静态资源。
3.1 目录结构规划
bash
# 创建 Nginx 相关目录
mkdir -p /data/nginx/{conf,conf.d,html,logs,ssl,cert}
目录说明:
| 目录 | 用途 |
|---|---|
/data/nginx/conf |
主配置文件 nginx.conf |
/data/nginx/conf.d |
站点配置,按域名拆分 |
/data/nginx/html |
静态网站根目录 |
/data/nginx/logs |
访问日志 + 错误日志 |
/data/nginx/ssl |
SSL 证书存放 |
3.2 从容器拷贝默认配置
不要自己从零写配置,先从官方镜像里拷出来再改:
bash
# 先临时启动一个容器
docker run --name nginx-tmp -d nginx:1.27-alpine
# 拷贝主配置文件
docker cp nginx-tmp:/etc/nginx/nginx.conf /data/nginx/conf/
# 拷贝 conf.d 目录
docker cp nginx-tmp:/etc/nginx/conf.d/default.conf /data/nginx/conf.d/
# 拷贝默认 html 页面
docker cp nginx-tmp:/usr/share/nginx/html /data/nginx/
# 删掉临时容器
docker rm -f nginx-tmp
3.3 主配置文件 nginx.conf
bash
user nginx;
worker_processes auto; # 自动匹配 CPU 核心数
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 10240; # 调大连接数
use epoll; # Linux 高效 IO 模型
multi_accept on; # 一次接受多个连接
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on; # 开启 gzip 压缩
gzip_vary on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain text/css text/javascript application/json application/javascript application/xml;
include /etc/nginx/conf.d/*.conf; # 加载所有站点配置
}
3.4 站点配置示例
/data/nginx/conf.d/default.conf:
bash
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2?)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
3.5 正式启动容器
bash
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
--restart=always \
-v /data/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /data/nginx/conf.d:/etc/nginx/conf.d:ro \
-v /data/nginx/html:/usr/share/nginx/html:ro \
-v /data/nginx/logs:/var/log/nginx \
-v /data/nginx/ssl:/etc/nginx/ssl:ro \
--network web-network \
nginx:1.27-alpine
关键点:
:ro表示只读挂载,配置文件建议只读,防止容器内误改- 日志目录不要加
:ro,容器需要写权限--network建议自定义网络,方便和其他容器(如后端服务)内部通信
3.6 配置热重载
改完配置不用重启容器,直接 reload:
bash
# 测试配置语法是否正确(必做!)
docker exec nginx nginx -t
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 热重载配置
docker exec nginx nginx -s reload
铁律 :改完配置先
nginx -t,没问题再 reload,直接 reload 可能把服务搞挂。
四、方式三:Docker Compose 部署(推荐)
生产环境统一用 Compose 管理,方便维护和迁移。
4.1 docker-compose.yml
bash
version: '3.8'
services:
nginx:
image: nginx:1.27-alpine
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf.d:/etc/nginx/conf.d:ro
- ./html:/usr/share/nginx/html:ro
- ./logs:/var/log/nginx
- ./ssl:/etc/nginx/ssl:ro
networks:
- web-network
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
networks:
web-network:
driver: bridge
4.2 启动
bash
# 前台启动看日志
docker compose up
# 后台启动
docker compose up -d
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f nginx
五、HTTPS 配置(Let's Encrypt 免费证书)
5.1 申请证书(certbot)
bash
# 安装 certbot
apt install certbot -y # Debian/Ubuntu
# 或
yum install certbot -y # CentOS
# 手动模式申请(需要在域名 DNS 加 TXT 记录验证)
certbot certonly --manual --preferred-challenges dns -d yourdomain.com
证书生成位置:/etc/letsencrypt/live/yourdomain.com/
5.2 Nginx HTTPS 配置
/data/nginx/conf.d/yourdomain.conf:
bash
server {
listen 80;
server_name yourdomain.com;
# HTTP 强制跳转 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# SSL 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
5.3 证书续期
Let's Encrypt 证书有效期 90 天,设置定时任务自动续期:
bash
# 测试续期
certbot renew --dry-run
# 添加 crontab,每天凌晨 2 点检查续期
crontab -e
# 0 2 * * * certbot renew --quiet --deploy-hook "docker exec nginx nginx -s reload"
六、反向代理配置(最常用场景)
6.1 代理到后端服务
bash
server {
listen 80;
server_name api.yourdomain.com;
location / {
proxy_pass http://backend-service: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;
proxy_set_header X-Forwarded-Proto $scheme;
# 超时设置
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
注意 :
proxy_pass里的backend-service是容器名,前提是 Nginx 和后端服务在同一个 Docker network 里。
七、常用运维命令
7.1 容器操作
bash
# 启动/停止/重启
docker start nginx
docker stop nginx
docker restart nginx
# 进入容器
docker exec -it nginx sh # alpine 用 sh,不用 bash
# 查看实时日志
docker logs -f nginx
docker logs -f --tail 100 nginx # 只看最后 100 行
# 查看资源占用
docker stats nginx
7.2 Nginx 内部命令
bash
# 查看版本
docker exec nginx nginx -v
# 查看编译参数
docker exec nginx nginx -V
# 测试配置
docker exec nginx nginx -t
# 热重载
docker exec nginx nginx -s reload
# 优雅退出
docker exec nginx nginx -s quit
7.3 日志分析
bash
# 实时看访问日志
tail -f /data/nginx/logs/access.log
# 统计 TOP 10 IP
awk '{print $1}' /data/nginx/logs/access.log | sort | uniq -c | sort -rn | head -10
# 统计 404 数量
grep ' 404 ' /data/nginx/logs/access.log | wc -l
八、常见问题与排错
Q1:容器启动后立即退出
bash
# 查看退出原因
docker logs nginx
大概率是配置文件语法错误,先 nginx -t 检查。
Q2:403 Forbidden
常见原因:
- 目录没有 index 文件
- 文件权限问题(容器内 nginx 用户 uid=101)
- SELinux 限制(CentOS 常见)
bash
# 修复权限
chmod -R 755 /data/nginx/html
chown -R 101:101 /data/nginx/html # alpine 镜像 nginx uid 是 101
Q3:502 Bad Gateway
反向代理场景常见,后端服务没起来或网络不通:
bash
# 检查后端容器是否在同一网络
docker network inspect web-network
# 从 nginx 容器里 ping 后端
docker exec nginx wget -qO- http://backend-service:8080/health
Q4:上传文件 413 Request Entity Too Large
Nginx 默认限制请求体大小 1MB,在 server 或 location 块加:
bash
client_max_body_size 50M;
九、性能优化建议
- worker_processes auto --- 自动匹配 CPU 核心数
- worker_connections 调大 --- 根据服务器内存设,一般 10240 起步
- 开启 gzip --- 文本类资源压缩率 60%+
- 静态资源缓存 --- 图片、CSS、JS 设长缓存
- 开启 sendfile + tcp_nopush --- 减少内核态用户态切换
- 日志缓冲 --- 高并发场景
access_log加buffer=64k flush=5s - 使用 HTTP/2 --- HTTPS 下开启
http2多路复用
总结
Docker 部署 Nginx 三步走:
- 测试环境 :直接
docker run快速起一个 - 生产环境:目录挂载 + 配置外置 + 数据卷持久化
- 规范管理:Docker Compose 编排 + 健康检查 + 自定义网络
核心原则:配置文件外置、日志持久化、版本号固定、改配置先 -t 再 reload。
CSDN 标签(Tags) : Docker Nginx Docker Compose 反向代理 HTTPS 运维 容器化 Linux 部署 性能优化
关键词: Docker 安装 Nginx、Docker Nginx 教程、Nginx 反向代理 Docker、Docker Compose Nginx、Nginx HTTPS 配置、Docker Nginx 挂载配置、容器化部署、Nginx 性能优化
完成硬核CSDN风格Docker安装NGINX文章
已输出完整硬核 CSDN 风格教程,核心要点速览:
三种部署方式
- 快速测试:
docker run直接起,适合临时验证 - 生产标准:目录挂载 + 配置外置 + 数据卷持久化(
conf、conf.d、html、logs、ssl五个目录) - 规范管理:Docker Compose 编排 + 健康检查 + 自定义网络
核心操作铁律
- 镜像版本固定,生产别用
latest,推荐nginx:1.27-alpine - 改配置先
nginx -t验证,没问题再nginx -s reload - 配置文件加
:ro只读挂载,防止容器内误改
常见坑
- 403:文件权限问题,alpine 镜像 nginx uid 是 101
- 502:后端容器不在同一 network
- 413:默认请求体 1MB,需加
client_max_body_size