单元六 域名与上线 · 第 25 课

更新、回滚与备份

网站上线只是开始。这一课把发布流程整理成清单,学会出问题时快速回到上一个版本,并备份好那些丢了就很麻烦的文件。

本课目标

  • 按清单发布一个新版本 v3。
  • 学会回滚:一分钟内换回上一个版本。
  • 备份服务器上的部署配置,并确认备份能用。
  • 知道日常要做哪些维护。

发布清单

以后每次更新,都按这个顺序来:

步骤在哪里做什么
1自己电脑让 AI 修改代码,npm start 本地测试
2自己电脑git commit 存档,git tag v3 标记版本
3自己电脑scp 把项目传到服务器
4服务器docker build 构建新版本镜像
5服务器docker push 推送到仓库
6服务器修改 compose.yaml 里的版本号,docker compose up -d
7浏览器打开网站验证;有问题马上回滚

跟着做:发布 v3

1. 做一个小改动

cd ~/ai-course/weekly-report
codex
请在网页上的“生成周报”按钮旁边加一个“清空”按钮,点击后清空文本框和结果。改完告诉我改了哪些文件。

npm start 本地试一下,确认没问题后存档并打上版本标签:

git add -A
git commit -m "清空按钮"
git tag v3

git tag 给这次存档起个版本名,以后看 git log --oneline --decorate 就知道哪个存档对应线上的哪个版本。

2. 构建、推送、部署

scp -r "$HOME\ai-course\weekly-report" ai-server:
scp -r ~/ai-course/weekly-report ai-server:
ssh ai-server

看到服务器的提示符后,再运行:

cd ~/weekly-report
docker build -t 你的用户名/weekly-report:v3 .
docker push 你的用户名/weekly-report:v3
cd ~/apps/weekly-report
vim compose.yaml

把 app 的 image 改成 v3,保存后:

docker compose up -d
docker compose ps

打开 https://report.example.com,能看到“清空”按钮。浏览器如果显示的还是旧页面,按 Ctrl + F5(macOS 按 Command + Shift + R)强制刷新。

回滚:换回上一个版本

假设 v3 上线后发现了严重问题。回滚只需要两步:

cd ~/apps/weekly-report
vim compose.yaml

把 v3 改回 v2,保存,然后:

docker compose up -d

几秒钟后,线上就回到了 v2。v2 的镜像还在服务器上,也在仓库里,所以回滚几乎是瞬间的事。这就是每个版本都打标签、不用 latest 的原因。

演练完记得再改回 v3,运行 docker compose up -d。

备份

要备份什么

内容在哪里丢了会怎样怎么备份
源代码自己电脑的 Git 仓库无法继续开发已经在 Git 里;可以再推到 GitHub(见扩展课)
镜像Docker Hub要重新构建已经在仓库里
部署配置:.env、compose.yaml、Caddyfile、certs/服务器 ~/apps/weekly-report要重新申请证书、重新配置需要手动备份

把部署配置复制到自己电脑

每次备份放进一个以日期和时间命名的新文件夹,不会和之前的备份混在一起。

$backup = "$HOME\ai-course\backups\$(Get-Date -Format yyyy-MM-dd-HHmmss)"
if (Test-Path $backup) { "这个文件夹已经存在,请过一秒再运行" } else { New-Item -ItemType Directory $backup -ErrorAction Stop | Out-Null; scp -r ai-server:apps/weekly-report $backup }
backup=~/ai-course/backups/$(date +%F-%H%M%S)
mkdir -p ~/ai-course/backups && mkdir "$backup" && scp -r ai-server:apps/weekly-report "$backup"

文件夹名精确到秒;如果同名文件夹已经存在,命令会停下而不是往里面复制。完成后,备份在 ai-course/backups/日期-时间/weekly-report 里。$backup 只在当前终端里有效,下面的核对步骤请在同一个终端里继续。

备份里有 Key、访问密码和证书私钥。只存在自己电脑上,不要放进 Git 仓库、网盘或聊天工具。

确认备份能用

没有验证过的备份不算备份。把整份备份传回服务器的临时目录,和正在用的部署配置逐个文件比较:

ssh ai-server "rm -rf /tmp/restore-check"
scp -r "$backup\weekly-report" ai-server:/tmp/restore-check
scp -r "$backup/weekly-report" ai-server:/tmp/restore-check
ssh ai-server 'diff -rq /tmp/restore-check ~/apps/weekly-report; result=$?; rm -rf /tmp/restore-check; if [ $result -eq 0 ]; then echo SAME; else echo DIFFERENT; fi; exit $result'

diff -rq 只报告哪些文件不同,不会把 .env、私钥的内容打在屏幕上。看到 SAME 说明 .env、compose.yaml、Caddyfile 和证书全部一致;看到 DIFFERENT 和一串文件名,说明备份不完整,重新备份一次。无论结果如何,临时副本都会被删掉。

需要恢复时

把备份传回服务器,恢复文件权限,再启动:

scp -r "$backup\weekly-report" ai-server:apps/
scp -r "$backup/weekly-report" ai-server:apps/
ssh ai-server "chmod 600 ~/apps/weekly-report/.env ~/apps/weekly-report/certs/* && cd ~/apps/weekly-report && docker compose up -d"

如果不是在同一个终端里,把 $backup 换成备份文件夹的完整路径。scp 复制过去的文件权限会变宽,所以要重新 chmod 600。

云服务商的控制台一般还提供“快照”功能,可以给整台服务器拍一张照片,需要时整机恢复。快照可能另外收费,按需使用。

日常维护

多久一次做什么命令或位置
每月更新系统软件sudo apt update && sudo apt upgrade -y;如果存在 /var/run/reboot-required 文件,找个空闲时间 sudo reboot
每月更新 Caddy 镜像在 ~/apps/weekly-report 运行 docker compose pull caddy && docker compose up -d
每月清理旧镜像docker image prune 只清理没有标签的悬空镜像;旧版本要按名字单独删除。v1 当初有两个名字,要一起删:docker image rm weekly-report:v1 你的用户名/weekly-report:v1。至少保留当前版本和上一个版本以便回滚
每周看看日志有没有异常docker compose logs --tail 100 app
每周看看 API 用量本站账户后台
到期前云主机、域名续费控制台的到期提醒

常见问题

docker compose up -d 之后网站还是旧版本? 先 docker compose ps 看 IMAGE 一列是不是新版本号。是的话强制刷新浏览器;不是的话检查 compose.yaml 有没有保存。

磁盘快满了? df -h 看看占用情况,docker system df 看 Docker 占了多少。先用 docker image prune 清理悬空镜像,再用 docker image rm 删除确定不再需要的旧版本。

自检

  • 我按清单发布了 v3。
  • 我演练过回滚到 v2,又恢复到 v3。
  • 部署配置已经备份到 backups 文件夹,并确认和服务器上的一致。
  • 我知道每月、每周要做哪些维护。