Files
cjw b03431b511 📝 docs(deploy): 明确裸 up 不重建已有镜像 + 修正 build.sh 三步描述
- DEPLOYMENT §1.2 / LINUX_SETUP §11 / README / OPERATIONS 补充:
  docker compose up -d 对本地已有同名镜像不会自动重建,更新代码后
  需 up -d --build 或先 build(部署机实测复用旧镜像后澄清)
- build.sh 描述由四步修正为 base → backend → frontend 三步(celery
  复用 backend 镜像,随 Dockerfile.celery 移除的文档收尾)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-24 17:05:01 +08:00

117 lines
8.1 KiB
Markdown
Raw Permalink 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.
# 配置与运行(OPERATIONS)
> 文档定位:**配置 / 启动 / 环境 / 运维硬性要求的唯一归属**。
> 部署入口与部署文档分工见 [DEPLOYMENT.md](DEPLOYMENT.md),Linux 详细步骤见 [deployment/LINUX_SETUP.md](deployment/LINUX_SETUP.md);当前状态见 [STATUS.md](STATUS.md),架构见 [ARCHITECTURE.md](ARCHITECTURE.md)。
---
## 1. 配置来源与优先级
- 配置统一走**环境变量**,代码侧由 [src/shared/config/settings.py](../src/shared/config/settings.py) 的 `Settings` 单例经 `dotenv` + `os.getenv` 读取。
- **本地运行**:仓库根 `.env`(`load_dotenv()` 自动加载;不在仓库内,参照 [.env.example](../.env.example) 复制编辑)。
- **Compose 运行**:compose 文件用 `${VAR}` 从同目录 `.env` 注入容器环境变量;按模式对应不同文件名(见 [DEPLOYMENT.md §1.1](DEPLOYMENT.md))。
- **键值约定**:
- `DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD`:**惰性校验、无代码默认**——缺失时 import 不报错(便于测试/静态分析),真正连库时才失败。生产必须显式配置。
- `AUTO_MIGRATE`:应用启动时是否自动执行 alembic 迁移,默认 `true`(单机开发语义);**多副本 / 容器编排部署应设 `false`**,改由部署流程单点执行 `alembic upgrade head` 或 `python -m shared.database.init_db`(迁移脚本已随镜像分发于 `/app/migrations/`)。
- `SECRET_KEY`:JWT 签名密钥,**无默认**;生产必须 ≥32 字符强随机。
- `ADMIN_PASSWORD`:初始管理员密码,**无默认**;首次建库前必须设置。
- `RUSTFS_*`:对象存储(兼容 `MINIO_*` 别名写法);本地开发缺省值仅为占位,连不上会在用到存储的链路报错。
- `REDIS_*`:默认 `localhost:6379` 无密码(本地开发语义),生产必须显式覆盖;连接串唯一拼装点为 `Settings.redis_url`(Celery broker/backend 复用)。
- `MAX_FILE_SIZE`:上传文件大小上限(字节),默认 `104857600`(100MB);此前为死配置(处理器硬编码 50MB),2026-09-17 起真实生效,收紧上限需同步调整该值。
- `CORS_ORIGINS`:逗号分隔白名单;不设默认放行 `*`,**生产必须显式设置**。
- `LOG_FORMAT`:`json`(生产默认,结构化)/ `text`(开发人可读);`LOG_LEVEL`:DEBUG/INFO/WARNING/ERROR。
- `DEBUG`:`true` 时额外注册 `/api/debug/*` 调试路由(仍需登录),**生产必须为 false**。
- 新增配置项的规则:只加 `settings.py` + `.env.example`,关键依赖项不给 localhost/弱口令兜底(见 [AGENTS.md](../AGENTS.md) §2)。
## 2. 安装与环境
- 后端依赖:`pip install -r requirements.txt`。
- **OCC 几何能力**:PythonOCC 不走 pip 主路径,通过 conda 环境提供(本项目实践环境名 `gemold` 或 `moldinsight`)。无 OCC 环境时项目可启动,但几何分析契约测试自动 skip。
- 前端:`cd frontend && npm install`。
- 数据库迁移:`migrations/`(`alembic.ini` 在仓库根;2026-09-16 由 `alembic/` 改名——原目录名与 alembic 包重名,应用内 import 会被遮蔽导致启动期迁移静默失败);数据修复类一次性脚本在 `scripts/migrations/` 与 `scripts/db/`,**不是运行时代码**,勿在服务内引用。
### 2.1 pip 锁文件生成(D13 流程)
`deploy/requirements-{base,moldinsight}.lock.txt` 是项目依赖的**版本锁**,由 conda 环境首次构建成功后一次性落盘:
- **生成时机**:在 `moldinsight` / `gemold` conda 环境(仅含项目依赖 + conda 基础库,**不能**在混装全开发栈的本机 pip 环境跑)执行 `pip freeze`
- **生成命令**:
- Linux / macOS:`bash deploy/generate_lockfiles.sh`
- Windows:`deploy\generate_lockfiles.bat`
- **产物**:
- `deploy/requirements-base.lock.txt`
- `deploy/requirements-moldinsight.lock.txt`
- **消费方**:CI、离线构建、生产复现部署;`pip install -r deploy/requirements-base.lock.txt` 可直接锁定安装而不依赖 `>=` 解析
- **提交策略**:两个 lock.txt 提交到仓库;版本下限(`requirements-{base,moldinsight}.txt`)按团队策略同步或保留 `>=` 灵活解析
## 3. 本地启动
后端三入口(均含 sys.path 修正,可从仓库根直接跑):
```bash
# unified(moldinsight + inventory,推荐):8000
uvicorn src.entrypoints.unified:app --reload --host 0.0.0.0 --port 8000
# moldinsight-only:8000
uvicorn src.entrypoints.moldinsight:app --reload --host 0.0.0.0 --port 8000
# inventory-only:8001
uvicorn src.entrypoints.inventory:app --reload --host 0.0.0.0 --port 8001
```
Celery worker(moldinsight 异步分析链路;本地从 `src` 目录跑,与 compose 中 `moldinsight-celery` 的 `command:` 覆盖同参——worker 与后端共用 `gemold-backend` 镜像,无独立 Dockerfile):
```bash
cd src && celery -A celery_app worker --concurrency=2 --loglevel=info
```
- `--concurrency=N` 即 OCC 并行分析数:每个 prefork 子进程持一个常驻 OCC 工作进程(方案 B,见 [topics/performance/OCC_THROUGHPUT.md](topics/performance/OCC_THROUGHPUT.md))——每个 OCC 工作进程是独立的 Python + OCC 运行时,**N 增大时按「worker 子进程 + OCC 子进程」双份预算内存**,并预留 PG 连接数(按 celery 角色池随子进程倍增)。
- `--max-tasks-per-child=M`(如 50):worker 子进程定期重启,连带回收其 OCC 子进程(进程级兜底,方案 A)。
前端:
```bash
cd frontend
npm run dev # Vite 开发服务器
npm run gen:api # 从根目录 openapi.json 重新生成 src/types/api.ts(见 API_CONTRACT §4)
```
探活:unified/moldinsight `GET /health` 与 `GET /api/health`;inventory `GET /health`。
## 4. Docker Compose
按"模式 ↔ 文件名"一一对应:
```bash
# unified(默认;frontend + backend + moldinsight-celery)
docker compose up -d
# moldinsight-only(moldinsight + moldinsight-celery)
docker compose -f docker-compose.moldinsight.yml up -d
# inventory-only(仅 inventory)
docker compose -f docker-compose.inventory.yml up -d
```
> 旧 `--profile` 写法已失效(服务不再声明 profiles);模式切换唯一入口是 `-f` 文件名。
- 镜像构建:`bash deploy/build.sh`(base → backend → frontend 3 个 tag,celery 复用 backend 镜像);首次部署或更新代码后必须先 build(或 `docker compose up -d --build`)——裸 `up` 对本地已有同名镜像**不会自动重建**。
- PostgreSQL / Redis / RustFS 通常**复用服务器已有服务**,不由项目 compose 自带;容器只注入连接配置。
## 5. 运行时硬性要求
- **生产环境必须显式设置**:`SECRET_KEY`、`ADMIN_PASSWORD`、`DB_*`、`CORS_ORIGINS`、`RUSTFS_*`、`REDIS_PASSWORD`、`DEBUG=false`、`LOG_FORMAT=json`。
- **单数据库**:moldinsight 与 inventory 共享同一 PostgreSQL(刻意设计,不拆库)。
- **后台任务一律走 `task_dispatcher`** 与 Celery,不要在路由里 fire-and-forget。
- **uploads/ 与 html_output/ 为运行时产物目录**,不提交、不作为配置源头。`html_output/` 自 D11 起仅作 `/html` 报告代理的**存量兜底读**(新产物直传 RustFS 报告键 `html/reports/`,worker 不再写本地卷)。
- `scripts/` 下的一次性脚本执行前先确认目标环境(多为不可逆数据迁移)。
## 6. 排障指针
| 症状 | 先看 |
|---|---|
| 起服务连不上数据库 | `.env` 的 `DB_*` 是否与服务器一致(惰性校验:import 成功 ≠ 连接正常) |
| 上传/导出报对象存储错误 | `RUSTFS_*` 四项 + [topics/storage/RUSTFS_STORAGE.md](topics/storage/RUSTFS_STORAGE.md) |
| 分析任务一直 pending | Celery worker 是否在跑;Redis 连通性;`task_dispatcher` 日志 |
| 前端类型与接口对不上 | `openapi.json` 是否重新导出、`npm run gen:api` 是否执行([API_CONTRACT.md](API_CONTRACT.md) §4) |
| 登录 401 | `SECRET_KEY` 是否跨进程一致(JWT 校验依赖同一密钥) |
| 部署端口/反代问题 | [deployment/DEPLOY_PORT.md](deployment/DEPLOY_PORT.md)、[deployment/PORT_CONFIG.md](deployment/PORT_CONFIG.md) |