---
url: /courses/cloud-platform-build-management/04-storage-backup-transfer/index.md
---
# 第四次课：备份、传输与恢复 Nginx 站点

## 进入本课环境

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

第三次课已经把课程学习站发布到了 Nginx。接着自然要问：万一首页被误删，站点还能恢复吗？

本课做的事情：把 `/var/www/html` 打成带时间戳的归档，生成 SHA-256 校验值，传到 WSL，然后在隔离目录里走一遍“删了再恢复”的完整测试。

完成后应留下：

* 一个带日期时间的 Nginx 站点备份包；
* 一个与备份包配套的 SHA-256 校验文件；
* ECS 与 WSL 两端的校验、传输和恢复证据；
* “文件误删”和“云盘或实例故障”两种恢复方案。

::: warning 安全边界
恢复练习只删除 `~/cloud-course/lab-04/restore-test` 中的测试文件，不删除在线站点 `/var/www/html`。创建快照和 OSS 资源可能产生费用，本课只讲用途，不要求学生自行购买。
:::

## 4.1 文件存放在哪一层

在 Linux 中，站点文件经过以下关系落到云盘：

```txt
/var/www/html/index.html
  -> 目录与文件
  -> 文件系统
  -> 挂载点
  -> 分区或逻辑块设备
  -> ECS 云盘
```

几个概念对应不同的存储层级：

* **文件系统**（在块设备上组织目录、文件、权限和空间的数据结构），例如 ext4、xfs。
* **挂载**（把一个文件系统接入 Linux 目录树，使其可以通过某个目录访问）。
* **云盘**（提供给 ECS 使用的块存储设备，操作系统通常把它识别为磁盘设备）。
* **快照**（针对云盘某个时间点创建的备份，用于创建云盘或回滚等恢复场景）。
* **对象存储**（通过 Bucket、对象名和 API 管理数据的存储服务，不等同于本机目录或云盘分区）。

用下面三条命令查看这条关系：

* `lsblk -f`：查看块设备、文件系统类型和挂载点。
* `findmnt /`：查看根目录来自哪个设备、使用什么文件系统。
* `df -hT /var/www/html`：查看站点所在文件系统的类型、容量和使用率。

```bash
[ECS] lsblk -f
[ECS] findmnt /
[ECS] df -hT /var/www/html
```

这三条命令能确认站点落在哪个文件系统、哪块云盘上，但不能代替备份。云盘正常工作只说明当前数据还能读。

## 4.2 文件备份、快照和 OSS 的恢复粒度

**文件归档**

* 保护对象：指定目录和文件。
* 常见用途：误删单个页面、配置文件或小型站点目录。
* 本课工具：`tar`（归档打包工具）、`sha256sum`。

**云盘快照**

* 保护对象：一块云盘在某个时间点的数据状态。
* 常见用途：系统变更前保护整块盘，或从快照创建、恢复云盘。
* 注意：创建快照会产生存储费用，使用前核对开课当期计费规则。

**OSS 对象存储**

* 保护对象：上传到 Bucket 中的对象。
* 常见用途：把备份包放到独立于 ECS 云盘的位置，按对象管理和长期保存。
* 注意：OSS 不是默认挂载的本地磁盘，存储、请求和流量都可能涉及费用。

::: tip 关键提醒
备份位置与原数据在同一块云盘时，只能应对部分文件误操作，不能应对整块云盘不可用。恢复目标不同，备份方式也应不同。
:::

## 4.3 一份可靠的备份需要哪些证据

光拿到一个 `.tar.gz` 压缩包，离“备份可用”还有相当长的距离。一套合格的备份至少要经受住 5 个维度的检验：

1. 归档数据源是否准确完整；
2. 压缩包内是否如期包含了目标文件；
3. 跨网络传输后文件内容是否损坏或被篡改；
4. 能否在隔离测试目录中成功解压；
5. 解压恢复后的关键文件内容是否与原文件完全一致。

本课对应的防线与工具：

* `tar -tzf`：只读列出压缩包内的目录与文件树，免解压核验；
* `sha256sum`：计算文件内容的哈希摘要，比对指纹；
* `scp`：基于已建立的加密 SSH 频道安全传输数据；
* `diff`：逐行比对恢复出来的副本与生产源文件。

需要清楚的是：校验和相同，仅代表那一刻两份文件的字节完全一致。它无法证明打包的内容本身有没有漏文件，也无法代替真实的解压恢复演练。

## 4.4 检查站点与备份空间

备份前先确认目标、来源和容量：

* `whoami`、`hostname`、`pwd`：确认账号、主机和当前目录。
* `du -sh /var/www/html`：估算站点目录当前占用。
* `find /var/www/html -maxdepth 2 -type f -print`：查看两层范围内有哪些普通文件。
* `df -hT "$HOME"`：确认备份目标所在文件系统有可用空间。

```bash
[ECS] whoami
[ECS] hostname
[ECS] pwd
[ECS] du -sh /var/www/html
[ECS] find /var/www/html -maxdepth 2 -type f -print
[ECS] df -hT "$HOME"
```

确认 `/var/www/html/index.html` 是第三次课发布的页面。来源目录或目标空间没搞清楚之前，不要创建归档。

下面的真实案例没有读取共享主机的 `/var/www/html`，而是检查了课程专用目录 `/opt/xpk-course-demos/lesson-03-04-capture/site`。`lsblk` 和 `findmnt` 先确认目录落在 `/dev/vda1` 的 ext4 根文件系统上；`df` 再确认捕获时可用空间为 34G；`du` 与 `find` 最后把备份范围收窄到 8.0K 的 `site/index.html`。

## 4.5 创建带时间的站点归档

先建立课程备份目录，再用变量保存本次文件名：

```bash
[ECS] mkdir -p ~/cloud-course/backups ~/cloud-course/lab-04
[ECS] backup_name="nginx-site-$(date +%Y%m%d-%H%M%S).tar.gz"
[ECS] backup_path="$HOME/cloud-course/backups/$backup_name"
[ECS] printf 'backup_name=%s\n' "$backup_name"
```

文件名里嵌入时间戳，是为了区分多次备份。变量只在当前 Shell 会话里有效，重新打开终端后需要按实际文件名重新赋值。

创建归档：

```bash
[ECS] tar -czf "$backup_path" -C /var/www html
```

各参数含义：

* `-c`：创建归档。
* `-z`：使用 gzip 压缩。
* `-f`：后面跟归档文件名。因为 `-f` 必须紧接文件名，它在组合参数中必须放在最后——`-czf` 正确，`-fcz` 会让 `tar` 把 `z` 当成文件名。
* `-C /var/www`：先切换归档基准目录。
* `html`：只把 `/var/www/html` 作为相对路径写入归档。

创建后检查文件大小和归档目录：

```bash
[ECS] ls -lh "$backup_path"
[ECS] tar -tzf "$backup_path" | sed -n '1,30p'
```

归档列表里应该有 `html/` 和 `html/index.html`。如果列表路径跟预期不符，停在这里，不要继续传或恢复。

## 4.6 生成并验证 SHA-256

进入备份目录，以相对文件名生成校验文件：

```bash
[ECS] cd ~/cloud-course/backups
[ECS] sha256sum "$backup_name" | tee "$backup_name.sha256"
[ECS] chmod 600 "$backup_name" "$backup_name.sha256"
[ECS] sha256sum -c "$backup_name.sha256"
```

输出 `OK` 表示当前备份包与校验文件中的摘要一致。

SHA-256 校验文件要和备份包一起保存。如果只截图保存摘要，不仅容易抄错，也无法用于自动验证。

## 4.7 使用 SCP 传输到 WSL

`scp` 通过 SSH 连接传输文件，不需要额外开放 FTP 端口。传输前需记录 ECS 中 `backup_name` 的实际值。

在 WSL 中建立接收目录，并填写自己的登录目标与备份文件名：

```bash
[WSL] mkdir -p ~/cloud-course/lab-04-received
[WSL] cd ~/cloud-course/lab-04-received
[WSL] ECS_TARGET="登录用户名@自己的ECS公网地址"
[WSL] BACKUP_NAME="填写ECS中显示的备份文件名"
```

传输备份包和校验文件：

```bash
[WSL] scp "$ECS_TARGET:cloud-course/backups/$BACKUP_NAME" .
[WSL] scp "$ECS_TARGET:cloud-course/backups/$BACKUP_NAME.sha256" .
[WSL] ls -lh
[WSL] sha256sum -c "$BACKUP_NAME.sha256"
```

WSL 中再次输出 `OK`，说明传输后的备份包与 ECS 生成校验文件时内容一致。

::: warning 安全边界
不要为传文件额外开放 FTP、Samba 或任意高位端口。SCP 复用现有 SSH 访问；私钥和密码仍然不能放入命令记录、Word 或 AI 对话。
:::

案例把课程站点打包为 `nginx-site-20260728-081700.tar.gz`，先在云主机检查目录和 SHA-256，再用 SCP 传到本地控制端。案例中的 `[CTRL]` 是 macOS 控制端，不是学生 WSL；个人实训仍应在自己的 WSL 中完成同一组接收与 `sha256sum -c` 检查。

## 4.8 在隔离目录中验证恢复

恢复测试不覆盖在线站点。先回到 ECS，重新指定实际备份文件名：

```bash
[ECS] cd ~/cloud-course/backups
[ECS] backup_name="填写本次实际备份文件名"
[ECS] backup_path="$PWD/$backup_name"
[ECS] restore_dir="$HOME/cloud-course/lab-04/restore-test"
[ECS] mkdir -p "$restore_dir"
```

解压并检查：

```bash
[ECS] tar -xzf "$backup_path" -C "$restore_dir"
[ECS] find "$restore_dir" -maxdepth 3 -type f -print
[ECS] diff -u /var/www/html/index.html "$restore_dir/html/index.html"
```

`diff` 没有输出，说明两份 `index.html` 内容一致。注意：这只是测试目录中的恢复文件跟当前在线文件一致，不代表其他文件也没问题。

在删除测试文件前，先确认它位于隔离目录：

```bash
[ECS] realpath "$restore_dir/html/index.html"
[ECS] ls -l "$restore_dir/html/index.html"
```

确认路径位于 `~/cloud-course/lab-04/restore-test` 后，删除测试副本：

```bash
[ECS] rm "$restore_dir/html/index.html"
[ECS] test ! -e "$restore_dir/html/index.html" && echo "测试文件已删除"
```

从归档恢复这一个文件，再比较内容：

```bash
[ECS] tar -xzf "$backup_path" -C "$restore_dir" html/index.html
[ECS] test -f "$restore_dir/html/index.html" && echo "测试文件已恢复"
[ECS] diff -u /var/www/html/index.html "$restore_dir/html/index.html"
```

{{guided-demo:lesson-04-backup-restore-loop}}

同一备份随后只在课程专用的 `restore-test` 中解压。第一次 `diff` 证明隔离副本与源文件一致；删除的也是隔离副本；从归档恢复指定成员后再次比对，并检查 `lesson03-nginx-ok` 页面标记。整个过程没有覆盖在线站点。

## 4.9 为两类故障选择恢复方式

**文件误删，但 ECS 和云盘正常**

* 优先使用文件归档恢复指定文件或目录。
* 恢复前确认归档时间、目录结构和校验结果。
* 先恢复到隔离目录，再决定是否覆盖在线文件。

**云盘损坏、实例无法启动或需要整盘回退**

* 同一云盘中的归档可能无法读取。
* 需要快照、独立云盘、OSS 或其他外部备份。
* 回滚云盘会影响回滚点之后的数据，执行前必须确认范围、费用和停机影响。

判断标准就一句话：

```txt
要恢复的是一个文件、一组目录，还是一整块云盘？
```

恢复粒度决定工具选择，不是越“云”就越好。

{{chat-lab:lesson-04-backup-evidence}}

## 4.10 实训：备份并恢复课程学习站

实训包含五项任务：

1. **存储识读**：说明站点文件、文件系统、挂载点和云盘的关系。
2. **归档与校验**：创建带时间的站点备份包，检查目录并生成 SHA-256。
3. **安全传输**：把备份包和校验文件传到 WSL，再次验证。
4. **恢复测试**：只删除隔离目录中的测试首页，从归档恢复并比较。
5. **方案设计**：分别说明文件误删和云盘故障应使用什么恢复方式。

ECS 暂不可用时，可以在 WSL 使用课程提供的合成站点目录完成 `tar`、校验和恢复流程，并标明运行位置。云盘、挂载和公网服务器证据需要在 ECS 可用后补交。

完整步骤、截图清单和验收脚本见[实训 04：备份并恢复课程学习站](./lab-04.md)。最终提交：

```txt
班级_学号_姓名_第04次课_站点备份恢复报告.docx
```

报告需依次包含存储关系、备份前检查、归档列表、ECS 校验、WSL 传输校验、测试文件删除、恢复结果和两级恢复方案。

{{reflection-checkpoint:lesson-04-restore-ready}}

::: tip 关键提醒
整理完成后，将一个最终 .docx 上传到智慧职教在线平台“第04次课”对应的作业收集中。备份包只保存在自己的 ECS 与 WSL，不上传到智慧职教，也不提交服务器地址和凭据。
:::

## 4.11 第四次课小测

小测检查以下判断能力：

* 能否区分文件系统、挂载、云盘、快照和对象存储；
* 能否解释归档列表、SHA-256 和恢复测试的证据边界；
* 能否安全使用 SCP 传输备份；
* 能否根据恢复粒度选择文件归档或云盘级方案。

{{assessment:lesson-04-check}}

## 4.12 小结

本课完成了课程学习站第一次可验证的备份：

* `tar` 把站点目录整理成可传输的归档文件。
* `tar -tzf` 检查归档内容，SHA-256 检查文件在传输前后是否一致。
* SCP 复用 SSH 传输，不需要开放额外文件服务端口。
* 恢复测试在隔离目录中进行，不用在线站点冒险。
* 文件归档、云盘快照和 OSS 保护的对象与恢复粒度不同。

下一次课在现有 Nginx 和备份的基础上，加入 PHP、数据库与 WordPress，搭出课程学习站 v1。

为下一步保留三样交接物：

* 当前 Nginx 首页的文件位置和 HTTP 成功证据；
* 已通过 `tar -tzf`、SHA-256 与隔离恢复测试的站点归档；
* 一条恢复说明：WordPress 部署出现问题时，如何先保护现有静态站点再继续变更。

第 5 次课会把单一静态服务扩展为 Nginx、PHP-FPM 和 MariaDB 三层应用。届时要继续沿用本课的习惯：变更前留基线，故障时先分层，恢复后沿原路径验证。

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