4.DockerCompose是什么为什么算法服务需要多个容器

Docker Compose 是什么?为什么算法服务需要多个容器?

码海寻道 · AI 算法工程化与系统落地实战第 4 篇

一个算法服务很少只需要一个进程。实际项目通常还需要 PostgreSQL 保存任务和结果,Redis 做缓存和限流,MinIO 保存文件,RabbitMQ 处理异步推理,Nginx 接收外部流量。

如果每个服务都手动安装、手动配置、手动启动,换一台机器就要重复一遍。Docker Compose 用一个 YAML 文件描述多个容器、网络、数据卷、健康检查和环境配置,让开发、测试和单机部署拥有一套可复现的启动方式。

一、为什么算法服务需要多个容器?

算法 API 负责接收请求,但不应该承担所有职责:

text 复制代码
algorithm-api:HTTP 接口、鉴权、参数校验
algorithm-worker:耗时推理和批量任务
postgres:任务、用户、结果和审计
redis:缓存、限流和短期状态
minio:原始文件、结果文件和模型文件
rabbitmq:异步任务投递
nginx:TLS、路由和外部访问入口

拆分的核心原因不是"服务越多越专业",而是不同组件的生命周期和资源需求不同:API 需要快速响应,Worker 需要消耗 CPU/GPU,数据库需要持久化,缓存可以重建,消息队列需要可靠投递。

二、Compose 文件的基本结构

yaml 复制代码
services:
  api:
    build: .
    ports:
      - "8000:8000"

  redis:
    image: redis:7-alpine

services 是核心。每个服务可以指定镜像或构建目录、环境变量、端口、网络、Volume、健康检查和依赖关系。服务之间通过 Compose 网络中的服务名访问,而不是使用宿主机 localhost。

例如,API 容器连接 Redis 时应该使用:

text 复制代码
redis://redis:6379/0

不能写成 redis://localhost:6379/0,因为容器中的 localhost 指向 API 容器自己。

三、一个最小的算法系统

yaml 复制代码
services:
  api:
    build: .
    environment:
      REDIS_URL: redis://redis:6379/0
      DATABASE_URL: postgresql://app:app@postgres:5432/app
    ports:
      - "8000:8000"
    depends_on:
      redis:
        condition: service_healthy
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16
    environment:
      POSTGRES_DB: app
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 10

volumes:
  postgres_data:
  redis_data:

这里有三个容易被忽略的点:

  1. 数据库和 Redis 使用命名 Volume,避免容器删除后数据直接消失;
  2. depends_on 配合 service_healthy,避免 API 在数据库尚未可用时立即启动;
  3. 数据库密码只是演示值,生产环境应通过 Secret 或外部密钥管理注入。

Compose 官方文档支持服务级健康检查、命名 Volume 和 Secrets 配置。Docker Compose services 文档

四、服务启动顺序不等于服务可用

错误理解是:

text 复制代码
postgres 容器先启动
↓
api 容器再启动
↓
数据库一定可以连接

实际情况是,容器进程启动后,数据库可能还在初始化、执行恢复或创建用户。depends_on 只能表达依赖关系,可靠判断应该依赖健康检查;应用自身也要在启动时重试连接,并在数据库不可用时保持未就绪。

五、网络、端口和服务发现

端口有两个概念:

text 复制代码
容器端口:服务在容器内部监听的端口
宿主机端口:外部访问宿主机时使用的端口

只有需要被宿主机或公网访问的服务才需要 ports:

yaml 复制代码
api:
  ports:
    - "8000:8000"

PostgreSQL、Redis 和 RabbitMQ 管理端口通常只供内部服务访问,可以不映射到宿主机,减少暴露面。API 通过服务名访问它们:

text 复制代码
postgres:5432
redis:6379
rabbitmq:5672

六、环境变量和不同环境

不要把开发、测试和生产配置写成三份完全不同的 Compose 文件。可以把稳定结构放在 compose.yaml,再用环境变量覆盖:

yaml 复制代码
services:
  api:
    image: ${ALGO_IMAGE:-algorithm-api:dev}
    environment:
      APP_ENV: ${APP_ENV:-development}
      MODEL_VERSION: ${MODEL_VERSION:-demo}

运行前检查最终配置:

bash 复制代码
docker compose config

这个命令可以帮助发现变量没有注入、Volume 路径错误和 YAML 合并问题。敏感配置不要提交 .env 到 Git,生产环境应使用 Secret 文件、平台密钥或专用密钥管理系统。

七、健康检查应该检查什么?

yaml 复制代码
api:
  healthcheck:
    test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
    interval: 30s
    timeout: 5s
    retries: 3
    start_period: 30s

算法服务最好区分:

text 复制代码
/health:进程是否存活
/ready:模型、数据库和必要依赖是否已经准备好

不要在健康检查中执行一次完整推理,也不要让一个短暂的 Redis 故障导致 API 容器不断重启。健康检查应该轻量、有限时,并且能反映服务是否适合接收流量。

八、常用操作命令

bash 复制代码
# 构建并后台启动
docker compose up -d --build

# 查看服务状态
docker compose ps

# 查看 API 日志
docker compose logs -f api

# 查看某个服务的环境和配置
docker compose config

# 执行一次性命令,例如数据库迁移
docker compose run --rm api python -m app.migrate

# 停止并删除容器,但保留命名 Volume
docker compose down

# 连同 Volume 一起删除,谨慎使用
docker compose down -v

down -v 会删除数据库和缓存数据,开发环境也不要在没有确认目标的情况下执行。

九、Compose 适合什么,不适合什么?

适合:

  • 本地开发和联调;
  • 单机测试环境;
  • 小规模内部服务;
  • 复现一套依赖组件;
  • 给新成员提供一键启动环境。

不应把 Compose 自动等同于高可用生产平台。生产环境还需要考虑多机调度、滚动发布、备份恢复、监控告警、密钥轮换和故障转移。规模扩大后,可以把同样的服务边界迁移到 Kubernetes 或托管容器平台。

结语

Docker Compose 的真正价值,是把"算法 API 依赖哪些组件、如何连接、数据存在哪里、什么时候算健康"写成可以评审和复现的配置。下一篇将用 Compose 启动 FastAPI、PostgreSQL 和 Redis,做出第一个可以落地的算法服务基础环境。

参考资料

  1. Docker Compose 官方文档:How Compose works
  2. Docker Compose 官方文档:Services
  3. Docker Compose 官方文档:Quickstart

本文为"码海寻道"原创技术文章。Compose 示例用于开发和单机联调,生产部署仍需单独设计高可用、备份和安全策略。

相关推荐
FII工业富联科技服务1 小时前
工业智能体技术架构解析:六级部署、核心模块与制造场景实践
人工智能·架构·制造
长不大的杨瑞杰1 小时前
OpenCode v2 配置工程实战:Config 优先级、JSONC、变量替换与多环境治理
人工智能·安全·云计算·软件工程·devops
.Bryce.1 小时前
从零到一开发技术名词大全:从需求分析到 AI Agent 工程
java·网络·人工智能·agent·需求分析·agent评测
高升说1 小时前
手眼方案怎么选:眼在手上与眼在手外的工程对比
人工智能·数码相机
Highcharts.js1 小时前
智能数据分析组件Orbit 正式发布与快速上手体验教程
前端·人工智能·信息可视化·数据分析系统·highcharts·orbit·智能可视化
apple_692658852 小时前
基于 Qwen-Image-2.1 的人物替换 LoRA 模型及部署工作流 人物替换的效果 吊打闭源
人工智能·计算机视觉
甲维斯2 小时前
绝了!Codex找苹果客服解决Claude订阅问题!
人工智能
斗象科技2 小时前
斗象入选上海市“AI+制造“服务商能力图谱·AI安全服务商
人工智能·安全·制造
明志数科2 小时前
工业采集数据的计量口径分层与可复算质检设计
人工智能·机器人