Docker Compose 多服务编排实战:依赖、健康检查与常见坑

举报
yd_268144123 发表于 2026/11/09 09:52:13 2026/11/09
【摘要】 一、为什么需要 Compose一个应用往往不止一个容器:Web 服务、数据库、缓存、消息队列……如果用 docker run 一个个起,命令又长又难维护,容器间网络、依赖顺序、环境变量都要手动处理。Docker Compose 用一个 compose.yaml 描述整组服务,一条 docker compose up 就能把整套环境拉起,特别适合本地开发、联调、单机部署。 二、一个完整示例以...

一、为什么需要 Compose

一个应用往往不止一个容器:Web 服务、数据库、缓存、消息队列……如果用 docker run 一个个起,命令又长又难维护,容器间网络、依赖顺序、环境变量都要手动处理。

Docker Compose 用一个 compose.yaml 描述整组服务,一条 docker compose up 就能把整套环境拉起,特别适合本地开发、联调、单机部署。

二、一个完整示例

以「Web + MySQL + Redis」为例:

services:
  web:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_started
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 5s
      timeout: 3s
      retries: 10

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

volumes:
  mysql_data:
  redis_data:

要点:

  • 服务之间用服务名互访(mysql、redis 就是主机名),Compose 默认创建一个共享网络。
  • depends_on + healthcheck 保证依赖真正就绪再启动,而不是仅仅容器被创建。
  • 命名卷 volumes 让数据库数据持久化,down 不删数据(down -v 才删)。

三、常用命令

docker compose up -d            # 后台启动全部服务
docker compose ps               # 查看状态
docker compose logs -f web      # 跟踪某服务日志
docker compose exec web sh      # 进入容器
docker compose restart web      # 重启单个服务
docker compose down             # 停止并删除容器/网络(保留卷)
docker compose down -v          # 连数据卷一起删(谨慎)
docker compose build --no-cache # 重新构建镜像

四、环境变量与多环境

不要把密码写死在 yaml 里。用 .env 文件 + 变量插值:

services:
  web:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}
# .env
DB_PASSWORD=change_me

还可以准备 compose.override.yaml(开发用,自动叠加)与 compose.prod.yaml(生产),用 -f 指定:

docker compose -f compose.yaml -f compose.prod.yaml up -d

五、开发体验提升

  1. 热更新:把代码目录挂载进容器,配合框架的 reload:
    volumes:
      - ./src:/app/src
    
  2. 一次性初始化:用 init 服务跑迁移/建表,跑完即退:
    migrate:
      build: .
      command: python manage.py migrate
      depends_on:
        mysql:
          condition: service_healthy
      restart: "no"
    
  3. 合理使用 profiles:把可选服务(如监控)用 profiles: [debug] 标记,默认不启动。

六、常见坑

  1. depends_on 不等于“就绪”:不带 condition/healthcheck 时,只保证启动顺序,数据库可能还没能接受连接,应用就报连接失败。务必配 healthcheck + service_healthy。
  2. volume 覆盖了镜像内文件:把整个目录挂载到 /app 会盖掉镜像里已安装的依赖,导致找不到包。只挂需要改的子目录。
  3. 容器里跑定时任务/守护进程:Compose 适合编排,但别把它当完整编排系统(无跨节点调度、无自动扩缩),生产集群用 K8s。
  4. 构建缓存失效:COPY . . 放在安装依赖之前会导致每次改代码都重装依赖,.dockerignore + 分层顺序要优化。
  5. 端口冲突:宿主机端口重复映射会启动失败,注意 ports 左侧。

七、Compose 与 K8s 怎么分工

  • 本地开发/单机/小规模:Compose 足够,简单直观。
  • 多节点、需要自愈/扩缩/滚动发布:上 Kubernetes。
  • 常见路径:本地用 Compose 开发,把同一镜像推到镜像仓库,生产用 K8s/Helm 部署。

八、总结

Docker Compose 用一份声明式 compose.yaml 把多容器应用“一键拉起”,核心是服务网络互通、依赖健康检查、命名卷持久化、.env 注入配置。它最擅长本地开发与单机编排;把「healthcheck + depends_on 就绪」和「别用 volume 盖住依赖」这两个坑避开,日常联调会顺畅很多。生产级大规模编排则交给 Kubernetes。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。