来源:
notes/topics/environment_backup_restore/README.md工作站环境:云端备份与一键恢复
目标:把整台工作机的环境变成”云上可复原的产物”。任意一台新机器, 装完系统后跑一条命令,就能在 30 分钟内回到当前工作状态。
硬约束:云是唯一中转。禁止机器之间 scp/rsync/直连同步。 即便原有两台机器全部损坏,只要能上网,就能重建。
调研明细见 cloud-options-research.md(含一手来源引用)。
备份机的不可变系统机制与重启连通性实测见
deepin-immutable-and-reboot-verification.md。
实现状态
| 组件 | 状态 |
|---|---|
scripts/collect-manifest.sh |
✅ 已实现,可运行 |
inventory/ |
✅ 已生成(本机实测清单) |
cloud-options-research.md |
✅ 已完成 |
nas-vm-sync.md / backup-machine-setup.md |
✅ 已完成 |
deepin-immutable-and-reboot-verification.md |
✅ 已完成(含真实重启验证) |
bootstrap.sh |
⬜ 未实现(设计中的新机引导脚本) |
restore.sh |
⬜ 未实现(Layer 4 运行时重建) |
backup.sh / verify.sh |
⬜ 未实现(定时备份与自检) |
inventory/manifest.json |
⬜ 未实现(云上对象校验和清单) |
下面章节里提到的 bootstrap.sh、restore.sh、backup.sh、verify.sh
均为设计目标,尚未落地,不要去找这些文件。
1. 盘点结论:真正”不可重建”的只有 ~3 GB
本机 /home 占 33 GB,但其中绝大部分是可重建的运行时,不该上传。
| 类别 | 体积 | 处置 |
|---|---|---|
| nvm / node | 587 MB | 重建 |
Go 工具链 + ~/go |
1.7 GB | 重建 |
~/src(ruby 源码) |
606 MB | 重建 |
node_modules |
383 MB | 重建 |
.venv(绝对路径写死) |
~1.1 GB | 重建 |
.git 对象库 |
~600 MB | 重新 clone |
| 不可重建数据 | ~2.97 GB | 上云 |
不可重建数据的构成(实测):
| 项目 | 体积 | 备注 |
|---|---|---|
bilibili_transcripts/BV1uu5WzvEnn |
1848 MB | 其中 horizon-2025.wav 1.6 GB;文本转写仅 ~600 KB |
codex_personal_assistant/{notes,migration-artifacts,data} |
252 MB | |
~/.codex/{sessions,skills} |
447 MB | |
~/stock_monitor |
178 MB | |
ashare_monitor/{logs,reports,company_analyze} |
208 MB | |
~/.cc-connect-qqbot/codex |
89 MB | |
~/.dsh |
28 MB | 含凭据 |
| 密钥 / 配置 / units / crontab | < 20 MB | 见 Layer 1/2 |
结论:免费额度就能装下。 Cloudflare R2 送 10 GB、Backblaze B2 送 10 GB、 腾讯 COS 送 50 GB×6 个月 —— 全部覆盖 3 GB。
2. 分层模型
每一层用不同的机制,混用会互相打架。
Layer 0 — OS 基线(不备份,只记录版本)
- Deepin 25 官方 ISO(安装介质本身就是”备份”)
apt-mark showmanual/dpkg --get-selections(本机 2351 个包)ll-cli list(linglong 应用:deepin-browser / deepin-mail / dde-calendar)- 第三方 apt 源:
/etc/apt/sources.list.d/{appstore,driver,zerotier}.list
Layer 1 — 声明式配置(小,进私有 Git 仓库)
- dotfiles:
.bashrc.profile.gitconfig.imwheelrc ~/.config/systemd/user/*.{service,timer}+default.target.wantscrontab -l(含 ashare_monitor 的 6 条 sync + 2 条行情同步)~/.config/{ashare_monitor,astro,go,nvm}的非机密部分- 本项目里的
bootstrap.sh/restore.sh
Layer 2 — 密钥凭据(小,必须加密,绝不能明文进 Git)
~/.ssh/id_ed25519、~/.gnupg/~/.cc-connect*/config.toml(含app_secret、api_key)~/.dsh/.credentials.yaml、~/.codex/auth.json~/.lark-cli/、~/.Monocloud.json~/.config/ashare_monitor/cycle_web.env~/.git-credentials(如存在)
处置:打包成 secrets.tar → age 加密 → 提交进私有仓库。
解密的私钥是唯一需要人为保管、不能上云的东西(密码管理器 + 纸质各存一份)。
Layer 3 — 不可重建数据(~3 GB,进 restic → 对象存储)
restic 提供客户端加密、去重、增量、单文件恢复。仓库密码同样属于”不能上云”的范畴。
Layer 4 — 可重建运行时(不备份)
nvm/node、Go、ruby、.venv、node_modules、~/go/pkg、.cache。
全部由 restore.sh 重建。.venv 里写死了 /home/admin/... 绝对路径,
复制过去反而会坏,必须重建。
3. 传输通道选型(本机实测,2026-09-18)
在 10.71.48.85 上的实测:
| 目标 | 冷启动 | 稳定吞吐 | 结论 |
|---|---|---|---|
| GitHub HTTPS | 33 KB/s,建连 5s | 3.5–4.7 MB/s | 冷启动慢、方差大 |
GitHub git clone 大仓库 |
linux 浅克隆 90s 后断流 | 不可靠 | 不适合大对象 |
| Gitee HTTPS | — | 1.4–2.7 MB/s | 稳定,国内首选 |
| npm registry | — | 0.7–2.0 MB/s | 可用 |
| OneDrive | 不可达 | — | 排除 |
| HuggingFace | 不可达 | — | 排除 |
推荐组合:
- Layer 1 + Layer 2 → Gitee 私有仓库为主,GitHub 作镜像(已用
andywu1998/cc-connect等) - Layer 3 → 国内对象存储(阿里 OSS ¥0.12/GB·月 / 腾讯 COS 送 50GB×6月 / 七牛)
- 想先用免费额度:R2 或 B2,但必须先实测本机到该端点的速度再定
- 不要用 GitHub 存大文件:单文件硬上限 100 MiB,仓库建议 <1 GB,免费 LFS 仅 10 GiB
- 不要依赖 Syncthing/Tailscale/ZeroTier 做传输:默认走 P2P,违反硬约束
- 不要用阿里云盘/百度网盘/夸克的第三方桥:rclone 无官方后端,封号风险未量化
4. 新机器恢复流程(目标 <30 分钟)
装 Deepin 25 ISO
└─> curl -fsSL <bootstrap-url> | bash
├─ 安装 git/curl/age/rclone/restic
├─ clone 私有配置仓库(Gitee)
├─ 用 age 私钥解开 secrets.tar → 还原 SSH/GPG/凭据
├─ 安装并加入 ZeroTier
├─ 恢复 apt 清单 + linglong 应用
├─ 安装 nvm/node@v22.23.2、Go 工具链
├─ clone 各业务仓库(cc-connect / ashare_monitor / blog / ...)
├─ 重建 .venv 与 node_modules
├─ 恢复 systemd --user units + crontab + enable timers
├─ 拉起 cc-connect(见第 5 节)
└─ restic restore(从对象存储拉 Layer 3)
└─> 通过 QQ bot 确认就位 → SSH over ZeroTier 接管
5. QQ 机器人 = 新机器的引导通道
要解决的问题: 全新机器装好后没有任何入口 —— 不在身边、没有公网 IP、 SSH 未配置、ZeroTier 未授权。这时你无法登录进去完成剩下的恢复。
解法: QQ bot 走 WebSocket 长连接外呼,不需要任何入站端口, 在 NAT 后面也能连出来。因此:
- 为每台机器配一个独立 QQ bot(或同一 bot 下不同
[[projects]]), 凭据放在加密的 secrets 包里 —— 这里就是”另外一个 QQ 机器人”的用处。 - bootstrap 的最后一步自动启动
cc-connect,work_dir指向工作区。 - bot 一上线就主动推一条消息(“
<hostname>已就位,当前恢复进度 X/Y”)。 - 你从 QQ 发指令,让新机器上的 agent 自己跑完剩余恢复步骤。
- 恢复完成后,再用 ZeroTier 内网 IP 走 SSH 常规操作。
这条通道是唯一不依赖入站网络的引导路径,必须做成幂等、可重入。
6. 一致性保障
- 单向主从:本机(主)→ 云 → 新机(从)。永远不做双向同步,避免互相污染。
- 每日自动备份:systemd timer 跑
backup.sh,失败通过 QQ bot 告警。 - 每周自检:
verify.sh在临时目录做一次 dry-run 恢复,校验清单。 - 清单化:
inventory/manifest.json记录”云上必须存在哪些对象 + 校验和”, 任何一项缺失即告警。这是防止”以为备份了其实没有”的关键。 - 备份仓库不能放进被备份的目录(循环引用)。
7. 已知风险 / 待验证
| 风险 | 说明 |
|---|---|
Deepin 25 /usr 只读(“Solid” 不可变) |
apt 批量恢复可能受限,需在目标机实测;可能只能恢复用户层 |
.venv 绝对路径 |
必须重建,不能复制 |
| 备份密码单点 | restic 密码 + age 私钥必须离线保管,丢了就全丢 |
| Gitee 仓库配额 | 官方帮助页未能抓取,待登录后确认仓库/单文件上限 |
| 腾讯 COS 国内单价 | 文档 JS 渲染未能提取,待控制台确认 |
| 本机到 R2/B2 的实测速度 | 需在选定后实测 |
8. 待决事项
- 对象存储选哪家?(阿里 OSS / 腾讯 COS / 七牛 / 先白嫖 R2·B2)
- 那个新 QQ bot 是给新机器做引导通道,还是替换现在这个?
- 1.6 GB 的
horizon-2025.wav要不要备份?(丢源视频就找不回了,但占一半体积) - 是否接受把密钥加密后上传云?(否则新机器无法全自动恢复)