主题
nginx 配置不生效:symlink 陷阱与三指令区别
一个血泪教训:改了 sites-available 里的文件以为能生效,因为 sites-enabled 里那个同名文件是独立副本而不是符号链接。
| 字段 | 内容 |
|---|---|
| 标签 | #nginx #配置排故 #symlink #reload #sites-enabled |
| 踩坑日期 | 2026-07-19 |
| 严重程度 | 🔴 中 |
事故经过
场景一:改了配置但死活不生效
那天给 kb.sirenzhuli.cn 更新 nginx 配置,增加一个 gzip 压缩的优化。改动很简单,在 /etc/nginx/sites-available/kb 里加了几行:
nginx
gzip on;
gzip_types text/css application/javascript text/plain;
gzip_min_length 256;然后:
bash
sudo nginx -t # ✅ syntax is ok
sudo systemctl reload nginx # ✅ 重载成功用浏览器打开页面,检查 Response Headers —— 没有 Content-Encoding: gzip。等了五分钟再试,还是没有。
重新 vim 打开 sites-available/kb,配置好好的在那里。折腾了一个多小时。
最终发现
bash
$ ls -la /etc/nginx/sites-enabled/
lrwxrwxrwx 1 root root 31 Jul 13 17:00 chat -> /etc/nginx/sites-available/chat
lrwxrwxrwx 1 root root 32 Jul 13 17:00 fayan -> /etc/nginx/sites-available/fayan
lrwxrwxrwx 1 root root 29 Aug 7 15:07 kb -> /etc/nginx/sites-available/kb
-rw-r--r-- 1 root root 1896 Aug 2 09:07 sandbox-proxy
-rw-r--r-- 1 root root 3303 Aug 1 23:42 sirenzhulisirenzhuli 和 sandbox-proxy 两个文件前面是 -rw-r--r--(普通文件),不是 l(符号链接)。
之前有人用 cp 而不是 ln -s 把这两个配置塞进了 sites-enabled。后来有人改了 sites-available/sirenzhuli 里的配置,但 sites-enabled/sirenzhuli 是独立副本,根本没被更新。
根因分析
第一层:nginx 到底读哪个目录
主配置文件 /etc/nginx/nginx.conf 里最关键的一行:
nginx
include /etc/nginx/sites-enabled/*;nginx 只读取 sites-enabled 目录。sites-available 只是一个"仓库",放着所有站点的配置模板/原件。
Ubuntu/Debian 的设计哲学:
text
sites-available/ ← 配置仓库(原件),nginx 不读
├── chat ← 真实配置
├── fayan
├── kb
└── sirenzhuli
sites-enabled/ ← 生效目录(符号链接或副本),nginx 只读这里
├── chat -> ../sites-available/chat ← symlink,改动同步生效
├── fayan -> ../sites-available/fayan
├── kb -> ../sites-available/kb
├── sandbox-proxy ← 独立普通文件,改了sites-available也没用
└── sirenzhuli ← 同上启用一个站点:ln -s sites-available/xxx sites-enabled/xxx 停用一个站点:rm sites-enabled/xxx(删除链接而已,原件还在)
第二层:cp vs ln -s 的本质区别
| 操作 | sites-enabled 里是什么 | 改 sites-available 会同步? |
|---|---|---|
ln -s (推荐) | 符号链接 → 指向原文件 | ✅ 自动同步 |
cp | 独立的文件副本 | ❌ 不会同步 |
符号链接就像一个快捷方式:当你读取 /etc/nginx/sites-enabled/kb 时,Linux 核心自动重定向到 /etc/nginx/sites-available/kb。所以改原文件等于改链接。
cp 复制是两个独立的文件:改了 sites-available/kb,sites-enabled/kb 纹丝不动。
第三层:三个"重载"命令的区别
这是另一个常见的混乱点:
bash
# 1. nginx -t → 只测试语法,不重载
sudo nginx -t
# 输出: syntax is ok / test is successful
# 作用:检查配置文件语法是否有错误(缺分号、括号不匹配等)
# 但不检测逻辑错误(端口冲突、upstream 不通等)
# 不重载配置!不生效!
# 2. nginx -s reload → 热重载(直接发信号)
sudo nginx -s reload
# 作用:向 nginx master 进程发送 SIGHUP 信号,触发重新读取配置
# 不中断现有连接,新连接用新配置
# 前提:必须能访问 nginx.pid 文件(/run/nginx.pid)
# 3. systemctl reload nginx → 通过 systemd 管理重载
sudo systemctl reload nginx
# 作用:systemd 帮你找到进程、发送信号
# 好处:统一的 systemd 管理界面,有日志、有状态跟踪
# 前提:nginx 必须是通过 systemd 管理的服务关系:systemctl reload nginx ≈ nginx -s reload(底层都是发 SIGHUP),但 systemctl 更规范。
什么时候用哪个:
| 场景 | 用什么 |
|---|---|
| 改了配置,不确定语法对不对 | nginx -t |
| 语法没问题,让新配置生效 | systemctl reload nginx |
| nginx 不是 systemd 管理的 | nginx -s reload |
| 想知道 nginx 正在加载什么配置 | nginx -T |
当前服务器的真实配置结构
服务器上实际有 4 个站点生效:
| 站点 | 域名 | sites-enabled 类型 | 说明 |
|---|---|---|---|
| 聊天 | chat.sirenzhuli.cn | symlink ✅ | 指向 sites-available/chat |
| 法眼 | fayan.sirenzhuli.cn | symlink ✅ | 指向 sites-available/fayan |
| 知识库 | kb.sirenzhuli.cn | symlink ✅ | 指向 sites-available/kb(Let's Encrypt 自动管理) |
| 小雅主页 | www.sirenzhuli.cn | 普通文件 ⚠️ | 独立副本,需要手动同步 |
| 沙箱代理 | (端口 8899) | 普通文件 ⚠️ | 独立副本,没有对应 sites-available |
解决方案
正确的工作流
Step 1:永远从 sites-available 开始
bash
sudo vim /etc/nginx/sites-available/sirenzhuliStep 2:如果 sites-enabled 里是普通文件 → 先删掉,再建 symlink
bash
# 检查状态
ls -la /etc/nginx/sites-enabled/sirenzhuli
# 如果是普通文件(-rw-r--r--),先备份
sudo cp /etc/nginx/sites-enabled/sirenzhuli /etc/nginx/sites-available/sirenzhuli.bak
# 删除 sites-enabled 里的副本
sudo rm /etc/nginx/sites-enabled/sirenzhuli
# 建符号链接
sudo ln -s /etc/nginx/sites-available/sirenzhuli /etc/nginx/sites-enabled/sirenzhuli
# 验证
ls -la /etc/nginx/sites-enabled/sirenzhuli
# 预期输出: lrwxrwxrwx ... sirenzhuli -> /etc/nginx/sites-available/sirenzhuliStep 3:语法检查 → 重载 → 验证
bash
sudo nginx -t && sudo systemctl reload nginx一键诊断命令
bash
# 列出 sites-enabled 中的所有文件,标注类型
ls -la /etc/nginx/sites-enabled/
# 看 nginx 实际加载的所有配置(含所有 server 块)
sudo nginx -T 2>/dev/null | grep -E "^# configuration file|server_name|listen" | head -40
# 检查有没有 orphan 文件(sites-available 有但 sites-enabled 没有链接的)
comm -23 <(ls /etc/nginx/sites-available/ | sort) <(ls /etc/nginx/sites-enabled/ | sort)
# 输出示例: default, miniflux — 这些配置存在但未启用预防措施
铁律
- 永远用
ln -s,不许用cp— 进sites-enabled的唯一合法方式 - 改配置前先
ls -la /etc/nginx/sites-enabled/— 确认链接状态 - 改完配置先
nginx -t再systemctl reload nginx— 两步缺一不可 - 怀疑不生效时跑
nginx -T— 直接看 nginx 真正加载的内容
日常检查命令
bash
# 定时任务(cron weekly):检查是否有副本而非symlink
find /etc/nginx/sites-enabled/ -maxdepth 1 -type f ! -type l
# 如果有输出 → 那些文件就是隐患,该改成 symlink关联知识点
- SSL 证书迁移实战 — nginx + SSL 证书组合排故
- 前端排故方法论 — DNS→端口→服务→API→功能 五步排查
- Linux 文件系统 — 软链接 vs 硬链接的 inode 原理
- systemd 服务管理 —
systemctl reloadvsrestart的区别 - 计算机网络故障排查 — DNS 和端口检测
🎯 本章要点
- 改配置后必须
nginx -t检查语法,再重载 nginx -s reload热重载不会断开已有连接- sites-enabled 应通过 symlink 指向 sites-available
加载练习题中...