Smail/docs/运行目录迁移说明.md
smail 9c450f1734
Some checks are pending
Security Checks / security (push) Waiting to run
运行时配置清理阶段检查点
2026-10-05 01:31:34 +08:00

64 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 运行目录迁移说明
`SMAIL_ROOT` 始终指向服务根目录,不能指向 `config`、`data` 或编译输出目录。
```text
服务根目录/
├── config/ # 仅五个当前配置文件
│ ├── config.json
│ ├── smtp.json
│ ├── email.json
│ ├── ssl.json
│ └── plugins.json
└── data/ # 必须与配置一起备份,不得上传 Git
├── *.db # SQLite 数据库及其附属文件
├── *.key # 原加密密钥,不可重新生成或替换
├── ssl/ # 证书、私钥、签发账号、受管版本
├── dkim/ # 邮件签名密钥
├── backups-v2/ # 分区配置历史备份
├── transaction/ # 配置事务与故障恢复
├── migration-backups/ # 旧配置迁移备份
├── runtime-migration-backups/ # 本次人工保存的完整迁移前备份,不由工具自动生成
├── config-audit-v2.jsonl
└── legacy-config/ # 待验收后人工清理的废弃配置
```
## 升级旧部署
1. 停止后端及自动重启服务,确认没有其他进程读写数据库;关闭前端开发服务器。
2. 将整个旧 `config` 目录备份到受保护位置,包括数据库的 WAL、SHM 和日志文件。不要使用历史配置备份替换当前配置。
3. 编译配置工具:在 `backend` 中运行 `go build -o ../out/backend/smail-config.exe ./cmd/smail-config`。Linux 去掉 `.exe`。
4. 只读检查:`smail-config --root 服务根目录 --runtime-data`。
5. 确认已停服后执行:`smail-config --root 服务根目录 --runtime-data --apply`。
6. 核对迁移清单及文件哈希,启动新版后端,然后启动前端。Windows 开发入口为 `deploy/start-dev.ps1`,后端仍是 5201,前端仍是 80/443。
7. 验证登录、证书、配置保存、备份及审计。通过后才能清理 `data/legacy-config` 中明确废弃的文件;数据库、密钥和证书不能删除。
工具不会覆盖目标文件。未知项目、符号链接或目标冲突会阻止迁移。操作失败时逆序回滚已移动项目;回滚失败时保留现场和原始备份,禁止启动旧后端或新建数据库。迁移独占锁为 `data/.runtime-migration.lock`;进程崩溃或回滚失败后会保留锁并阻止启动,管理员必须先确认没有运行进程、核对源和目标文件与备份一致,再移除残留锁并重新检查。已移动项目不会重复覆盖。嵌套 SQLite 目录须根据 `database.localRef` 人工核对,未知目录不会被自动处理。
若升级前只有旧格式 `config.json`,先执行运行目录迁移,再执行 `smail-config --root 服务根目录 --apply` 转换为五个分区配置。不要先生成新密钥,也不要用旧格式配置覆盖现有分区配置。迁移工具不自动备份整个数据库目录,也不自动停止服务;停服和完整备份是执行前提。
迁移只移动运行文件,不改写五个配置的字节、代次和摘要。旧 `config/ssl` 相对引用先通过原摘要校验,再在运行态解析到 `data/ssl`;下一次正常保存会写入新引用。历史备份不改写摘要,恢复时沿用同一兼容规则。
## 权限与回退
- Linux:`config`、`data` 由专用服务账号拥有,目录 0700、敏感文件 0600;不要给普通账号开放读取权限。
- Windows:正式服务由安装脚本设置服务账户和受保护 ACL;开发模式仍明确停用管理员恢复通道,不提升普通邮件业务权限。
- 加密密钥必须与数据库及配置一同迁移,不能只复制 JSON。已初始化部署缺少数据库或关键密钥时,新后端拒绝启动,不会默默生成空库。
- 需要回退时先停服,使用迁移前的完整备份与对应旧二进制成套恢复;若迁移后已经收信或修改账号,先备份最新数据并制定数据回迁方案,不能直接覆盖。
- 前端开发证书默认读取 `data/ssl/example.com.crt` 与 `data/ssl/example.com.key`;自定义环境变量指向旧位置时需要同步修改。
## 配置保存与证书路径
- 管理页面保存成功后,系统通过事务写入五个当前配置文件,更新代次与摘要;历史备份中的同名文件不参与日常配置加载。
- 自定义证书填写的是后端服务器上的证书、私钥文件路径。校验成功后会复制到 `data/ssl/managed/upload/version-...`,页面回读受管副本的引用,而不是保留输入的任意外部路径。
- 旧配置中的 `config/ssl` 引用可兼容读取;下一次正常保存写入 `data/ssl`。不要手工批量替换 JSON 中的路径,否则会破坏分区摘要。
- 保存后需要重启的服务以页面返回结果为准。启动新版后端后,应确认当前代次不变、待重启标记清空,并核对邮件监听实际使用的证书。
## 无损验收
`test/runtime_data_check.py` 必须在停服状态下执行,只读核对文件 SHA256、SQLite 完整性及各表内容摘要,不输出账号数据或密钥。迁移前使用 `--layout old`,完整备份也使用 `--layout old`,迁移后使用 `--layout new`,通过 `--baseline` 比较三者。`--output` 必须是尚不存在的文件,测试记录放在 `test-log`。
正常运行后,配置保存、会话活动、审计和新邮件都会产生合法变化,不能继续要求整个运行目录与迁移前完全一致。应保留停服阶段的原始验收记录,并单独记录保存、刷新、重启及协议验收。
本机 Windows 迁移已核对 51 个原始文件及两份 SQLite 数据库;证书保存、刷新和后端重启后仍使用新目录,SMTP、IMAP、POP3 隐式 TLS 监听返回的证书与当前配置一致。Linux 正式部署、真实外部收发信及完整首次初始化流程不属于本次本机迁移验收结果。