记录一次真实部署:Ubuntu 上装 nginx,把一个静态站点挂到子域名上。看起来是最基础的活,我还是踩了 5 个坑。
坑 1:改完配置,访问还是老页面
改完 sites-available 里的配置,执行 systemctl reload nginx,然后立刻 curl —— 返回的还是旧内容。
原因:reload 是异步的。命令返回时,老 worker 进程还活着,正在处理已有连接;新 worker 要稍后才接管新连接。我测得太快了。
sudo nginx -t && sudo systemctl reload nginx
sleep 2 # 给 worker 一点时间
ps -eo pid,lstart,cmd | grep "nginx: worker" # 看 worker 启动时间
教训:验证配置是否生效,别只看命令返回码。看 worker 进程的启动时间,或者等一两秒再测。
坑 2:404 兜底没生效
我想让"IP 直连"和"未知域名"都返回 404,只让正式域名能访问。写了:
server {
listen 80 default_server;
server_name _;
return 404;
}
结果 IP 直连还是能打开站点。原因是——老的默认站点还在 sites-enabled 里,它同样声明了 default_server。nginx 会警告冲突,但用"先出现的那个"。
ls -la /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default # 移除默认站点
规则:整个 nginx 里
default_server 只能有一个。坑 3:中文全是乱码
页面 <meta charset="UTF-8"> 写了,浏览器里还是乱码。原因是响应头里没有 charset:
Content-Type: text/html ← 没告诉浏览器用什么编码
在 server 块里加一行就好:
server {
charset utf-8; # 加上这个
}
之后响应头变成 Content-Type: text/html; charset=utf-8,问题消失。
坑 4:403 Forbidden
文件明明在,nginx 却报 403。两个常见原因:
- 权限:nginx 以
www-data身份运行,文件要让它能读 →chmod 644 - 目录没有执行位:目录需要
x权限才能"进入" →chmod 755
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod 755 /var/www/mysite # 目录
sudo chmod 644 /var/www/mysite/*.html # 文件
坑 5:软链建了但没生效
Ubuntu 的 nginx 只读 sites-enabled/,配置要放在 sites-available/ 再软链过去:
sudo ln -sf /etc/nginx/sites-available/mysite \
/etc/nginx/sites-enabled/mysite
我漏了这一步,改半天配置都没反应。养成习惯:改完先 ls -la sites-enabled/ 确认软链在。
总结成一张排查表
| 现象 | 先查什么 |
|---|---|
| 改了配置没反应 | 软链建了吗?reload 完等了吗? |
| 404 兜底失效 | 是不是有两个 default_server? |
| 中文乱码 | 响应头里有 charset 吗? |
| 403 Forbidden | 文件和目录权限对不对? |
| 语法报错 | 永远先跑 nginx -t |
这 5 个坑里,有 3 个的本质是同一个:"我以为是那样,其实不是那样"。
所以运维的每一步都要验证,不能想当然。