## Work Log - 修复 Docker Flower 容器重启异常(2026-05-02) - 背景: - `docker compose ps` 显示 `fquiz-flower` 持续 `Restarting`。 - `docker compose logs flower` 报错:`Error: No such command 'flower'.` - 根因: - `flower` 服务命令使用 `celery ... flower`,但 `api` 镜像依赖中未安装 `flower` 包。 - 同时 `docker compose` 在解析阶段对 `minio-init.command` 中的 `$MINIO_*` 进行了提前插值,导致每次执行出现变量未设置 warning。 - 本次改动(最小闭环): - 文件:`api/requirements.txt` - 新增依赖:`flower==2.0.1`。 - 文件:`api/pyproject.toml` - 新增依赖:`flower>=2.0.0,<3.0.0`,与 requirements 口径一致。 - 文件:`docker-compose.yml` - `minio-init` 启动脚本中的变量引用改为 `$$MINIO_*`,避免 compose 提前展开: - `"$MINIO_ENDPOINT" -> "$$MINIO_ENDPOINT"` - `"$MINIO_ACCESS_KEY" -> "$$MINIO_ACCESS_KEY"` - `"$MINIO_SECRET_KEY" -> "$$MINIO_SECRET_KEY"` - `"$MINIO_BUCKET" -> "$$MINIO_BUCKET"` - 验证: - 执行:`docker compose up -d --build flower` - `docker compose ps flower`:`Up`,不再重启。 - `docker compose logs flower`: - 出现 `Visit me at http://0.0.0.0:5555` - 出现 `Connected to redis://redis:6379/0` - 执行:`docker compose logs --since=10m ... | rg "ERROR|Traceback|Exception|No such command|CRITICAL|FATAL|UndefinedColumn|relation \"|failed|denied|permission"` - 结果:近 10 分钟内无命中。 - 风险与影响: - 影响面:`api` 镜像新增 `flower` 依赖,镜像体积与构建时长略有增加。 - 当前运行中的 `api/celery-worker/celery-beat/scheduler/web` 仍为既有镜像;本次仅重建并替换了 `flower`。 ## Work Log - 固定 workflow WEB 端口为 3000(2026-05-02) - 背景: - 发布后 `fquiz-web` 宿主机端口出现 `13000->3000`,与 Nginx 固定代理 `127.0.0.1:3000` 不一致。 - 根因是 workflow 的 `ensure_web_port_available` 在 3000 冲突时会自动回退到 13000+ 并写回 `.env`。 - 本次改动(最小闭环): - 文件:`.github/workflows/main.yml` - 调整 `ensure_web_port_available`: - 每次部署前强制写入 `WEB_PORT=3000`(存在则覆盖,不存在则追加)。 - 移除自动回退到 `13000+` 逻辑。 - 若 `3000` 被其它容器占用,直接输出错误并终止部署。 - 预期效果: - workflow 部署后,`fquiz-web` 宿主机端口稳定为 `3000`,避免与 Nginx 前端代理端口漂移。 - 风险与影响: - 若服务器上已有其他容器占用 `3000`,本次部署会失败(可预期失败),需先释放端口或手动调整冲突容器。 ## Work Log - 移除 scheduler 服务并统一任务调度为 API 直连 Celery(2026-05-02) - 背景: - 用户明确要求“去掉 scheduler”。 - 当前仓库默认调度本就为 `celery_direct`,`scheduler` 仅作为可选分支与独立容器存在。 - 本次改动(最小闭环): - 后端任务派发收敛为直连 Celery: - `api/app/services/elevation_service.py` - 删除 `dispatch_mode` 分支与 `_enqueue_via_scheduler_api` 转发实现。 - 保留单一路径:`apply_elevation_for_line_job.delay(job_id)`。 - `api/app/api/v1/elevation.py` - 删除 `dispatchMode` 查询参数透传。 - 后端路由与配置清理: - `api/app/api/router.py` - 移除 `scheduler` 路由注册。 - `api/app/core/config.py` - 删除 `scheduler_api_token` / `scheduler_default_queue` / `scheduler_api_base_url` 及其 `resolved_*` 属性。 - 保留 `scheduler_expire_interval_seconds` 作为 Celery Beat 定时任务间隔配置。 - 删除 scheduler 相关源文件: - `api/app/api/v1/scheduler.py` - `api/app/services/scheduler_service.py` - `api/app/schemas/scheduler.py` - `api/app/scheduler_main.py` - 运行与部署配置同步: - `docker-compose.yml` - 删除 `scheduler` 服务。 - 删除 `api` / `celery-worker` / `celery-beat` 的 `SCHEDULER_API_BASE_URL`、`SCHEDULER_API_TOKEN`、`SCHEDULER_DEFAULT_QUEUE`。 - `.env.example` - 删除 `SCHEDULER_API_BASE_URL`、`SCHEDULER_API_TOKEN`、`SCHEDULER_DEFAULT_QUEUE`、`SCHEDULER_PORT`。 - `.github/workflows/main.yml` - 删除生产 compose 模板中的 `scheduler` 服务块。 - 删除部署模板与默认 `.env` 中的 `SCHEDULER_API_*` / `SCHEDULER_PORT`。 - 删除故障诊断日志中的 `fquiz-scheduler`。 - 长期记忆更新: - `MEMORY.md` - 将“调度与监控口径”更新为“API 直连 Celery,不再保留 scheduler 服务”。 - 验证: - 语法检查通过: - `python3 -m py_compile api/app/api/router.py api/app/api/v1/elevation.py api/app/services/elevation_service.py api/app/core/config.py` - 关键残留检查: - `rg -n "scheduler_main|services/scheduler_service|api/v1/scheduler|SCHEDULER_API_BASE_URL|SCHEDULER_API_TOKEN|SCHEDULER_DEFAULT_QUEUE|scheduler_api|fquiz-scheduler|SCHEDULER_PORT|resolved_scheduler_" .` - 仅命中文档历史记录,不再命中运行代码与部署配置。 - 风险与影响: - 影响范围:任务调度入口、部署编排与环境模板。 - 行为变化:不再支持 `dispatchMode=scheduler_api` 与独立 scheduler HTTP 网关调用。 - 保持不变:默认任务链路(API 直连 Celery)与 Flower 监控链路。 ## Work Log - 浏览器标签图标替换为高压电塔(2026-05-02) - 背景: - 需求要求将浏览器标签图标替换为工程内 `高压电塔.png`。 - 本次改动(最小闭环): - 文件:`web/src/app/favicon.ico` - 使用仓库根目录 `高压电塔.png`(200x200)重生成为 ICO,并覆盖现有 `favicon.ico`。 - 页面标题与其他元数据未改动。 - 验证: - `file web/src/app/favicon.ico` - 结果:`MS Windows icon resource - 1 icon, 200x200 withPNG image data`。 - `git diff -- web/src/app/favicon.ico` - 结果:仅该二进制图标文件发生变更。 - 风险与影响: - 影响面仅前端浏览器标签图标资源。 - 可能受浏览器 favicon 缓存影响,首次需强刷后看到新图标。