feat: 生产上线准备(部署硬化 + 密钥管理 + 备份 + 部署手册) - #2
Merged
Conversation
- 新增 REGISTRATION_DISABLED(12003) 错误码 - AuthProperties 配置 app.auth.registration-enabled,默认 true 保持现状 - UserService.register 开关关闭时抛 BusinessException(REGISTRATION_DISABLED) - UserServiceTest 增加开关关闭/开启两个用例 Co-Authored-By: Claude Code <[email protected]>
APP_SEED_KB_DIR 已设置但系统无 ADMIN 时仅告警并跳过, 注册首个用户(自动成为 ADMIN)后重启生效。 Co-Authored-By: Claude Code <[email protected]>
- 新增 application-prod.yml:关闭 Swagger、限制 actuator 暴露、滚动日志、信任代理头 - docker-compose.yml:必填变量 :? 校验、内网端口不再对外暴露、日志锚点与重启策略、app 健康检查与持久化卷 - app/Dockerfile 运行时安装 curl 供 healthcheck;frontend/Dockerfile 升级 node:24 并启用 --frozen-lockfile Co-Authored-By: Claude Code <[email protected]>
- nginx 隐藏版本号、增加 X-Content-Type-Options 与 Referrer-Policy 安全头 - X-Forwarded-For 改为透传直连 IP,防止伪造 IP 绕过后端限流 - .dockerignore 补充 .env / .env.* 排除,避免密钥进入构建上下文 Co-Authored-By: Claude Code <[email protected]>
- 新增 docs/production-deployment.md 单机生产部署手册 - .env.example 增补生产部署段与密钥生成提示 - README 增加生产部署章节并指向部署手册 - .gitignore 排除 backups/ 并放行生产部署手册 - bootRun 加载 .env 时空值不覆盖开发占位值,避免必填项留空导致启动失败 Co-Authored-By: Claude Code <[email protected]>
- 新增 scripts/deploy.sh 生产升级脚本(git pull + 重建镜像 + 重启 + 前端健康检查) - 新增 scripts/backup.sh 数据库与配置卷备份脚本,日备保留 14 天、月备长期保留 Co-Authored-By: Claude Code <[email protected]>
- LocalKbSeedRunner 会把 APP_SEED_KB_DIR 挂载目录(./docs)下每个根级 md 导入为公共知识库,compose 又挂载整个 ./docs,手册必须移出 docs/ - 同步更新 README 生产部署章节链接为 ops/production-deployment.md - 移除 .gitignore 中旧路径的 docs/production-deployment.md 例外 Co-Authored-By: Claude Code <[email protected]>
- deploy.sh:仅允许 main 分支执行升级,防止回滚 checkout 被 git pull 拉回 main;预检拦截 .env 中的 change_me/your_dashscope 占位密钥 - backup.sh:新增 minio_data 卷归档(上传的知识库原始文档),纳入 14 天保留策略 - 手册同步:回滚改为直接命令并注明不能重跑 deploy.sh;备份清单与恢复流程补充 minio_data;常见故障补充占位密钥不对称现象;修正种子目录说明与恢复示例占位符 Co-Authored-By: Claude Code <[email protected]>
- build.gradle:bootRun 空值跳过注释改为实际留空的 POSTGRES_PASSWORD(生产段重新定义且留空) - UserService:register javadoc 补充注册开放受 app.auth.registration-enabled 开关控制 Co-Authored-By: Claude Code <[email protected]>
- docker-compose.yml 顶层固定 name: quantmore,避免克隆目录名不同导致命名卷前缀漂移 - backup.sh 按实际卷名归档:quantmore_app_quantmore_data / quantmore_minio_data,注释注明前缀来源 - 手册卷名引用同步为 quantmore_ 前缀实际名称;占位密钥字节数 21 更正为 20;备份脚本表格说明补充 MinIO 数据卷 Co-Authored-By: Claude Code <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
目标
把 QuantMore 从「本地开发」推进到「可上线」:单机云服务器 + Docker Compose 全栈部署、自用/小团队(非公开注册)、暂无域名(先 IP + 80 端口 HTTP 直连)。
改动内容
后端(最小改动,默认行为不变)
APP_REGISTRATION_ENABLED(默认 true):关闭后注册返回业务码 12003(ErrorCode.REGISTRATION_DISABLED),新增AuthProperties配置类与测试LocalKbSeedRunner:无 ADMIN 用户时由抛异常改为告警跳过,防止生产 crash-loop配置与编排生产化
application-prod.yml:关闭 Swagger、forward-headers-strategy: native、日志落盘轮转、actuator 收缩、JWT 默认 30 天docker-compose.yml:凭据:?必填(去掉 "password"/minioadmin 默认值)、基础设施端口全部内网化(唯一对外入口 frontend:80)、固定项目名name: quantmore、app 健康检查 + restart + 日志轮转、/root/.quantmore与日志卷持久化、挂载./docs:/seed-docs:ro种子导入app/Dockerfile装 curl(healthcheck);frontend/Dockerfilenode:24 +--frozen-lockfile(与 CI 对齐);新增frontend/.dockerignorenginx.conf:XFF 改为$remote_addr(防伪造 IP 绕过限流)、安全头、server_tokens off密钥、脚本与文档
.env.example生产段(openssl 生成命令与「加密密钥不可更改」警示,密钥去重)scripts/deploy.sh(升级 + main 分支守卫 + 占位密钥预检)、scripts/backup.sh(PG 自定义格式 + 配置卷 + MinIO 数据卷,14 天保留 + 月备,crontab 示例)ops/production-deployment.md生产部署手册:服务器初始化、密钥生成、首次部署两阶段顺序(先注册首个 ADMIN 再启用种子导入)、升级/回滚、备份恢复演练、常见故障、生产 schema 变更须知(必须新增 V2 迁移)验证
./gradlew :app:test --rerun --no-daemonBUILD SUCCESSFUL(真实 Redis 6379)pnpm run build、docker compose config --quiet、nginx 配置nginx -t容器验证、bash -n脚本语法首次部署顺序(关键)
.env生成全部密钥,APP_SEED_KB_DIR留空、APP_REGISTRATION_ENABLED=true→docker compose up -d --build.env:APP_SEED_KB_DIR=/seed-docs、APP_REGISTRATION_ENABLED=false→ 重启导入知识库种子ss -tlnp只有 80/22后续可选(不在本次范围)
域名 + HTTPS、MinIO 桶私有化 + 预签名 URL、Redis 密码、CI 镜像推送。
🤖 Generated with Claude Code