← 全部笔记

实践记录 · 入门

从本地页面到Nginx服务器

Nginx站在服务器入口处,决定接收哪些请求、去哪里找文件、返回什么结果,以及预览入口是否会意外暴露到公网。

三幕 · 更新于 2026-09-06 · 实践过

内容审阅稿 · 待确认后发布

文章目录

这篇记录复盘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;

逐句翻译成人话:

你不需要先知道Nginx的全部指令。只要能回答“谁在什么门口等着”“东西放在哪里”“默认拿哪一件”,这三行就搞清楚了。

Nginx官方文档说明,它会先根据监听地址和端口确定候选Server Block,再结合请求中的Host选择处理请求的服务器配置。路径匹配则决定后续使用哪个location。

为什么不直接使用80端口

当时服务器的公网80端口已有水滴服务在运行。端口不是抽象编号,它是正在被程序占用的入口。

如果为了预览官网直接改写80端口配置,可能让原有服务中断。于是这次选择了另一个入口,并把它限制在127.0.0.1。需要从自己的电脑预览时,再通过SSH端口转发进入。

这次实际验证得到四个结果:

这四项合在一起,才证明“官网已经内部预部署,而且没有抢走原服务”。只看第一项不够。

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日内部预部署结束时,官网仍未正式公开。后续还需要单独处理:

它也不会自动处理应用的身份验证、数据隔离和业务权限。以后即使Nginx把请求转交给Node.js应用,这些责任仍在应用内部。

怎样验证理解

安装了Nginx、写了Server Block、运行nginx -t,都不等于网站已经安全上线。这些只是外在形式。

去掉形式,直接检查结果:目标入口能否访问、不该公开的入口能否被阻止、原有服务是否正常、错误资源是否诚实返回404、发布失败能否回滚。如果这些没有证据,控制塔搭好了,跑道灯也亮了,但你没有检查飞机能不能安全降落。

你真的搞清楚了吗

试着不用“Nginx”这个词回答:

  1. 为什么文件已经在服务器上,公网仍可能访问不到?
  2. 127.0.0.1:8081和0.0.0.0:8081的访问边界有什么不同?
  3. 为什么不存在的图片应该返回404,而不是index.html?
  4. nginx -t通过以后,还要验证什么?
  5. 怎样用一个实验证明官网没有影响原有水滴服务?

如果能画出“请求从入口到文件”的路线,你就不是只会背配置名了。

我现在知道什么,还不知道什么

我现在能确定:Nginx站在服务器入口处,负责选择处理请求的配置、寻找静态文件、设置响应,并控制这次预览只在服务器内部可见。这个结论已经由配置和访问测试验证。

9月4日,官网已经完成域名解析、HTTPS和公网访问验证。内部预部署与公网发布是两次不同的验收;完整过程见《从本地页面到官网上线》。

资料与验证范围