帮朋友折腾阿里云服务器的时候,最常见的需求就是:Docker装好了,接下来怎么把网站跑起来?我在系列第一篇文章里讲了ECS上Docker环境的准备,这篇直接往下走,用Docker把Nginx完整部署起来,从拉镜像、起容器,到静态站点配置、反向代理、HTTPS证书落地,一条线走通。目标读者很明确:手里有一台阿里云服务器,已经装好Docker,想挂站又不想被零散教程绕晕的人。哪怕你现在连Nginx配置文件的语法都还不熟,按这篇文章的步骤操作,也能拿到一个能上线的服务。
1. 动手之前:为什么在阿里云上推荐用Docker部署Nginx
1.1 比起apt装Nginx,Docker方案到底强在哪
先回答一个很多人会纠结的问题:既然服务器上有apt,直接apt install nginx不就行了,为什么非要用Docker?
我在阿里云上两种方式都跑过,说点实际感受。直接装Nginx最大的问题是环境耦合——你升级系统、装别的软件、调整依赖库,都有可能影响Nginx的运行。特别是在生产环境里,你很难保证两台机器上的Nginx版本、编译参数、配置文件完全一致。Docker把Nginx连同它需要的运行环境封装在镜像里,宿主机装了什么、缺了什么,都不会干扰容器内的程序。
再有就是升级和回滚。用apt升级Nginx,要么改源要么手动下载,出问题想退回旧版本比较麻烦。用Docker就简单得多:新版本镜像拉下来,换个tag重新起容器;新版本有问题,再把旧tag起回来。整个过程半分钟以内搞定,损失最多是几秒钟的请求失败。
还有一个很多新手忽略的点:Docker部署Nginx后,配置文件、网站文件、日志通过挂载目录暴露在宿主机上。这意味着你可以用本地的编辑器直接改配置,不用SSH到服务器上跟vi较劲,也不用操心系统里Nginx的目录结构。我个人的习惯是把所有站点文件放在/opt/nginx下统一管理,哪个目录是配置、哪个目录是页面,一目了然。
1.2 部署前的四项检查:安全组、端口、目录、域名
动手前先做检查,这能省掉后面大把排错时间。我在给服务器部署服务时,习惯先过一遍下面这个清单:
| 检查项 | 怎么查 | 不检查的后果 |
|---|---|---|
| 安全组规则 | 阿里云控制台 -> ECS实例详情 -> 安全组 | 外部访问不到80/443端口 |
| 端口占用 | ss -lntp | grep :80 | 容器启动时报端口冲突 |
| 目录结构 | ls /opt/nginx | 配置文件和网站文件散落各处 |
| 域名解析 | 云解析DNS控制台查看A记录 | 无法用域名访问站点 |
安全组这个坑在阿里云上太典型了。很多人装完Docker、跑起容器,本机curl localhost一切正常,换到浏览器用公网IP访问就是白屏、连接超时。十有八九是安全组没放行。需要注意,ECS实例的安全组在实例控制台里配置,而轻量应用服务器那边叫“防火墙”,入口位置不同,别找错地方。
放行规则很简单:入方向添加TCP 80和443,授权对象填0.0.0.0/0。如果后面还要折腾其他端口,比如先跑一个8080测试服务,也一并放行,省得来回切控制台。
另外提醒一句,如果你打算绑定域名对外提供服务,先把域名解析到服务器公网IP,同时确认域名备案状态没问题。这一步不在技术配置范围内,但经常是最后访问不了的真凶,提前确认能避免白忙一场。
2. 拉镜像、规划目录、启动容器,把Nginx跑起来
2.1 镜像选择与目录规划
Nginx官方镜像有几个常用tag,我推荐生产环境使用nginx:stable-alpine。Alpine基础镜像非常小,整个镜像不到几十MB,一个精简的Linux层加一个Nginx层,干净利落。nginx:latest虽然更新更快,但基于Debian,体积大不少,对于只跑Nginx的场景没必要。
镜像确定后,先规划目录。我的标准结构是:
/opt/nginx/ ├── conf.d/ 存放站点配置 ├── html/ 静态网站文件 ├── logs/ Nginx日志 └── ssl/ SSL证书文件执行命令建目录:
mkdir -p /opt/nginx/{conf.d,html,logs,ssl}然后放一个默认首页,方便验证容器是否正常工作:
echo '<h1>Hello Nginx</h1>' > /opt/nginx/html/index.html为什么把这些目录挂载出来?因为Docker容器本身是“一次性”的。容器删了,内部所有文件跟着消失。如果你把配置写在容器里,哪天手滑执行了docker rm,所有配置和网站文件就都没了。挂载目录相当于把容器的状态留在宿主机上,删容器、重建容器,数据依然还在。
2.2 首次启动容器的完整命令与参数说明
目录准备好后,拉取镜像:
docker pull nginx:stable-alpine启动容器的命令,我逐项拆开解释:
docker run -d --name nginx \ --restart unless-stopped \ -p 80:80 \ -p 443:443 \ -v /opt/nginx/conf.d:/etc/nginx/conf.d:ro \ -v /opt/nginx/html:/usr/share/nginx/html:ro \ -v /opt/nginx/logs:/var/log/nginx \ -v /opt/nginx/ssl:/etc/nginx/ssl:ro \ -v /etc/localtime:/etc/localtime:ro \ nginx:stable-alpine参数分别说明:
-d:后台运行。--name nginx:容器名字叫nginx,后面执行docker exec nginx ...方便。--restart unless-stopped:容器因异常退出自动重启,服务器重启后也会跟着起来。这行在生产环境几乎是必须的。-p 80:80、-p 443:443:把宿主机80和443端口映射到容器。-v /opt/nginx/conf.d:/etc/nginx/conf.d:ro:把宿主机配置目录挂载到容器Nginx的conf.d目录,只读。Nginx启动时会加载/etc/nginx/conf.d/*.conf里的所有配置。-v /opt/nginx/html:/usr/share/nginx/html:ro:网站根目录挂载进去,只读。-v /opt/nginx/logs:/var/log/nginx:日志目录挂载出来。-v /opt/nginx/ssl:/etc/nginx/ssl:ro:证书目录。现在还没有证书文件,先挂上,后面申请完直接放进去就能用。-v /etc/localtime:/etc/localtime:ro:让容器使用宿主机时区,否则容器内取到的是UTC时间,Nginx访问日志的时间会差8个小时,排查问题的时候容易产生奇怪的感觉。
这里有一个很容易踩的细节:挂载conf.d时必须保证目录里至少有一个站点配置文件,否则目录虽然是空的,但容器内原有的默认配置会被空目录“遮住”,导致Nginx启动后没有可用的server块,访问80端口会出现404或拒绝连接。后面章节我会专门说明。
2.3 启动后必做的三步验证
容器起来后,不要急着配业务,先做三项验证:
docker ps确认容器状态是Up,没有反复重启。
curl http://localhost在服务器本机测试,能返回你写的首页内容就说明Nginx基本工作正常。
docker logs nginx --tail 20查看容器日志,确认没有报错。这里注意,Nginx官方镜像默认把access_log和error_log挂到了标准输出,所以docker logs能看到最近访问记录。
本机通了之后,再用浏览器访问公网IP。如果打不开,回到第一章的安全组检查——80端口有没有放行。这一步我遇到过太多次:本机curl通、浏览器不通,折腾半天最后发现安全组忘配置。
3. 静态站点配置:location匹配规则与server块详解
3.1 一个能用的静态站点配置长什么样
容器跑起来了,接下来就是Nginx的核心配置。很多人对Nginx的恐惧其实来自配置文件语法不熟,不知道server、location、root之间的关系。我习惯把一个站点配置写在一个独立的文件中,放在/opt/nginx/conf.d/下,例如/opt/nginx/conf.d/blog.conf。
server { listen 80; server_name blog.example.com; root /usr/share/nginx/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } access_log /var/log/nginx/blog.access.log; error_log /var/log/nginx/blog.error.log; }server块代表一个虚拟主机,listen 80监听80端口,server_name决定哪个域名匹配到这个配置。root指定网站文件根目录,注意这个路径是容器内部的路径,不是宿主机路径。因为我们把/opt/nginx/html挂载到了/usr/share/nginx/html,所以这里写容器内路径。
location /是最基础的匹配,代表所有未被其他location拦截的请求。try_files $uri $uri/ =404的意思很直白:先尝试找URI对应的文件,再尝试找这个目录,都找不到就返回404。这行配置能避免访问一个不存在的路径时出现奇怪的错误页。
写完配置后,先做语法检查再重载:
docker exec nginx nginx -t docker exec nginx nginx -s reloadnginx -t是检查配置语法,报错会指出具体文件和行号。确认没问题再用nginx -s reload重载。reload是平滑重载,不会中断现有连接,这是Nginx一个非常优雅的设计。
3.2 location匹配机制的优先级
location是Nginx配置里信息量最大的指令,掌握了它的匹配规则,写任何反代、静态资源都心中有数。它的匹配类型和优先级如下表:
| 匹配类型 | 写法示例 | 行为特点 |
|---|---|---|
| 精确匹配 | location = /api | 路径完全等于/api,命中立即使用 |
| 前缀匹配(强制停止) | location ^~ /static/ | 命中立即使用,不再检查正表达式 |
| 正则匹配(区分大小写) | location ~ \.php$ | 按配置文件顺序,第一个命中的生效 |
| 正则匹配(不区分大小写) | location ~* \.jpg$ | 同上 |
| 普通前缀匹配 | location /static/ | 记录最长匹配,之后检查正则,正则没命中才用它 |
| 通用匹配 | location / | 兜底,几乎能匹配所有请求 |
理解这个规则有个简单的心法:先找前缀最长匹配,再按顺序跑正则,正则赢了用正则,正则没赢就用之前记录的最长前缀。=和^~属于“赢家通吃”型,命中就直接拍板。
举个例子,网站上有一批图片放在/static/images/下,我一般这么配:
location ^~ /static/ { alias /data/static/; expires 7d; }^~保证了这个匹配优先于任何正则,同时给静态资源加上expires 7d缓存头部,浏览器访问过一次后七天内不再重复请求。
3.3 root与alias:最常见的路径困惑
很多新手在root和alias之间选错,导致静态文件一直404。我讲个最直观的差异。
root会把你配置的路径和location匹配的URI拼在一起。比如:
location /img/ { root /usr/share/nginx/html; }请求/img/a.png时,Nginx查找的文件路径是/usr/share/nginx/html/img/a.png。也就是root拼接完整URI,包括img这段。
而alias是替换关系:
location /img/ { alias /data/images/; }请求/img/a.png时,Nginx会用/data/images/替换掉/img/,实际查找/data/images/a.png。
记住口诀:root是“拼上去”,alias是“换掉前缀”。实际项目里,静态文件如果不在网站根目录下,建议用alias,逻辑更清晰。
3.4 改完配置如何生效
配置修改后,严格遵循一个习惯:先nginx -t,再nginx -s reload,两条命令连成一条执行也OK:
docker exec nginx nginx -t && docker exec nginx nginx -s reload这个习惯非常重要。我见过有人在生产环境改了配置直接reload,结果配置有语法错误,Nginx直接把所有worker进程全部退掉,服务整个挂掉。先做语法检查再过五秒reload,成本极低,收益极高。另外,reload和restart不一样,reload是让Nginx重新读取配置,不会中断正在处理的请求,对线上影响为零。
4. 反向代理实战:一个域名挂多个后端服务
4.1 反代场景与配置骨架
静态站点只是Nginx的基本功,真正凸显它价值的是反向代理。简单来说,反代就是把外部的请求接进来,转发到服务器上另一个端口跑着的服务,再把响应返回给客户端。
最常见的场景:你在机器上跑了一个博客、一个管理系统、一个接口服务,它们分别监听3000、8080、5000端口。不想让用户记端口号,也不想在每个应用里配置TLS,更不想让服务直接暴露公网。这时候Nginx做主入口,根据域名或路径把流量分发到各自端口。
配置骨架如下:
server { listen 80; server_name blog.example.com; location / { proxy_pass http://127.0.0.1:3000; 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_pass是反代的核心指令。请求到达Nginx后,Nginx作为客户端把请求转发给127.0.0.1:3000,拿到结果后再返回给浏览器。对浏览器来说,它只看到Nginx在服务,并不知道背后还有一层应用。
4.2 proxy_pass末尾的斜杠:细节决定成败
proxy_pass这行配置里有一个非常容易踩的细节:URL末尾到底带不带斜杠。
假设location是/api/,后端接口服务挂在8080端口:
location /api/ { proxy_pass http://127.0.0.1:8080; }此时请求/api/user,转发给后端的是完整路径/api/user。location里面的/api/原封不动地带过去了。
如果写成这样:
location /api/ { proxy_pass http://127.0.0.1:8080/; }请求/api/user,转发给后端的是/user。/api/被替换成了/。
这两者的语义差别很大。后端如果只认/user路由,而你用了不带斜杠的写法,它收到的/api/user就找不到对应接口,返回404。反过来也一样。我建议写反代前先拉一下后端接口的根路径设计,确认要不要带location前缀,再决定斜杠。这是一个看着不起眼、坑起人来毫不含糊的细节。
4.3 容器间通信用容器名,别写IP
如果你被反代的服务也是Docker容器,注意不要用IP互相访问。容器的IP在每次重建后都会变化,今天配置里写的172.17.0.3,明天容器一重建可能变成172.17.0.5,代理立刻失效。
正确做法是让容器在同一个自定义网络里,通过容器名互相访问。先创建网络:
docker network create webnet把Nginx和后端容器都加入网络:
docker network connect webnet nginx docker network connect webnet backend然后在Nginx配置里,直接写容器名:
location / { proxy_pass http://backend:8080; }Docker自带的DNS解析会把backend解析到对应容器的地址,IP怎么变都不影响。这是我在Docker部署里最推荐的做法,比查docker inspect拿IP、写死IP要省心得多。
4.4 请求头穿透:把真实客户端IP传给后端
反代有一个隐性问题:后端服务看到的请求来源变成了Nginx的IP,而不是真实用户的IP。日志里全是127.0.0.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;$host是浏览器请求的域名,$remote_addr是真实客户端IP,$proxy_add_x_forwarded_for会把已有转发链追加在后面,$scheme标记原始请求是HTTP还是HTTPS。后端服务器读取这些请求头,就能拿到准确的客户端IP和访问协议。如果你的后端应用还要判断用户IP做限流或封禁,这几行绝对不能省。
5. HTTPS配置:让443端口正式接管站点
5.1 证书从哪来:三种来源对比
现在没有纯HTTP站点还能留住用户的。浏览器会直接标“不安全”,小程序、App等在调用接口时也强制要求HTTPS。证书来源我实际用过的有三种:
| 证书来源 | 有效时长 | 适用场景 |
|---|---|---|
| 阿里云免费数字证书 | 3个月或1年(视政策) | 国内单域名站点,申请方便 |
| Let's Encrypt(通过certbot) | 90天 | 需要自动化续期,习惯命令行 |
| 自签证书 | 无固定期限 | 仅内网测试,浏览器会告警 |
个人站点我一般用阿里云免费证书,控制台提交申请,验证域名归属后就能下载,里面有nginx用的.pem证书文件和.key私钥文件。如果是多域名或子域名特别多,考虑Let's Encrypt,配合certbot可以写脚本自动续期,省去手动反复操作的麻烦。
5.2 把证书文件放进容器:挂载与路径
拿到证书文件后,放到宿主机/opt/nginx/ssl/目录下。注意,Nginx运行在容器里,它只能读取容器内的路径。因为我们在启动容器时已经挂载了/opt/nginx/ssl到/etc/nginx/ssl,所以Nginx配置里写的是容器路径:
ssl_certificate /etc/nginx/ssl/example.com.pem; ssl_certificate_key /etc/nginx/ssl/example.com.key;docker run命令里已经预留了ssl挂载,这里只需要把文件放进去,再reload配置即可生效。如果当初启动容器时忘了挂载ssl目录,就得重建容器加上挂载,操作起来麻烦一些,这也是我推荐一开始就把目录规划完整的原因。
5.3 完整的443 server配置与HTTP跳转
一份完整的HTTPS server配置,加上HTTP自动跳转HTTPS,参考如下:
server { listen 80; server_name blog.example.com; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name blog.example.com; ssl_certificate /etc/nginx/ssl/example.com.pem; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /usr/share/nginx/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } access_log /var/log/nginx/blog.ssl.access.log; }return 301 https://$host$request_uri是HTTP跳转HTTPS的标准写法,把80端口所有请求直接导向443端口。ssl_protocols建议至少支持TLS 1.2,老旧的TLS 1.0和1.1协议漏洞多,该退役就让它退役。
配置写好,老规矩执行语法检查和重载:
docker exec nginx nginx -t && docker exec nginx nginx -s reload然后浏览器用https://域名访问,地址栏出现小锁图标就说明配置成功。
5.4 证书常见报错与域名校验
HTTPS配置最容易出错的点,我在实际操作中总结出两个高频问题。
第一个:nginx -t报cannot load certificate或类似无法读取证书文件的错误。原因通常是证书文件没放对地方,Nginx在容器内看不到。排查方法很简单:
docker exec nginx ls /etc/nginx/ssl/如果看不到证书文件,说明宿主机/opt/nginx/ssl目录下也没有,或者文件名写错了。解决方法是把证书文件复制到宿主机对应目录,确保文件名与配置完全一致。
第二个:浏览器访问报ERR_CERT_COMMON_NAME_INVALID。这种问题基本是证书的域名和访问的域名对不上。比如你申请的是example.com的证书,在浏览器里却用blog.example.com访问,或者干脆用IP访问域名证书,浏览器就会因为证书CN/SAN不匹配而拦截连接。解决思路也很简单:要么访问对应的域名,要么重新申请匹配当前域名的证书。备案过的域名正常使用是没有这个问题的。
6. 部署过程中最常见的五个坑
6.1 安全组忘放行:本机通、外网不通
这个坑在第一章提过,但在整个部署过程中出现的频率太高,必须再强调一遍。现象是服务器上curl localhost返回正常,用手机或本地电脑访问公网IP就是超时。判断思路很清晰:既然本机能通,Nginx服务肯定正常,问题必然出在从服务器到外部网络之间的某个环节。对阿里云来说,第一个要查的就是安全组规则。ECS去实例详情页看安全组,轻量应用服务器去防火墙页面看规则,入方向放行80和443,授权对象0.0.0.0/0,问题基本解决。
6.2 conf.d空目录遮住默认配置
启动容器后,如果访问80端口返回403、404或者直接拒绝连接,很可能是conf.d挂载导致的问题。比如执行了docker run -v /opt/nginx/conf.d:/etc/nginx/conf.d:ro,但宿主机/opt/nginx/conf.d目录是空的。Docker挂载空目录后,容器内原有目录里的文件就被遮蔽了,Nginx找不到任何站点配置,自然无法正常响应。
排查方式:
docker exec nginx ls /etc/nginx/conf.d/看到为空,问题就找到了。解决方法是先把一个默认站点配置文件放进/opt/nginx/conf.d/再重启容器。这也是我在第二章就提示先建目录并放配置文件的原因。
6.3 改了配置页面没变:确认挂载加reload
配置改了半天,网站一点变化没有,这种挫败感我太懂了。排查顺序如下:
先确认挂载路径是宿主机的哪个目录。docker inspect nginx可以查看容器的挂载情况,确认你编辑的文件确实映射到了容器内的Nginx配置目录。很多人会用vi直接改容器里的配置文件,但没挂载的话容器一重建就全丢了。
再确认是否执行了reload。改完conf.d里的文件后,Nginx不会自动感知,需要docker exec nginx nginx -s reload。如果config语法有问题,reload也不会生效,所以要养成nginx -t && nginx -s reload连用的习惯。
最后确认浏览器缓存。静态资源被浏览器缓存是常事,按Ctrl+F5强制刷新或开隐私模式访问。
6.4 容器删了配置全丢:卷挂载是唯一的保险
Docker容器删除后,内部一切文件随之消失。之前没有做任何挂载的话,配置、页面、证书都没了。我建议做任何修改前,先检查:
docker inspect nginx --format '{{json .Mounts}}'如果Mounts列表里只有基础数据卷没有站点挂载,那当前容器是一件“脏衣服”,删了就没了。正确做法是重建容器并添加所有需要的挂载。不要试图往一个没有挂载的容器里长期保存配置,容器随时可能因为故障或误操作被删除。在容器生命周期管理上,我始终遵守一条原则:容器可以随时删,宿主机上的数据才是根本。
6.5 日志无限膨胀:处理好Nginx日志轮转
跑了一段时间后,宿主机磁盘突然告警,查下来往往是Nginx日志把空间吃满了。原因是我们把日志挂载到了宿主机/opt/nginx/logs,但没有任何轮转策略,access.log和error.log会无限增长。
处理办法分两步。第一步,用系统crontab做一个简单的日志切割:
0 0 * * * mv /opt/nginx/logs/*.log /opt/nginx/logs/$(date +\%Y\%m\%d).log 2>/dev/null; docker exec nginx nginx -s reopen第二步,nginx -s reopen这句很关键。Nginx进程仍然持有旧日志文件的文件句柄,直接切割完文件后,磁盘空间不会释放,必须让Nginx重新打开日志文件。reopen就是干这个的。生产环境更优雅的方案是配置logrotate,但对大多数单机站点,上面的crontab思路已经够用。
7. 生产环境常用优化:自动重启、资源限制、Compose管理
7.1 容器跟着服务器开机自启
部署完服务只是开始,稳定性才是关键。服务器重启后,Nginx容器能不能自动恢复,取决于启动参数里有没有--restart unless-stopped。如果当时忘了加,不用重建容器,一条命令补上:
docker update --restart unless-stopped nginx这个策略的含义是:容器异常退出时自动重启,除非你手动停止它。注意always和unless-stopped的区别,always即使手动停止,服务器重启后也会自动拉起,有时候反而会打扰你排查问题。我习惯用unless-stopped。
7.2 用资源限制防止Nginx吃干机器
阿里云小规格的ECS,内存可能只有2G甚至1G。Nginx默认配置在极端流量下会占用不少内存,加上同一台机器上还可能跑着其他容器,出现过内存耗尽导致整机卡死的尴尬。
给容器加上资源限制:
docker update --memory="512m" --cpus="1.0" nginx限制Nginx最多使用512MB内存和1个CPU核心。如果跑静态站点这个上限大概率够用,遇到突发流量Nginx也不会拖垮整台服务器。这个限制对单机多服务的场景特别有意义,谁都别占谁的资源。
7.3 用docker compose固化整套配置
当挂载项多起来,手敲docker run命令就显得笨重且容易出错。我最终都会把部署定义写成docker compose文件,放到/opt/nginx/docker-compose.yml:
services: nginx: image: nginx:stable-alpine container_name: nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - /opt/nginx/conf.d:/etc/nginx/conf.d:ro - /opt/nginx/html:/usr/share/nginx/html:ro - /opt/nginx/logs:/var/log/nginx - /opt/nginx/ssl:/etc/nginx/ssl:ro之后启动就一句话:
docker compose up -d升级镜像、重建容器、老配置迁移到新机器,把整个目录复制过去执行docker compose up -d就行。配置文件即代码,出问题按定义重建,比手动敲命令可靠得多。
7.4 几个值得改的nginx.conf参数
容器内Nginx的/etc/nginx/nginx.conf是镜像自带的默认配置,生产上我一般会调整几个参数。可以直接修改宿主机和容器内的文件,或者在配置里覆盖:
worker_processes auto; server_tokens off; gzip on; gzip_min_length 1k; gzip_types text/plain text/css application/javascript application/json;worker_processes auto让Nginx按服务器CPU核心数自动分配worker进程。server_tokens off隐藏Nginx版本号,减少被针对性探测的风险。gzip压缩文本类资源,对静态页面加载速度提升非常直观。这些参数改动后同样需要nginx -t && nginx -s reload。
如果对容器内nginx.conf修改比较谨慎,也可以把这些优化放进站点配置的http块里,不过更推荐直接在镜像挂载一份自定义nginx.conf出来。这个属于进阶玩法,等你熟悉了当前的配置结构再折腾也不迟。
最后再分享一个我个人的操作习惯:每次改完Nginx配置,无论是新增站点还是调整代理规则,都严格按nginx -t && nginx -s reload走,并且立刻用浏览器无痕窗口验证一次。这个习惯帮我避免了很多线上事故。Nginx部署本身不难,难的是把细节保持住——安全组放行、目录规划、卷挂载、reload验证,每一步都老老实实做完,Nginx在阿里云上跑个几年都不带出问题的。这篇文章到这就结束了,下一篇准备聊聊用Docker部署后端服务以及和Nginx组成一套完整的站点体系,到时候见。