# Docker + Prefect 使用说明 当前方案是: - 使用 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml) 管理 deployment - 使用 Docker 容器运行 Prefect worker - 由 Prefect Server 统一调度 当前只有一条调度: - `12:00` 执行物流未发货数据同步,并写入飞书多维表格 ## 1. 创建 Docker 镜像 在项目目录执行: ```bash cd /Users/idss/YXT_Project/logistics-service docker build -t logistics-service-prefect:0.1.0 . ``` 镜像构建特点: - 基础镜像:`python:3.12-slim-bookworm` - 使用 `uv` 安装依赖 - 使用清华 `apt` 和 `PyPI` 源 - 依赖来源:[pyproject.toml](/Users/idss/YXT_Project/logistics-service/pyproject.toml) ## 2. 启动 Docker 容器 推荐使用 Compose。 项目里的 [docker-compose.yaml](/Users/idss/YXT_Project/logistics-service/docker-compose.yaml) 已经配置了: - `.env` - `PREFECT_API_URL` - `FEISHU_CHAT_ID` - `host.docker.internal` - `uv_cache` 持久化卷 - CPU / 内存资源限制 启动: ```bash cd /Users/idss/YXT_Project/logistics-service docker compose up -d --build ``` 停止: ```bash docker compose down ``` 查看运行状态: ```bash docker ps ``` 当前容器名是: ```bash prefect-logistics-worker ``` ## 3. 容器启动后会做什么 容器启动后: 1. 加载 `.env` 2. 创建 `/app/logs` 3. 启动 `supervisord` 4. 再由 [supervisord.conf](/Users/idss/YXT_Project/logistics-service/supervisord.conf) 启动: ```bash prefect worker start --pool "logistics-service-pool" --type process ``` 也就是说,这个容器的职责不是直接跑 flow,而是作为 Prefect worker 等待调度。 ## 4. 注册 Prefect 调度 调度定义在 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml)。 当前 work pool 是: ```bash logistics-service-pool ``` 注册 deployment 的方式: ### 方式 A:在本机或服务器上直接执行 前提是当前环境里有 `prefect` CLI,并且能访问 `PREFECT_API_URL`: ```bash cd /Users/idss/YXT_Project/logistics-service prefect deploy --all ``` ### 方式 B:在容器里执行 如果宿主机没有 `prefect` 命令,可以直接在容器里执行: ```bash docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all' ``` 注意: - 这条命令要求容器里的 `PREFECT_API_URL` 可访问 - 如果你看到 `ConnectError`,通常是 `.env` 里的 `PREFECT_API_URL` 地址在容器里不可达 ## 5. 自动执行是怎么发生的 完整流程如下: 1. `prefect deploy --all` 把 [prefect.yaml](/Users/idss/YXT_Project/logistics-service/prefect.yaml) 注册到 Prefect Server 2. Prefect Server 根据 cron 在每天 `12:00` 触发: - `logistics-bitable-sync-daily` 3. `prefect-logistics-worker` 容器里的 worker 从 `logistics-service-pool` 拉取任务 4. worker 执行 [prefect_logistics_scheduler.py](/Users/idss/YXT_Project/logistics-service/prefect_logistics_scheduler.py) 里的 flow 5. flow 调用 [import_logistics_to_feishu_bitable.py](/Users/idss/YXT_Project/logistics-service/import_logistics_to_feishu_bitable.py): - 查询 PostgreSQL - 删除多维表旧记录 - 写入新记录 6. 同步完成或失败后,使用 `FEISHU_APP_ID`、`FEISHU_APP_SECRET` 和 `FEISHU_CHAT_ID` 推送结果到飞书群 ## 6. 单次手动执行 手动跑一次同步: ```bash python /Users/idss/YXT_Project/logistics-service/prefect_logistics_scheduler.py --mode sync ``` 如果要在 Docker 里手动执行: ```bash docker run --rm \ --env-file /Users/idss/YXT_Project/logistics-service/.env \ -e PREFECT_API_URL=http://host.docker.internal:4200/api \ --add-host host.docker.internal:host-gateway \ logistics-service-prefect:0.1.0 \ python prefect_logistics_scheduler.py --mode sync ``` ## 7. Docker 中的日志 现在日志分成三层: ### 7.1 容器标准输出日志 查看 worker 容器日志: ```bash docker logs -f prefect-logistics-worker ``` 或者: ```bash cd /Users/idss/YXT_Project/logistics-service docker compose logs -f ``` 这里通常能看到: - worker 启动日志 - Prefect 调度执行日志 - Python 进程报错堆栈 ### 7.2 容器内本地文件日志 worker 的 supervisor 日志会写到: - `/app/logs/prefect_worker.out.log` - `/app/logs/prefect_worker.err.log` 查看方式: ```bash docker exec -it prefect-logistics-worker sh tail -f /app/logs/prefect_worker.out.log ``` ### 7.3 Prefect UI 日志 在 Prefect UI 的 `Logs` 面板里也能看到 flow / task 日志。 如果 UI 没看到新日志,通常说明: - worker 还没重启到最新代码 - 或本次 run 还是旧 deployment / 旧镜像执行的 ## 8. 常见问题 ### 8.1 `prefect: command not found` 说明宿主机没有安装 Prefect CLI。 可改为在容器里执行: ```bash docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all' ``` ### 8.2 `httpx.ConnectError: All connection attempts failed` 说明容器里访问不到 `PREFECT_API_URL`。 常见原因: - `.env` 里的 `PREFECT_API_URL` 写成了 `localhost` - 容器里访问不到宿主机 Prefect API 当前 compose 已经加了: ```yaml extra_hosts: - "host.docker.internal:host-gateway" ``` 所以更推荐把 `.env` 里的 `PREFECT_API_URL` 配成类似: ```bash PREFECT_API_URL=http://host.docker.internal:4200/api ``` ### 8.3 飞书返回 `91403 Forbidden` 说明当前应用对目标多维表没有足够权限。 需要检查: - 应用是否已添加到目标 Base - 是否具备可编辑权限 - 是否允许新增记录 / 删除记录 / 新增字段 ### 8.4 没有收到飞书群通知 需要检查: - `.env` 中是否配置了 `FEISHU_CHAT_ID` - 当前应用是否具备发送消息权限 - 该应用对应机器人是否已加入目标群 ## 9. 最推荐的执行方式 如果你要的是“服务器上长期稳定自动执行”,建议按这个顺序: 1. 构建镜像 2. 准备 `.env` 3. 启动 worker 容器 ```bash cd /Users/idss/YXT_Project/logistics-service docker compose up -d --build ``` 4. 在能连到 `PREFECT_API_URL` 的环境里注册 deployment ```bash docker exec -it prefect-logistics-worker sh -lc 'cd /app && prefect deploy --all' ``` 5. 到 Prefect UI 检查: - deployment 是否已注册 - work pool 是否是 `logistics-service-pool` - schedule 是否是每天 `12:00`