Procházet zdrojové kódy

docs: 明确 Docker SQLite 持久化方案

wangkangyjy před 1 dnem
rodič
revize
2fb5115f2f

+ 54 - 0
docs/superpowers/plans/2026-07-15-docker-sqlite-persistence.md

@@ -0,0 +1,54 @@
+# Docker 与 SQLite 持久化实现计划
+
+> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。
+
+**目标:** 构建可升级的 Docker 服务,并保证 SQLite 始终由宿主机 `./data` 持久保存。
+
+**架构:** 多阶段 Dockerfile 生成包含前端静态资源的 Spring Boot JAR;Compose 通过 bind mount 将 `./data` 映射到 `/app/data`。启动脚本只准备目录,由应用现有初始化器区分首次建库和增量升级。
+
+**技术栈:** Docker、Docker Compose、Node 20、Maven 3.9、Eclipse Temurin 17、Spring Boot、SQLite。
+
+---
+
+### 任务 1:建立 Docker 配置契约
+
+**文件:**
+- 创建:`scripts/test-docker-config.sh`
+
+- [ ] 编写断言:Dockerfile 多阶段构建、Compose 使用 `./data:/app/data`、数据源及备份目录指向 `/app/data`、`.dockerignore` 排除运行数据。
+- [ ] 运行 `bash scripts/test-docker-config.sh`,确认因文件缺失而失败。
+- [ ] 保留该脚本作为后续 Docker 配置回归测试。
+
+### 任务 2:实现镜像与启动边界
+
+**文件:**
+- 创建:`Dockerfile`
+- 创建:`docker/entrypoint.sh`
+- 创建:`.dockerignore`
+
+- [ ] 使用 Node 阶段执行 `npm ci && npm run build`。
+- [ ] 使用 Maven 阶段复制前端产物并执行 `mvn package -DskipTests`。
+- [ ] 使用 JRE 阶段安装 `gosu`,启动时创建并检查 `/app/data`,再以非 root 用户运行 JAR。
+- [ ] 运行配置契约测试,确认通过。
+
+### 任务 3:提供 Compose 部署配置
+
+**文件:**
+- 创建:`compose.yaml`
+- 创建:`.env.example`
+- 创建:`docs/docker-deployment.md`
+
+- [ ] 将宿主机 `./data` 绑定到 `/app/data`,显式配置 SQLite URL 和备份目录。
+- [ ] 提供 JWT、管理员密码和 CORS 必填环境变量示例。
+- [ ] 记录首次部署、升级、备份和恢复命令,明确禁止删除 `./data`。
+- [ ] 运行 `docker compose config` 验证配置可解析。
+
+### 任务 4:真实验证初始化和升级持久性
+
+**文件:**
+- 创建:`scripts/test-docker-persistence.sh`
+
+- [ ] 在临时宿主机目录启动容器,确认自动生成 SQLite 文件。
+- [ ] 向数据库写入哨兵数据,重建同一镜像的容器。
+- [ ] 确认数据库文件和哨兵数据仍存在,随后清理测试容器和临时目录。
+- [ ] 运行前后端全量测试与 `git diff --check`。

+ 21 - 0
docs/superpowers/specs/2026-07-15-docker-sqlite-persistence-design.md

@@ -0,0 +1,21 @@
+# Docker 与 SQLite 持久化设计
+
+## 目标
+
+将 OKR 服务构建为单个 Docker 镜像,同时将 SQLite 数据库和备份永久保存在宿主机 `./data` 目录。升级时只重新构建镜像并重建容器,不复制、覆盖或删除宿主机数据库。
+
+## 运行结构
+
+- 镜像使用多阶段构建:Node 构建 Vue,Maven 将静态资源打入 Spring Boot JAR,JRE 运行 JAR。
+- Compose 将宿主机 `./data` 绑定到容器 `/app/data`。
+- 数据源固定为 `jdbc:sqlite:/app/data/okr-performance.db`,备份目录固定为 `/app/data/backups`。
+- 启动脚本创建并验证 `/app/data` 可写。数据库文件不存在时不创建空文件,由现有 `DatabaseInitializer` 创建 schema、`DatabaseMigrationRunner` 执行迁移、`DataInitializer` 初始化基础数据。
+- 数据库存在时,启动逻辑直接复用原文件,只执行尚未执行的增量迁移。
+
+## 升级边界
+
+`docker compose build` 与 `docker compose up -d --force-recreate` 只替换镜像和容器。Compose 不声明匿名卷,不执行数据库复制,`.dockerignore` 排除 `data/`,因此数据库不会进入镜像层,也不会被镜像升级覆盖。
+
+## 验证
+
+自动检查 Docker 配置契约,并执行真实容器验收:首次启动生成数据库、写入哨兵数据、重建容器、确认同一数据库和哨兵数据仍存在。