主题
nginx 配置不生效?搞懂 sites-available 和 sites-enabled
一句话总结:nginx 配置改了不生效,99% 是因为没搞清楚 sites-available 和 sites-enabled 之间的符号链接机制,改错了文件或没做软链接。
| 字段 | 内容 |
|---|---|
| 标签 | #nginx #配置排故 #symlink #sites-enabled #DevOps |
| 踩坑日期 | 2026-07-19 |
| 严重程度 | 🔴 中 |
事故经过
时间线
那天风哥让我给一个新站点配 nginx,子域名 xxx.sirenzhuli.cn 要指向后端 8898 端口。
操作过程(错误的):
- 我信心满满地
vim /etc/nginx/sites-available/xxx,写了一个漂亮的配置文件 nginx -t检测通过,语法没问题systemctl reload nginx,重启服务- 浏览器访问
xxx.sirenzhuli.cn→ 404 Not Found - 我盯着配置反复看,哪里写错了?
nginx -t再跑一次,还是 OK- 抓狂了半小时……
最终发现:
bash
ls -la /etc/nginx/sites-enabled/——里面根本没有我新建的那个配置文件!
还有一次更坑的: 我之前改过 DNS,把某个子域名从旧 IP 指向了新 IP,结果旧 APP 还在用域名请求,直接全军覆没。教训在下面一起讲。
根因分析
第一层:出错了文件,改了个寂寞
nginx 在启动/重载时真正读取的是 /etc/nginx/sites-enabled/ 目录下的文件,而不是 /etc/nginx/sites-available/。
主配置文件 /etc/nginx/nginx.conf 里通常有这样一行:
nginx
include /etc/nginx/sites-enabled/*;也就是说——只有 sites-enabled 里的文件才会被加载,sites-available 只是一个"仓库",放着你所有的站点配置模板。
第二层:为什么这样设计?
这是 Debian/Ubuntu 系 Linux 的最佳实践:
| 目录 | 作用 | 被 nginx 读取? |
|---|---|---|
sites-available/ | 所有站点配置的原件存放地(仓库) | ❌ 不读取 |
sites-enabled/ | 需要启用的站点配置的符号链接(实际生效) | ✅ 读取 |
好处:想启用一个站点就 ln -s 做个软链接,想停掉就 rm 删链接,配置文件本身不动。比直接改文件名优雅得多。
第三层:符号链接 vs 直接复制
很多新手会 cp sites-available/xxx sites-enabled/xxx,这样做虽然也能生效,但会带来一个隐患:
- 后面你改了
sites-available/xxx,但sites-enabled/xxx还是老版本(因为是 cp 不是 ln) - 于是你又一次陷入"改了怎么不生效"的困境
正确的做法就是 ln -s 做符号链接。
第四层:DNS 变更的连锁反应
回到 DNS 的问题。风哥的教训 #1:"改 DNS 没考虑旧 APP"。
当你改了一个域名的 A 记录,旧的 APP/客户端如果没做热更新,会直接请求到旧 IP。看起来就像"nginx 不生效",其实是请求根本没到这台服务器。
所以排查 nginx 配置问题的第一步永远是:确认请求到底到了没有。
解决方案
标准工作流(复制即用)
Step 1:创建配置文件
bash
sudo vim /etc/nginx/sites-available/xxx写一个基础反向代理配置:
nginx
server {
listen 80;
server_name xxx.sirenzhuli.cn;
location / {
proxy_pass http://127.0.0.1:8898;
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;
}
}Step 2:检查 sites-enabled 里到底有什么
bash
ls -la /etc/nginx/sites-enabled/看看已有的文件是 symlink 还是普通文件:
bash
# 如果是软链接(箭头 → 指向原文件)
lrwxrwxrwx 1 root root 41 Jul 19 12:00 default -> /etc/nginx/sites-available/default
# 如果是普通文件(- 开头,没有箭头)
-rw-r--r-- 1 root root 1234 Jul 19 12:00 defaultStep 3:创建符号链接
bash
sudo ln -s /etc/nginx/sites-available/xxx /etc/nginx/sites-enabled/xxxStep 4:语法检查(永远别跳过这步!)
bash
sudo nginx -t预期输出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulStep 5:重载配置(不中断服务)
bash
sudo systemctl reload nginx⚠️ 用
reload而不是restart!reload不中断现有连接,restart会断开所有请求。
常见踩坑排查命令
bash
# 1. 看 nginx 到底加载了哪些 server 块
sudo nginx -T 2>/dev/null | grep -A 20 "server_name"
# 2. 看某个域名解析到了哪里
dig +short xxx.sirenzhuli.cn
# 3. 看端口有没有在监听
sudo ss -tlnp | grep nginx
# 4. 测试请求是否真的到了 nginx
curl -v -H "Host: xxx.sirenzhuli.cn" http://127.0.0.1/
# 5. 实时看 nginx 访问日志(确认请求到了没有)
sudo tail -f /var/log/nginx/access.log预防措施
操作前确认清单
每次改 nginx 配置前,先跑:
bash
# □ 确认 sites-enabled 里有什么
ls -la /etc/nginx/sites-enabled/
# □ 确认当前生效的配置内容
sudo nginx -T 2>/dev/null | grep -E "(server_name|listen|proxy_pass)" | head -30
# □ 确认 DNS 解析正确
dig +short xxx.sirenzhuli.cn改完配置必须做
bash
# □ 语法检查
sudo nginx -t
# □ 重载
sudo systemctl reload nginx
# □ 验证服务状态
sudo systemctl is-active nginx # 应该输出 active
# □ 实际请求测试
curl -I -H "Host: xxx.sirenzhuli.cn" http://localhost/铁律
- 永远用
ln -s而不是cp:确保sites-available和sites-enabled保持同步 - 改配置前先看
sites-enabled:确认链接状态,别改了半天改的是死链接 - 用
reload不用restart:生产环境别断流 nginx -t是底线:这条命令不绿,别动 prod
关联知识点
- SSL 证书从 TrustAsia 切 Let's Encrypt 全记录 — nginx 配置 + SSL 证书的组合排故
- Linux 进程管理 — systemctl 原理和 status/is-active 的区别
- Linux 文件系统 — 软链接 vs 硬链接、inode 原理
- 计算机网络故障排查 — DNS 解析和端口检测
- 前端排故方法论 — DNS→端口→服务→API→功能 五步排查法
🎯 本章要点
- nginx -t先检查语法,确认无误再reload,否则服务中断
- sites-enabled用ln -s指向sites-available,cp独立文件会导致不同步
加载练习题中...