单元六 域名与上线 · 第 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 v3git 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-checkscp -r "$backup/weekly-report" ai-server:/tmp/restore-checkssh 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文件夹,并确认和服务器上的一致。 - 我知道每月、每周要做哪些维护。