建站记录SWES · 技术记录

Docker 博客的 SQLite 备份:备份文件必须真正恢复一次

记录日期:2026-10-19(多伦多)。基于 eooce-blog 测试站的实际操作。文章中路径和容器名仅适用于本文环境。 为什么不能只看见一个备份文件就放心 SQLite 可能使用 WAL 日志。运行中的数据库可能同时涉及 .db、-wal、-shm 文件,直接复制一个正在变化的 .db 文件,

记录日期:2026-10-19(多伦多)。基于 eooce-blog 测试站的实际操作。文章中路径和容器名仅适用于本文环境。

为什么不能只看见一个备份文件就放心

SQLite 可能使用 WAL 日志。运行中的数据库可能同时涉及 .db、-wal、-shm 文件,直接复制一个正在变化的 .db 文件,不能作为通用的完整备份办法。

本次使用项目已有的 better-sqlite3 在线备份 API 创建一致性备份,再将备份恢复到另一份数据目录进行验证。

已验证的目录与容器

  • 主容器:swes-blog-test

  • 容器数据库:/app/data/blog.db

  • 宿主机数据目录:/opt/swes-blog-test/data

  • 备份目录:/opt/swes-blog-test/backups

Compose 已将宿主机 data 目录挂载到容器的 /app/data。

创建在线备份

mkdir -p /opt/swes-blog-test/backups

docker exec swes-blog-test node --input-type=module -e "import Database from 'better-sqlite3';const d=new Database('/app/data/blog.db');await d.backup('/app/data/verified-backup.db');d.close();console.log('SQLite 在线备份完成');"

cp /opt/swes-blog-test/data/verified-backup.db /opt/swes-blog-test/backups/blog-verified.db

这条命令依赖镜像内已有的 Node.js 与 better-sqlite3,不能直接套用到任意 SQLite 软件。上述固定文件名用于首次测试;日常备份应使用带时间的文件名,避免覆盖上一份可用备份。

恢复到独立容器

本次新建了 restore-data,把备份复制为该目录下的 blog.db。然后使用与主站相同的固定镜像启动恢复验证容器,挂载独立目录,端口仅绑定本机 127.0.0.1:3002,避免与主站冲突。

关键原则是:恢复时不覆盖正在使用的主站目录。

验证命令:

curl -fsS http://127.0.0.1:3002/api/posts/swes-debian12-test

恢复实例返回了与主站相同的测试文章,随后停止恢复容器。主容器重启后,该文章也能继续读取。

结果与局限

这次证明了“一次在线备份可以恢复并读取文章”,没有证明所有历史版本、所有附件或未来升级后的兼容性。

本次没有实现异地备份,也没有自动定时任务。数据库之外,还要保留 Compose 配置、环境配置和以后增加的本地上传目录。含密钥的配置应单独保护,不能上传到公开博客或代码仓库。

项目来源:eooce/eooce-blog。

感谢阅读 · 保持好奇,认真记录。浏览更多文章 ↗