# 运维与迁移 [返回项目首页](../README.md) ## 持久化、故障和恢复 | 持久卷 | 内容 | | --- | --- | | `content` | 私有 Git 缓存 `authors/<用户名>/content.git`、`collection.json`、`users.json`、公开 `published.json` | | `authorization` | 发布授权与公钥 | | `ingress` | 作者接收仓库 `authors/<用户名>.git` | | `ssh-host-keys` | SSH 服务器身份 | | `database` / `db-logs` | 数据库数据 / 数据库日志 | 应用日志输出 stdout,由 Docker 分卷轮换,不记录口令、会话或私钥。 ## 数据库故障与索引重建 - 数据库索引失败不会修改作者 Git 或阻塞已导入文章的 HTTP 阅读;新集合会触发同步,失败至少间隔 30 秒重试,并定期检查索引是否丢失。 - `blog_articles` 保存全部有效登记文章(含草稿)的作者、本地 ID、正文路径、格式、源提交、封面和系统时间;`blog_pages` 保存有效页面路径,`blog_article_tags` 保存全部文章标签;`blog_posts/blog_tags` 保留公开检索索引。 - 恢复数据库后可自动重建;离线命令为 `chublog-api rebuild-index`(必须停止同一数据卷上的 API 进程后运行,防止并发),或等待在线自动重试。 - `indexed_commit:null` 表示尚无已确认可用的索引,旧值表示尚未追平当前内容。 - 重建上述派生表使用 ChuSQL 事务;数据库不可用时保留阅读快照,恢复后重建。 ## 备份与恢复 - 备份必须同时包含正式 Git、用户文件、授权卷、SSH 主机密钥;备份包含密码哈希,须加密并限制权限。 - 接收 Git 可额外镜像备份。 - 恢复时先停止写入,从同一备份恢复各卷,再启动;不要只恢复 ChuSQL,也不要直接向正式仓库推送。 - 应用启动加载私有集合快照,并继续从各作者 Git 校验导入。 - `collection.json` 还保存生效版本、暂存状态与服务端生成的时间,必须备份。丢失时可从有效作者仓库重新导入正文,但无法还原原始系统时间;若作者当前索引损坏,还需要备份中的上一个生效版本。不要将它当作可随意丢弃的缓存。 - 进程重启会注销所有会话。 本实现对文件写入执行原子替换与 fsync,Git 引用采用受控更新;磁盘故障、主机断电和备份恢复仍需真实环境演练。不要对含正式数据的项目执行 `docker compose down -v`。 ## 从旧共享仓库迁移 这是不兼容的存储与 URL 变更,不能直接把旧共享 Git 历史提供给新的个人仓库。先停机并加密备份全部卷,再完成以下操作: 1. 从旧共享仓库导出各作者最新的文章文件(含草稿),按原发布前缀及管理员确认的所有权分给作者;不要复制 `.git` 或旧提交历史。 2. 管理员离线将 `/auth/publishers.json` 的 `repository` 改为 `/srv/ingress/authors`(或自定义 `INGRESS_DIR`),保留用户和公钥授权。新版本 init 服务会创建该根目录。 3. 将旧 API 数据卷根目录的 `content.git` 移入只对管理员可见的备份位置;旧 `published.json` 同样备份。旧 SSH 共享仓库不再供服务使用,应移出接收卷离线保管。不要删除备份或清空用户数据。 4. 启动新服务。每位作者重新 clone 自己的空仓库,复制自己的导出文件,将原 Frontmatter 中的标题、简介和标签迁入 `index.toml`,将原发布状态映射到 `public`;为每篇文章指定 ID、目录和入口,移除正文 Frontmatter,整理成一个首次提交并推送。作者和时间由服务端重新记录。 5. 核对草稿隔离、所有文章、数据库索引和新的 `作者名~ID` URL 后再恢复对外服务。旧版本已被其他人克隆的内容无法收回。 - 已有授权配置仍指向旧仓库时,新版本拒绝启动;不会自动重新分发旧历史。 - 原链接到新 ID 的重定向尚未实现,迁移时需另行安排。 - 若自定义 `INGRESS_DIR`,需同步调整镜像内 `deploy/gitconfig` 的受信目录范围;默认仅信任 `/srv/ingress/authors/*`,不使用全局 `safe.directory=*`。 ## 从个人仓库的文本索引迁移 停写并备份作者仓库和 `collection.json`,然后把 `index.txt` 改为根目录 `index.toml`。保留原文章 ID 和目录,从正文 Frontmatter 迁移允许的元信息,正文入口不叫 `main.md` 时显式填写 `entry`。删除旧 `index.txt` 和正文 Frontmatter 后,作为一个提交推送。沿用原私有集合快照可保留已有系统时间;旧正文中的日期不会被新版本采纳。 不要提交两种索引并存的仓库。仅根目录的 `index.toml` 在白名单内,其他 TOML 配置仍被拒绝。派生的 `blog_articles` 表若缺少新列,会由索引重建程序重建;该表不得混存评论、授权、审核或站长管理数据。