这篇记录复盘2026年8月22日的内部预部署。9月4日官网已完成正式域名与HTTPS上线;下面的回环地址、端口和测试结果描述的是当时的预览环境。
先做两个请求
官网文件已经上传到阿里云ECS。现在做两个实验:
在服务器内部访问127.0.0.1:8081 → 返回官网
从公网访问服务器IP的8081端口 → 无法访问
同一份文件,同一个端口,结果不同。
为什么?不是HTML突然害羞了,而是Nginx只监听服务器自己的回环地址。它被明确告知:“只接待从这台机器内部来的请求。”
这个实验比背“反向代理、高并发、负载均衡”有用得多。当前官网甚至还没有使用这些能力。先把眼前这个请求怎样进门搞清楚。
去掉术语后,Nginx是服务器门口的收发室:它看请求从哪里来、要找什么,再决定交文件、转交别人,还是拒绝。
本地打开文件,不等于部署网站
双击index.html时,浏览器直接读取你电脑上的文件。地址通常以file://开头,没有任何服务器参与。
通过HTTP访问时,过程变成:
浏览器请求一个IP和端口
↓
监听这个入口的程序接到请求
↓
程序根据路径寻找文件或转给应用
↓
程序返回状态码、响应头和内容
把HTML上传到服务器,只完成了“文件在那里”。如果没有程序监听端口,外部浏览器仍然拿不到它。仓库里有一架钢琴,不等于音乐会已经开始。
十秒演示:读懂这三行配置
当时预上线配置的核心是:
listen 127.0.0.1:8081;
root /opt/sanmu-site/current;
index index.html;
逐句翻译成人话:
- 第一行:只在服务器内部的8081入口等请求。
- 第二行:收到请求后,从这个目录找文件。
- 第三行:请求一个目录时,优先给出
index.html。
你不需要先知道Nginx的全部指令。只要能回答“谁在什么门口等着”“东西放在哪里”“默认拿哪一件”,这三行就搞清楚了。
Nginx官方文档说明,它会先根据监听地址和端口确定候选Server Block,再结合请求中的Host选择处理请求的服务器配置。路径匹配则决定后续使用哪个location。
为什么不直接使用80端口
当时服务器的公网80端口已有水滴服务在运行。端口不是抽象编号,它是正在被程序占用的入口。
如果为了预览官网直接改写80端口配置,可能让原有服务中断。于是这次选择了另一个入口,并把它限制在127.0.0.1。需要从自己的电脑预览时,再通过SSH端口转发进入。
这次实际验证得到四个结果:
- 服务器内部首页返回HTTP 200。
- 图标和本地字体可以读取。
- 公网80端口仍然返回原有水滴页面。
- 公网无法访问8081预览入口。
这四项合在一起,才证明“官网已经内部预部署,而且没有抢走原服务”。只看第一项不够。
try_files不是装饰
当时单页入口使用:
location / {
try_files $uri $uri/ /index.html;
}
它的意思是:先找请求对应的文件,再找目录,都没有就交回index.html。
但静态资源采用更严格的规则:
location /assets/ {
try_files $uri =404;
}
做个反例。浏览器请求一张不存在的图片。如果所有路径都退回index.html,服务器会返回一份HTML。状态可能还是200,但浏览器拿到的根本不是图片。页面只会留下一个莫名其妙的资源错误。
所以资源不存在时,诚实地返回404比“所有请求都成功”更正确。Nginx官方try_files文档说明,它会按顺序检查文件是否存在,并在没有找到时执行最后指定的内部跳转或状态处理。
缓存也可以做一个实验
把首页文字改掉,再刷新。如果浏览器长时间仍显示旧版本,说明缓存策略与发布方式不匹配。
当时配置让index.html使用no-cache,要求再次使用前先向服务器确认;字体和图标相对稳定,设置7天缓存。
这不是永恒正确的数字。正式发布后,如果资源文件名带内容Hash,可以缓存更久;如果文件名不变,过长缓存会让用户继续拿旧文件。
“设置了缓存”只是名称。真正的问题是:内容变了以后,用户什么时候拿到新版本?
字体到底有没有加载
网页看起来像用了某种字体,不足以证明字体文件加载成功。系统回退字体可能长得很接近。
这次预部署检查了字体请求,并确认TTF由Nginx返回font/ttf。浏览器不仅看文件内容,也会参考Content-Type。类型错误可能导致资源被拒绝或在不同浏览器中表现不一致。
这就是直接验证:不要盯着屏幕猜,去看网络响应。
为什么不用新文件覆盖旧文件
服务器采用:
/opt/sanmu-site/releases/<release-name>
/opt/sanmu-site/current -> 某个已验证版本
每次先创建完整的新版本,核对文件清单和SHA-256,再切换current软链接。这样不会出现一半旧文件、一半新文件的中间状态。新版本有问题,也可以重新指回上一个版本。
第一次归档版本20260822-prelaunch-01带有不需要的macOS元数据文件,因此没有继续使用;干净版本20260822-prelaunch-02才成为当时的预览版本。
这件小事很有教育意义。上传命令没有报错,不等于发布包正确。机器完成了你要求的事,但你要求的事可能错了。
nginx -t证明了什么
修改配置后先运行:
nginx -t
它能检查语法和引用文件,降低错误配置导致重载失败的风险。但它不证明页面内容正确,也不证明公网边界正确。
完整验证还要看首页、资源、MIME类型、缓存、日志、原有服务和公网可达性。
把nginx -t通过当成部署完成,就像医生确认体温计没坏,然后宣布病人健康。这算检查吗?只检查了工具,没有检查结果。
Nginx没有替我完成什么
8月22日内部预部署结束时,官网仍未正式公开。后续还需要单独处理:
- ICP备案。
- 域名DNS解析。
- HTTPS证书。
- 公网80、443入口设计。
- 隐私政策和备案信息展示。
- 联系表单、访问统计、监控和备份。
它也不会自动处理应用的身份验证、数据隔离和业务权限。以后即使Nginx把请求转交给Node.js应用,这些责任仍在应用内部。
怎样验证理解
安装了Nginx、写了Server Block、运行nginx -t,都不等于网站已经安全上线。这些只是外在形式。
去掉形式,直接检查结果:目标入口能否访问、不该公开的入口能否被阻止、原有服务是否正常、错误资源是否诚实返回404、发布失败能否回滚。如果这些没有证据,控制塔搭好了,跑道灯也亮了,但你没有检查飞机能不能安全降落。
你真的搞清楚了吗
试着不用“Nginx”这个词回答:
- 为什么文件已经在服务器上,公网仍可能访问不到?
127.0.0.1:8081和0.0.0.0:8081的访问边界有什么不同?- 为什么不存在的图片应该返回404,而不是
index.html? nginx -t通过以后,还要验证什么?- 怎样用一个实验证明官网没有影响原有水滴服务?
如果能画出“请求从入口到文件”的路线,你就不是只会背配置名了。
我现在知道什么,还不知道什么
我现在能确定:Nginx站在服务器入口处,负责选择处理请求的配置、寻找静态文件、设置响应,并控制这次预览只在服务器内部可见。这个结论已经由配置和访问测试验证。
9月4日,官网已经完成域名解析、HTTPS和公网访问验证。内部预部署与公网发布是两次不同的验收;完整过程见《从本地页面到官网上线》。
资料与验证范围
- 项目配置:
deploy/nginx-sanmu-prelaunch.conf。 - 操作与验证:
deploy/README.md、docs/work-logs/2026-08-22.md和PROJECT_HANDOFF.md。 - 官方资料:How nginx processes a request、
try_files指令。 - 后续更新:2026年9月4日正式上线记录;联系表单和实时访问统计仍待接入。