-今日
-本周
-本月
-累计
项目工作台运维 个人项目与实践记录
← 上一篇
我的手记第 1 篇 / 共 9 篇

手记 001:部署第一个静态页面

日期: 2026-09-14 用时: 约 40 分钟 难度: ⭐☆☆☆☆


1. 现象

任务要求在 8090 端口部署一个静态页面。执行过程中出现四次操作错误, 其中第三次为 nginx -t 无法检测的错误。

1.1 目录命名错误

使用 mkdir quest01.html 创建站点目录。该命令创建的是目录,但名称后缀 .html 造成混淆。执行 cat quest01.html 时报错:

cat: quest01.html: Is a directory

随后重命名为 quest01

1.2 root 指令使用相对路径

初次编写的配置为:

root   var/www/quest01;

nginx -t 检查通过:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

但该配置不正确。执行 nginx -V 可见 nginx 编译前缀为 /usr/share/nginx, 因此上述相对路径实际解析为:

/usr/share/nginx/var/www/quest01

该目录不存在。若直接执行 reload,端口会正常监听,但访问将返回 404, 且 nginx -t 不产生任何提示。

1.3 listen 端口错误

任务要求 8090,初次填写为 80。而 80 端口已被现有站点占用, 执行 reload 可能导致 server_name 冲突,影响正在运行的生产站点。

1.4 命令拼写错误

$ ngins -t
-bash: ngins: command not found

nginx 误写为 ngins


2. 排查过程

2.1 确认目标目录权限

stat -c '%A %U:%G %n' /root /srv /var/www

输出:

dr-xr-x--- root:root /root
drwxr-xr-x root:root /srv
drwxr-xr-x root:root /var/www

/root 权限为 dr-xr-x---,others 位为 ---,即 nginx 用户无法进入该目录。 结论:站点不能部署在 /root 下。/srv/var/www 的 others 位为 r-x, 二者均可作为站点根目录。

2.2 确认 nginx worker 运行身份

ps -eo user,cmd | grep '[n]ginx: worker'

输出:

nginx    nginx: worker process
nginx    nginx: worker process

worker 进程以 nginx 用户运行,非 root。因此站点文件的权限设置 需满足 nginx 用户的读取要求。

2.3 以 nginx 用户身份验证目录可读性

sudo -u nginx test -r /var/www && echo "能读" || echo "不能读"

输出 能读

该方法比 ls -l 更可靠:权限需沿整条路径检查,路径中任一级目录缺少 x 位都会导致访问失败,而 ls -l 仅显示末级对象的权限。

2.4 配置 nginx 前先验证文件权限

sudo -u nginx test -r /var/www/quest01/index.html && echo "ok" || echo "no"

输出 ok

该步骤的目的是隔离变量:若在配置完成后才发现访问失败, 将无法判断失败源于权限还是配置。

2.5 配置修改后逐级验证

cat /etc/nginx/conf.d/quest01.conf    # 确认内容
nginx -t                               # 语法检查
systemctl reload nginx                 # 加载配置

未在保存配置后立即 reload。该做法使 1.2 与 1.3 两处错误在生效前被拦截。


3. 根因

核心问题在于 nginx -t 仅检查语法,不检查语义

var/www/quest01 作为相对路径字符串在语法上合法,因此 nginx -t 报告 "test is successful"。但其解析结果指向不存在的路径, 仅在运行时表现为 404。

其余三处错误(目录命名、端口填写、命令拼写)属操作失误, 共同特征是:若缺少验证环节,错误会持续传递至后续步骤。


4. 修复

配置修改两处:

listen       8090;              # 由 80 改为 8090
listen       [::]:8090;         # 同步修改 IPv6 监听
server_name  quest01.test;      # 显式命名,避免与现有 server_name _ 重叠
root         /var/www/quest01;  # 补全路径开头的斜杠

执行顺序:

cat /etc/nginx/conf.d/quest01.conf     # 1. 确认内容
nginx -t                               # 2. 语法检查
systemctl reload nginx                 # 3. 平滑加载
ss -tlnp | grep 8090                   # 4. 确认端口监听
curl -s http://127.0.0.1:8090/ | head  # 5. 验证内容

验证结果:

  1. curl 返回的 HTML 中 <title> 为预期内容。
  2. 任务检查器 7 项全部通过:
✅ 8090 端口正在监听
✅ HTTP 返回 200
✅ 页面包含 'Chen Jin 的运维练手区'
✅ 页面标题包含你的名字
✅ 生产站点 /                  HTTP 200
✅ 生产站点 /postmortem.html   HTTP 200
✅ 生产站点 /ops.html          HTTP 200

后三项验证本次改动未影响正在运行的生产站点。


5. 结论

  1. 先验证权限、再配置 nginx 这一顺序是有效的。

在配置 nginx 之前先确认 "nginx 用户能够读取文件", 使后续若出现问题可直接排除权限因素。变量被隔离, 排查范围相应缩小。

  1. nginx -t 通过不代表配置正确。

该命令只做语法检查。本次它放过了一个会导致 404 的语义错误 (相对路径解析位置错误)。

  1. 配置修改后应先确认内容,再执行加载。

逐级验证(cat → nginx -t → reload → 检查监听 → 验证内容) 使 1.2 与 1.3 两处错误在生效前被发现,避免了生产站点受影响。

  1. 权限验证应以行为为准,而非命令返回值。

nginx -t 返回 successful,但真正的验证是 curl 是否取得预期内容。


6. 遗留问题

无。任务 001 完成。


7. 后续计划

学习使用 systemd 托管自建服务。先前任务中仅使用 nginx 自带的 unit 文件, 尚未涉及从零编写服务单元的流程。

← 上一篇
我的手记第 1 篇 / 共 9 篇

可用键盘 ← → 切换上下篇