---
url: /courses/cloud-platform-build-management/03-nginx-service-network/index.md
---
# 第三次课：部署并排查 Nginx 服务

## 进入本课环境

* `[Windows PowerShell] wsl ~`：打开本机默认的 WSL2 Ubuntu；出现 `用户名@主机名:~$` 后再执行标为 `[WSL]` 的命令。
* `[WSL] ssh root@你的ECS公网IP`：从 WSL 连接自己的 ECS；如果登录用户不是 `root`，请换成控制台显示的实际用户，看到远端提示符后再执行标为 `[ECS]` 的命令。

浏览器里的一张网页，背后至少要有三样东西：一个正在运行的服务、一个正在监听的端口、一条放行的网络路径。

本课在 ECS 上安装 Nginx，发布“云平台课程学习站”的第一张静态页面，然后用服务、端口、HTTP 和安全组证据，把“能访问”或“访问失败”的原因讲清楚。

完成后应留下：

* 一个可以从浏览器访问的 Nginx 首页；
* 一组服务状态、监听端口、本机访问和公网访问证据；
* 一份“现象—证据—原因—修复—验证”故障报告。

::: warning 安全边界
本课会安装软件、修改站点文件和开放 Web 端口。每次变更前确认当前终端位于自己的 ECS，切勿在公共演示机上停止服务或修改配置。
:::

## 3.1 浏览器怎样拿到一张网页

访问一个网站时，请求大致经过以下路径：

```txt
浏览器或 curl
  -> DNS 解析（使用域名时）
  -> 服务器 IP
  -> TCP 端口
  -> 云侧安全组
  -> 主机防火墙
  -> Nginx 监听端口
  -> 站点文件
  -> HTTP 响应
```

这条路径包含几个常用概念：

* **IP 地址**（用于在网络中找到一台主机或一个网络接口）。本课先使用 ECS 公网地址访问。
* **端口**（一台主机上用于区分不同网络服务的编号）。HTTP 常用 TCP（传输控制协议）80，HTTPS 常用 TCP 443，SSH 常用 TCP 22。
* **DNS**（把域名查询为 IP 地址的系统）。直接使用公网地址访问时，可以暂时跳过 DNS。
* **HTTP**（浏览器与 Web 服务交换请求和响应的应用层协议）。状态码和响应头是判断访问结果的重要证据。

::: tip 关键提醒
公网地址只负责找到主机，端口负责找到主机上的服务。能 SSH 登录 22 端口，不代表 80 端口上的 Web 服务一定可以访问。
:::

## 3.2 服务、端口与访问路径

排查 Nginx 服务，建立分层调取的习惯：

1. **服务状态层**：Nginx 进程是否在 systemd 中正常运行（`systemctl status`、`journalctl`）；
2. **监听端口层**：进程是否正常绑定并监听 TCP 80 端口（`ss -lntp`）；
3. **本机 HTTP 层**：Nginx 能否在服务器本地正常响应页面（`curl -I http://127.0.0.1`）；
4. **公网链路层**：请求能否穿越安全组与防火墙连通外部（WSL `curl` 或浏览器）。

这四层层层递进，绝不能凭单层结果草率下结论：

* 服务处于 `active`（运行中）状态，不代表它一定绑定了正确的端口；
* 端口确实在监听，也需要真实的 HTTP 请求才能检验响应内容；
* 本机 `curl 200` 只过了服务内部这一关，云侧安全组放没放行还是未知；
* 公网浏览器成功打开首页，也不意味着可以跳过对错误日志与配置规范的核对。

## 3.3 安装 Nginx

安装前，习惯性检查当前环境：

* `whoami`、`hostname`：核对账号与主机，严防误装到 WSL 或错误实例；
* `df -hT /`：确认根分区剩余容量；
* `apt-cache policy nginx`：确认系统软件包仓库中的 Nginx 版本。

```bash
[ECS] whoami
[ECS] hostname
[ECS] df -hT /
[ECS] apt-cache policy nginx
```

确认无误后，更新软件包列表并安装：

```bash
[ECS] sudo apt update
[ECS] sudo apt install nginx
```

安装过程会列出新增软件包和磁盘占用。看清楚确认信息再继续，没搞明白会改什么之前，慎用 `-y` 参数。

安装完成不等于服务可用。用下面三条命令检查：

* `systemctl is-active nginx`：快速判断服务当前是否处于活动状态。
* `systemctl is-enabled nginx`：判断服务是否设置为随系统启动。
* `systemctl status nginx --no-pager`：查看状态、主进程和最近的服务信息。

```bash
[ECS] systemctl is-active nginx
[ECS] systemctl is-enabled nginx
[ECS] systemctl status nginx --no-pager
```

`active (running)` 说明 systemd 认为服务正在运行，但这离确认 80 端口可访问还差一步——接着查监听端口。

## 3.4 检查监听端口和本机 HTTP

下面三条命令分别检查配置、端口和 HTTP：

* `sudo nginx -t`：检查 Nginx 配置语法以及引用的配置文件是否可以读取；修改配置后、重新加载前使用。
* `sudo ss -lntp 'sport = :80'`：只查看监听 TCP 80 的套接字及关联进程。
* `curl -I http://127.0.0.1`：从 ECS 本机发送 HTTP 请求，只查看响应头。

```bash
[ECS] sudo nginx -t
[ECS] sudo ss -lntp 'sport = :80'
[ECS] curl -I http://127.0.0.1
```

观察三个关键结果：

1. `nginx -t` 应显示配置语法检查成功。
2. `ss` 应出现 Nginx 监听的 80 端口；`0.0.0.0:80` 表示监听所有 IPv4 本地地址，`[::]:80` 表示监听 IPv6 地址。
3. `curl -I` 出现 `HTTP/1.1 200 OK` 时，说明本机请求已经得到成功响应。

如果 `curl` 返回 `404 Not Found`，请求通常已经到达 Web 服务，只是目标资源没有找到；如果连接被拒绝，则应先检查端口和服务状态。

{{guided-demo:lesson-03-service-port-path}}

### 真实案例：共享云主机上的隔离验证

下面的案例运行在云主机 B 的课程专用 Compose 项目中。为了不碰共享主机上已有服务，Nginx 只绑定远端回环地址 `127.0.0.1:18003`。检查顺序仍然与本课一致：先看容器状态，再做 `nginx -t`，接着检查监听端口，最后用 `curl` 验证状态码和页面标记。

## 3.5 发布课程学习站首页

课程文件在自己实验目录中准备好，再由 `sudo` 安装到站点目录：

```bash
[ECS] mkdir -p ~/cloud-course/lab-03/backup
[ECS] cd ~/cloud-course/lab-03
[ECS] sudo cp -a /var/www/html/. ./backup/
[ECS] nano index.html
```

在 `index.html` 中写入：

```html
<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>云平台课程学习站</title>
</head>
<body>
  <h1>云平台课程学习站</h1>
  <p>第 3 次课：Nginx 已在 ECS 上运行。</p>
</body>
</html>
```

保存后先检查文件，再安装到 Nginx 默认站点目录：

```bash
[ECS] sed -n '1,20p' index.html
[ECS] sudo install -m 0644 index.html /var/www/html/index.html
[ECS] stat /var/www/html/index.html
[ECS] curl -s http://127.0.0.1 | sed -n '1,20p'
```

更新静态 HTML 文件不需要重启或重新加载 Nginx。只有配置发生变化时，才先运行 `nginx -t`，再执行：

```bash
[ECS] sudo systemctl reload nginx
```

`reload` 让 Nginx 重新读取配置；它不是修一切问题的万能按钮。

## 3.6 安全组与主机防火墙

公网请求可能经过两道网络门禁：

**阿里云安全组**

* 位于云平台一侧，控制 ECS 的入方向和出方向流量。
* 本课只新增 TCP 80 入方向规则。
* 公开课程首页时，只将本课需要的 TCP 80 面向公网开放。

**Ubuntu 主机防火墙**

* 位于 ECS 操作系统内部，课程使用 `ufw` 检查。
* 先查看状态；未确认现有 SSH 规则前，切勿直接启用或重置防火墙。

```bash
[ECS] sudo ufw status verbose
```

如果输出为 `Status: active`，在确认 SSH 访问不会受影响的前提下，只增加 Web 端口：

```bash
[ECS] sudo ufw allow 80/tcp
[ECS] sudo ufw status numbered
```

如果输出为 `Status: inactive`，记录当前状态即可，无需临时启用。

安全组规则至少核对五项：

* 方向：入方向。
* 协议：TCP。
* 目标端口：80。
* 来源：按本次发布范围设置，不开放其他无关端口。
* 说明：第 3 次课 Nginx HTTP。

::: warning 安全边界
不要删除原有 SSH 规则，也不要把“全部协议、全部端口、所有来源”作为排障办法。修改规则前保留原状态，修改后只验证本课需要的 TCP 80。
:::

## 3.7 从 WSL 和浏览器验证公网访问

ECS 本机 `curl` 成功后，再从 WSL 测试外部路径。先把变量值替换为自己的 ECS 公网地址：

```bash
[WSL] ECS_IP="在这里填写自己的ECS公网地址"
[WSL] curl -I "http://$ECS_IP"
```

随后在 Windows 浏览器地址栏输入自己的 HTTP 地址。页面应出现“云平台课程学习站”。

三份证据回答的问题各不相同：

* ECS 本机 `curl`：Nginx 能否在服务器内部响应。
* WSL `curl`：TCP 80 是否能从外部经过安全组和主机防火墙。
* 浏览器页面：完整 HTML 是否可以被用户正常读取。

截图时保留 HTTP 状态、服务器提示符和页面标题，隐藏完整公网地址。

案例使用 SSH 隧道把远端 `127.0.0.1:18003` 临时映射到本地控制端 `127.0.0.1:11803`，浏览器实际取得了同一站点页面。隧道没有扩大服务器的公网暴露范围。

## 3.8 查看 Nginx 日志

日志分三路检查：

* `journalctl -u nginx -n 30 --no-pager`：查看 systemd 记录的 Nginx 启停和服务错误；服务启动失败时使用。
* `tail -n 20 /var/log/nginx/access.log`：查看最近到达 Nginx 的 HTTP 请求；确认请求是否真正到达服务。
* `tail -n 20 /var/log/nginx/error.log`：查看 Nginx 处理请求或读取文件时记录的错误。

```bash
[ECS] sudo journalctl -u nginx -n 30 --no-pager
[ECS] sudo tail -n 20 /var/log/nginx/access.log
[ECS] sudo tail -n 20 /var/log/nginx/error.log
```

如果 WSL 请求之后 `access.log` 出现了对应记录，说明请求已经到达 Nginx。反过来，外部请求超时、访问日志却完全没有新记录，问题多半还在 Nginx 之前的网络路径上——不过仍要结合服务、端口和安全组证据一起判断。

日志中可能包含访问来源和请求路径。作业只截取必要行，并对公网地址和无关信息脱敏。

## 3.9 按证据定位访问故障

常见现象及排查方向：

**`systemctl` 显示 inactive（未运行）**

* 已有证据：服务没有运行。
* 优先检查：`systemctl status`、`journalctl` 和配置语法。

**服务 active，但没有监听 TCP 80**

* 已有证据：systemd 服务状态与预期端口不一致。
* 优先检查：`nginx -t`、Nginx `listen` 配置和日志。

**ECS 本机返回 200，WSL 超时**

* 已有证据：服务内部链路基本正常。
* 优先检查：安全组、活动中的主机防火墙和目标公网地址。

**HTTP 返回 404**

* 已有证据：请求已经到达 HTTP 服务，但资源没有找到。
* 优先检查：URL、站点根目录、文件名和访问日志。

**HTTP 返回 403**

* 已有证据：请求已经到达服务，但访问被拒绝。
* 优先检查：文件和目录权限、Nginx 配置和错误日志。

故障报告统一记录：

```txt
原始现象：
命令运行位置：
服务状态证据：
监听端口证据：
本机 HTTP 证据：
公网路径证据：
当前原因：
采取的最小修复：
修复后验证：
```

{{chat-lab:lesson-03-nginx-evidence}}

案例随后只停止本课的 `web` 容器，回环入口立即出现 `Connection refused` 和 curl 退出码 7。启动容器并等待健康检查后，沿原地址重新检查，状态码恢复为 200，页面标记也再次出现。这说明恢复服务后仍要重新核对端口、HTTP 和内容，不能只看启动命令没有报错。

## 3.10 实训：部署并排查 Nginx

实训分为四项任务：

1. **安装与服务检查**：安装 Nginx，保留软件包、服务状态和配置检查证据。
2. **首页发布**：备份默认页面，发布课程学习站首页并从 ECS 本机验证。
3. **公网验证**：只开放 TCP 80，从 WSL 和 Windows 浏览器验证。
4. **故障工单**：排查服务停止、监听端口错误或安全组缺失等给定案例，切勿在共享服务器上自行制造故障。

ECS 暂不可用时，可以在 WSL 完成网络路径图、命令识读和给定故障案例，服务器可用后再补充服务、端口和公网证据。WSL 本机页面不能作为公网 ECS 结果。

完整步骤、截图清单和验收脚本见[实训 03：部署并排查 Nginx](./lab-03.md)。配套文件位于该页面链接的课程资源目录。

提交前停止 Nginx 并清理防火墙规则：

```bash
[ECS] sudo systemctl stop nginx
[ECS] sudo ufw delete allow 80/tcp
[ECS] rm -rf ~/cloud-course/lab-03
```

最终提交：

```txt
班级_学号_姓名_第03次课_Nginx服务与端口故障报告.docx
```

Word 中依次放入安装前检查、服务状态、监听端口、本机 HTTP、课程首页、公网访问、日志和故障工单。每张截图都要写明运行位置、关键输出和结论。

{{reflection-checkpoint:lesson-03-nginx-ready}}

::: tip 关键提醒
整理完成后，将一个最终 .docx 上传到智慧职教在线平台“第03次课”对应的作业收集中。不要上传含公网地址的终端记录、控制台原图或服务器配置目录。
:::

## 3.11 第三次课小测

小测检查以下判断能力：

* 能否区分服务状态、监听端口和 HTTP 响应；
* 能否根据本机与公网测试缩小故障范围；
* 能否正确使用日志和最小安全组规则；
* 能否在配置变更前检查、变更后验证。

{{assessment:lesson-03-check}}

## 3.12 小结

本课搭好了课程学习站的第一个 Web 服务：

* systemd 负责管理 Nginx 服务，进程是服务运行后的具体活动。
* `ss` 证明端口是否监听，`curl` 证明 HTTP 是否返回响应。
* ECS 本机成功不等于公网成功，外部路径还要经过主机防火墙和安全组。
* `journalctl`、访问日志和错误日志分别提供不同层面的证据。
* 故障排查按服务、端口、本机 HTTP、公网路径逐层缩小范围。

下一次课备份 Nginx 站点目录，比较本地文件、云盘、快照和对象存储的区别，并完成一次可验证的恢复。

{{assistant-invite:lesson-03-finish}}
