perf: 删除 psycopg2-binary 依赖 + 预构建 API 基础镜像 #1422
Reference in New Issue
Block a user
Delete Branch "cleanup/remove-psycopg2-binary"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
变更概述
子任务 2.1 - 删除重复 PostgreSQL 驱动
health.py:import psycopg2→import psycopg(psycopg3 迁移,3处修改)requirements-base.txt: 删除psycopg2-binary==2.9.9postgresql+psycopg://),仅 health.py 遗留 psycopg2子任务 2.2 - 预构建 API 基础镜像
infra/docker/api-base.Dockerfile:预装系统依赖(gcc/libpq-dev/libpq5/ffmpeg)+ 全部 Python 依赖infra/docker/api.Dockerfile:从预构建基础镜像开始,仅叠加业务代码(多阶段→单阶段).gitea/workflows/api-base-image.yml:requirements 或 base Dockerfile 变更时自动重建基础镜像scripts/ci/rebuild-api-base-image.sh:手动重建脚本预期效果
⚠️ 部署注意
合并后需先在构建服务器上手动执行一次基础镜像构建:
或手动触发
API Base Image Buildworkflow。基础镜像推送到 ACR 后,后续 CI 的
PR Build API Image才会正常通过。🚀 预览环境已部署
CI全绿,自动审批通过。
CI全绿,自动审批通过。
代码审查结果 - PR #1422
⚠️ 问题(2个需要修改)
apps/api/app/api/routes/health.py 第52行, 第127行:
psycopg.connect()不支持 SQLAlchemy 连接字符串格式。settings.DATABASE_URL(通常格式为postgresql+psycopg://...)传给psycopg.connect()'。psycopg库仅接受标准的 libpq DSN(如postgresql://...),不支持+driver前缀。这会导致健康检查接口在运行时抛出OperationalError,无法正确连接数据库。.gitea/workflows/api-base-image.yml 第45行:Docker 登录重试逻辑存在缺陷,失败后未退出脚本。
for循环中,如果 3 次登录尝试均失败,循环结束后脚本会继续执行后续的docker build和docker push步骤。由于未登录,Push 阶段必然失败,但在此之前会浪费时间构建镜像。💡 建议(2个可选)
infra/docker/api-base.Dockerfile 第33行:优化 Docker 层缓存策略。
requirements-base.txt和requirements.txt放在同一个COPY和RUN指令中。当requirements-base.txt变更时,requirements.txt的安装层缓存也会失效,导致所有依赖重新安装。COPY和RUN,以最大化利用缓存,仅在对应文件变更时重新安装。infra/docker/api-base.Dockerfile 第37行:谨慎使用
strip命令处理动态库。.so文件执行strip --strip-all可能会移除某些 C 扩展(如 psycopg)运行时所需的符号,导致不可预知的错误或崩溃。psycopg等关键库的兼容性,或考虑仅对特定目录执行瘦身,避免破坏依赖库。✅ 格式检查通过 | ❌ 逻辑审查需修改 | ⚠️ 建议关注性能
🤖 由 AI 代码审查机器人自动生成 | 2026-08-18 09:49:53 | 模型:
✅ CI 已修复,请 review。
修复内容:
CI 结果: Code Quality ✅ | mypy ✅ | alembic ✅ | Unit Tests ✅ | Integration Tests ✅ | PR Build API Image ✅ | PR Build Worker Image ✅ | CI Gate ✅
🗑️ 预览环境已清理
PR #1422 已关闭或合并,对应的预览环境已被清理。