1-部署步骤
1.1-拉取镜像
选择一个合适的版本(参考官网),推荐使用alpine版本(什么是Alpine)
1
| docker pull nginx:1.24.0-alpine
|
1.2-创建本地目录并初始化
目录结构布局参考如下
1 2 3 4 5 6 7 8
| /opt/nginx/ ├── docker-compose.yml # 项目入口(如果是通过docker-compose部署) ├── certs/ # 证书(可选) ├── conf/ # 配置文件 │ ├── nginx.conf # 主配置(初始化后一般不动) │ └── conf.d/ # 站点/代理配置(日常修改) ├── html/ # 静态资源 └── logs/ # 日志持久化(可选)
|
创建目录
1 2
| # 创建本地目录 mkdir -p /opt/nginx/{certs,conf,logs}
|
创建临时容器用于初始化(可选,根据需要来)
1 2 3 4 5 6 7 8 9 10
| # 1.创建临时容器(不用run) docker create --name tmp-nginx nginx:1.24.0-alpine
# 2.拷贝官方默认配置 docker cp tmp-nginx:/etc/nginx/nginx.conf /opt/nginx/conf/ docker cp tmp-nginx:/etc/nginx/conf.d /opt/nginx/conf/ docker cp tmp-nginx:/usr/share/nginx/html /opt/nginx/
# 3.删除临时容器 docker rm tmp-nginx
|
1.3-启动容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| docker run -d \ --name nginx \ --restart always \ -p 80:80 \ -p 443:443 \ -v /opt/nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro \ -v /opt/nginx/conf/conf.d:/etc/nginx/conf.d:ro \ # 证书,可选 -v /opt/nginx/certs:/etc/nginx/certs:ro \ -v /opt/nginx/html:/usr/share/nginx/html:ro \ # 日志持久化,可选 -v /opt/nginx/logs:/var/log/nginx \ -e TZ=Asia/Shanghai \ nginx:1.24.0-alpine
|
1.4-测试
验证nginx服务是否正常
1 2
| # 默认80,看你配置的 curl 127.0.0.1
|
或者浏览器访问http://{ip}:{端口}(端口以你的配置为主,下图示例是81) ,出现nginx经典首页,成功

2-使用docker-compose部署
目录布局和初始化同 1.2-创建本地目录并初始化
在/opt/nginx下添加docker-compose.yml,内容参考
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| version: '3.8'
services: nginx: image: nginx:1.24.0-alpine container_name: nginx restart: always ports: - "80:80" - "443:443" volumes: - ./conf/nginx.conf:/etc/nginx/nginx.conf:ro - ./conf/conf.d:/etc/nginx/conf.d:ro - ./certs:/etc/nginx/certs:ro - ./html:/usr/share/nginx/html:ro - ./logs:/var/log/nginx environment: - TZ=Asia/Shanghai
|
启动容器
3-配置与使用
3.1-配置规范
配置docker部署的nginx,建议遵循这些原则:
- 初始化后尽量不去修改覆盖/opt/nginx/conf/nginx.conf
- 所有站点独立配置,推荐放在/opt/nginx/conf/conf.d/目录下
- 可以一个服务或者域名对应一个.conf配置文件(比如按域名对应命名:example.com.conf、app.example.com.conf)
- 修改配置后必须先检查语法,再热重载
这样做的好处是:可以根据站点、功能分开管理配置,方便维护,降低出错概率。
当然也不是必须😅,根据项目和实际需求来,比如我就想所有配置都在一个nginx.conf里方便拷贝,也是可以的。但要注意的是,以上介绍的挂载方式,是将nginx.conf文件单独挂载,此处有坑:在宿主机上修改完这个文件后使用nginx热重载命令很有可能因为inode问题导致容器内部不能同步更新,参考这篇踩坑文章。
3.2-配置模板
常规配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
server { listen 80; server_name your-domain.com;
location / { return 301 https://$host$request_uri; } }
server { listen 443 ssl; server_name your-domain.com;
ssl_certificate /etc/nginx/certs/your-domain.com.pem; ssl_certificate_key /etc/nginx/certs/your-domain.com.key;
root /usr/share/nginx/html; index index.html;
location / { try_files $uri $uri/ /index.html; }
}
|
二级域名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
server { listen 80; server_name your-domain.com www.your-domain.com admin.your-domain.com app.your-domain.com; return 301 https://$host$request_uri; }
server { listen 443 ssl; server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/nginx/certs/your-domain.com.pem; ssl_certificate_key /etc/nginx/certs/your-domain.com.key;
root /usr/share/nginx/html/main; index index.html;
location / { try_files $uri $uri/ /index.html; } }
server { listen 443 ssl; server_name admin.your-domain.com;
ssl_certificate /etc/nginx/certs/your-domain.com.pem; ssl_certificate_key /etc/nginx/certs/your-domain.com.key;
root /usr/share/nginx/html/admin; index index.html;
location / { try_files $uri $uri/ /index.html; } }
server { listen 443 ssl; server_name app.your-domain.com;
ssl_certificate /etc/nginx/certs/your-domain.com.pem; ssl_certificate_key /etc/nginx/certs/your-domain.com.key;
root /usr/share/nginx/html/app; index index.html;
location / { try_files $uri $uri/ /index.html; } }
|
二级目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| server { listen 80; server_name your-domain.com www.your-domain.com; return 301 https://$host$request_uri; }
server { listen 443 ssl; server_name your-domain.com www.your-domain.com;
ssl_certificate /etc/nginx/certs/your-domain.com.pem; ssl_certificate_key /etc/nginx/certs/your-domain.com.key;
root /usr/share/nginx/html/main; index index.html;
location / { try_files $uri $uri/ /index.html; }
location /app/ { alias /usr/share/nginx/html/app/; try_files $uri $uri/ /app/index.html; }
location /user/ { alias /usr/share/nginx/html/user/; try_files $uri $uri/ /user/index.html; }
location /admin/ { alias /usr/share/nginx/html/admin/; try_files $uri $uri/ /admin/index.html; } }
|
3.3-日志管理
3.3.1 方案一:挂载到宿主机目录+logrotate 管理
适用于单机开发/生产,需要精细的轮转策略(按天轮转、压缩、自定义保留策略)时,将nginx日志挂载到宿主机目录,使用系统级工具logrotate进行日志管理(大多数Linux发行版已预装logrotate,若未安装,sudo yum install logrotate -y安装即可)。
创建或编辑 /etc/logrotate.d/nginx:
1
| sudo vi /etc/logrotate.d/nginx
|
写入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # 宿主机Nginx容器日志轮转配置 /data/nginx/logs/*.log { daily # 按天切割 maxsize 100M # 超过100M立即切割 rotate 7 # 保留7份历史日志 compress # 切割后gzip压缩 delaycompress # 下一次轮转再压缩,不占用瞬时IO missingok # 日志不存在不报错 notifempty # 空日志不切割 create 0644 nginx nginx # 新建日志权限+属主 sharedscripts # 所有日志只执行一次后置脚本 postrotate # 向容器内nginx发送信号,重新打开日志文件(核心!) docker exec nginx-log nginx -s reopen > /dev/null 2>&1 endscript }
|
模拟调试(不真实切割):
1
| logrotate -d /etc/logrotate.d/nginx
|
强制手动切割
1
| logrotate -f /etc/logrotate.d/nginx
|
logrotate 自带系统定时任务cron.daily,每天自动执行,无需手动加定时;
当然也可以自定义执行时间:
1 2 3 4 5
| mv /etc/cron.daily/logrotate /etc/cron.daily/logrotate.bak
crontab -e
|
写入规则,例如:
1 2
| 0 0 * * * /usr/sbin/logrotate /etc/logrotate.d/nginx >/dev/null 2>&1
|
查看是否写入成功:
3.3.2 方案二(推荐):stdout/stderr输出+docker内置日志限制配置
docker默认使用json-file日志驱动,将容器stdout和stderr的输出以JSON格式逐行存储到宿主机磁盘,路径为/var/lib/docker/containers/<容器ID>/<容器ID>-json.log,将nginx日志配置输出到stdout和stderr,而非直接写入容器内部文件,这样docker可以自动捕获并管理这些日志,实现统一轮转。
nginx最新官方镜像默认已将日志输出到stdout和stderr,覆盖行为请注意:需要注意的是,当使用-v或--mount将宿主机的目录挂载到容器的/var/log/nginx目录时,会覆盖容器内原有的目录内容。这会导致官方的符号链接被覆盖,日志会写入到宿主机挂载的目录中,从而无法再通过docker logs查看。
手动配置日志输出至stdout、stderr,编辑nginx.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
error_log /dev/stderr;
http {
access_log /dev/stdout; }
|
使用docker日志驱动管理日志(介绍2种配置方式):
1.启动时配置
运行时添加配置:
1 2 3 4 5 6
| docker run -d \ --name my-nginx \ --log-driver json-file \ --log-opt max-size=10m \ --log-opt max-file=3 \ nginx:stable
|
docker-compose配置:
在docker-compose.yml中为服务添加logging字段:
1 2 3 4 5 6 7 8
| services: web: image: nginx:stable logging: driver: "json-file" options: max-size: "10m" max-file: "3"
|
2.全局配置(可选,对所有新容器生效)
编辑/etc/docker/daemon.json:
1 2 3 4 5 6 7
| { "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }
|
重启docker生效
1
| systemctl restart docker
|
参数说明
| 参数 |
作用 |
--log-driver=local |
Docker 官方推荐生产驱动,压缩存储、性能最高 |
max-size=100m |
单个日志文件最大 100MB,自动切割 |
max-file=5 |
最多保留 5 份日志,自动清理旧日志,防磁盘爆满 |
3.3.3 方案三:ELK/EFK集中式日志管理
适用于大型生产系统,通过搭建集中式日志平台,把多台服务器、docker容器、服务日志统一收集、清洗、存储、检索、可视化、告警,替代挨个登录服务器看日志。其中常见的架构方案有传统的ELK(Elasticsearch+Logstash+Kibana)以及当前主流的EFK(Elasticsearch+Fluentd+Kibana)。
ELK简介:
Elasticsearch —— 分布式搜索和分析引擎,负责存储和索引日志数据
Logstash —— 服务器端数据处理管道,负责采集、过滤、解析、转换日志
Kibana —— 数据可视化平台,负责查询、展示、分析日志
部署和使用细节暂略;
3.3-常用命令
测试配置:
1
| docker exec nginx nginx -t
|
热重启:
1
| docker exec nginx nginx -s reload
|
查看日志
docker容器原始日志(配置了日志输出stdout、stderr):
1 2 3 4 5 6 7 8
| # 实时查看日志 docker logs -f nginx
# 查看最近100行 docker logs --tail 100 nginx
# 查看1小时内日志 docker logs --since 1h nginx
|
若是挂载到宿主机目录的日志:
1
| tail -f /opt/nginx/logs/access.log
|
重启容器:
进入容器:
1
| docker exec -it nginx /bin/bash
|