跳转至

624 Docker Compose 多容器编排

一句话概述:Docker Compose 用一个 YAML 文件定义和管理多个容器,一条命令启动整个应用栈(Web + 数据库 + 缓存),是本地开发和测试环境的标配工具。

核心知识点速查表

知识点说明
最新版本Docker Compose v2.39+(2026年)
规范版本Compose Spec v5.0.0 "Mont Blanc"
命令格式docker compose(空格,不是 docker-compose 横杠)
配置文件compose.yaml(推荐)或 docker-compose.yml
新特性watch(热重载)、Bake(构建工具)、GPU 支持
适用场景本地开发、测试环境、CI/CD、小型部署

一、安装与基本概念

# Docker Desktop 已内置 Compose(无需单独安装)
docker compose version                 # 查看版本

# Linux 服务器单独安装
sudo apt install docker-compose-plugin  # Ubuntu/Debian

1.1 核心概念

白话解释:
- Service(服务)   = 一个容器的定义(如 web、db、redis)
- Network(网络)   = 容器之间的通信通道(同网络内用服务名访问)
- Volume(卷)      = 数据持久化(容器删了数据还在)
- Profile(配置集)  = 按需启动部分服务(如只启动开发工具)

二、基本使用

2.1 最简配置

# compose.yaml
services:
  web:                                 # 服务名(可自定义)
    image: nginx:alpine                # 使用的镜像
    ports:
      - "8080:80"                      # 宿主机8080 → 容器80
    volumes:
      - ./html:/usr/share/nginx/html   # 挂载本地目录到容器
docker compose up                      # 前台启动(Ctrl+C 停止)
docker compose up -d                   # 后台启动(推荐)
docker compose down                    # 停止并删除容器
docker compose ps                      # 查看运行中的服务
docker compose logs -f web             # 查看 web 服务的日志(实时跟踪)

2.2 完整应用栈(Web + 数据库 + 缓存)

# compose.yaml - 典型的全栈应用配置
services:
  # ---- Web 应用 ----
  app:
    build:                             # 从 Dockerfile 构建
      context: .                       # 构建上下文(Dockerfile 所在目录)
      dockerfile: Dockerfile           # Dockerfile 文件名
    ports:
      - "3000:3000"                    # 映射端口
    environment:                       # 环境变量
      - DATABASE_URL=postgresql://user:pass@db:5432/mydb  # db 是服务名(自动解析为容器 IP)
      - REDIS_URL=redis://redis:6379
    depends_on:                        # 依赖关系(先启动 db 和 redis)
      db:
        condition: service_healthy     # 等 db 健康检查通过才启动 app
      redis:
        condition: service_started     # redis 启动就行
    volumes:
      - ./src:/app/src                 # 挂载源码(开发时热更新)
    restart: unless-stopped            # 异常退出时自动重启

  # ---- 数据库 ----
  db:
    image: postgres:17-alpine          # PostgreSQL 17
    environment:
      POSTGRES_USER: user              # 数据库用户名
      POSTGRES_PASSWORD: pass          # 数据库密码
      POSTGRES_DB: mydb                # 数据库名
    volumes:
      - postgres_data:/var/lib/postgresql/data  # 数据持久化(命名卷)
    ports:
      - "5432:5432"                    # 映射端口(方便本地工具连接)
    healthcheck:                       # 健康检查
      test: ["CMD-SHELL", "pg_isready -U user"]  # 检查命令
      interval: 5s                     # 每5秒检查一次
      timeout: 3s                      # 超时3秒
      retries: 5                       # 失败5次才算不健康

  # ---- 缓存 ----
  redis:
    image: redis:8-alpine              # Redis 8
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data               # 持久化 Redis 数据

# 命名卷(容器删了数据还在)
volumes:
  postgres_data:                       # PostgreSQL 数据卷
  redis_data:                          # Redis 数据卷

2.3 使用 .env 文件

# .env 文件(compose.yaml 自动读取)
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret123
POSTGRES_DB=production_db
APP_PORT=3000
# compose.yaml 中引用
services:
  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER}          # 引用 .env 变量
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
  app:
    ports:
      - "${APP_PORT}:3000"                     # 端口也可以用变量

三、常用操作命令

# 生命周期管理
docker compose up -d                   # 后台启动所有服务
docker compose up -d app               # 只启动 app 服务(含依赖)
docker compose down                    # 停止并删除容器和网络
docker compose down -v                 # 同上,并删除数据卷(危险!数据丢失)
docker compose stop                    # 停止服务(不删除容器)
docker compose start                   # 启动已停止的服务
docker compose restart app             # 重启指定服务

# 查看状态
docker compose ps                      # 查看服务状态
docker compose ps -a                   # 包括已停止的
docker compose logs -f                 # 查看所有日志
docker compose logs -f app db          # 只看 app 和 db 的日志
docker compose top                     # 查看容器进程

# 执行命令
docker compose exec app bash           # 进入 app 容器的 shell
docker compose exec db psql -U user mydb  # 进入数据库
docker compose run --rm app npm test   # 临时启动容器运行测试

# 构建
docker compose build                   # 构建所有需要构建的镜像
docker compose build --no-cache app    # 不使用缓存重新构建 app
docker compose up -d --build           # 启动并重新构建(常用)

四、高级用法

4.1 多环境配置(Override)

# compose.yaml - 基础配置
services:
  app:
    build: .
    environment:
      - NODE_ENV=production
# compose.override.yaml - 开发覆盖(自动加载)
# 白话:compose.yaml + compose.override.yaml 自动合并
services:
  app:
    environment:
      - NODE_ENV=development           # 覆盖为开发模式
    volumes:
      - ./src:/app/src                 # 开发时挂载源码
    ports:
      - "3000:3000"
      - "9229:9229"                    # 调试端口
# 指定使用生产配置
docker compose -f compose.yaml -f compose.prod.yaml up -d

4.2 Watch 模式(热重载)

# compose.yaml
services:
  app:
    build: .
    develop:
      watch:                           # 文件变化自动同步/重建
        - action: sync                 # 文件同步(不重建镜像)
          path: ./src                  # 监听的本地路径
          target: /app/src             # 同步到容器的路径
        - action: rebuild              # 变化时重新构建镜像
          path: package.json           # 监听 package.json
docker compose watch                   # 启动 watch 模式
# 白话:修改代码后自动同步到容器,不用手动重启

4.3 Profiles(按需启动)

services:
  app:
    build: .
    ports:
      - "3000:3000"

  db:
    image: postgres:17
    profiles: []                       # 无 profile = 始终启动

  # 调试工具(只在需要时启动)
  adminer:
    image: adminer                     # 数据库管理界面
    ports:
      - "8080:8080"
    profiles:
      - debug                         # 属于 debug profile

  mailhog:
    image: mailhog/mailhog             # 邮件测试工具
    ports:
      - "1025:1025"
      - "8025:8025"
    profiles:
      - debug                         # 属于 debug profile
docker compose up -d                   # 只启动 app 和 db
docker compose --profile debug up -d   # 启动所有服务(含调试工具)

4.4 网络配置

services:
  frontend:
    image: nginx
    networks:
      - frontend_net                   # 只在前端网络

  api:
    build: .
    networks:
      - frontend_net                   # 前端和后端都能访问
      - backend_net

  db:
    image: postgres:17
    networks:
      - backend_net                    # 只在后端网络(前端无法直接访问)

networks:
  frontend_net:                        # 前端网络
  backend_net:                         # 后端网络
# 白话:db 只在 backend_net,frontend 无法直接连 db,更安全

4.5 资源限制

services:
  app:
    build: .
    deploy:
      resources:
        limits:
          cpus: '2.0'                  # 最多用2个CPU核心
          memory: 1G                   # 最多用1GB内存
        reservations:
          cpus: '0.5'                  # 预留0.5个CPU
          memory: 256M                 # 预留256MB内存

五、常见报错与解决

问题解决
port is already allocated端口被占用,改映射端口或 lsof -i :端口号 找进程
network xxx not founddocker compose down 清理后重新 up
容器启动顺序不对使用 depends_on + condition: service_healthy
数据卷权限问题在 Dockerfile 中设置 USERchown
修改 compose.yaml 不生效需要 docker compose up -d(自动检测变化并重建)

六、速查表

操作命令
启动docker compose up -d
停止docker compose down
查看状态docker compose ps
查看日志docker compose logs -f 服务名
进入容器docker compose exec 服务名 bash
重新构建docker compose up -d --build
运行命令docker compose run --rm 服务名 命令
扩容docker compose up -d --scale 服务名=3
热重载docker compose watch
清理全部docker compose down -v --rmi all

七、同类工具对比

特性Docker ComposeKubernetesPodman ComposeDocker Swarm
复杂度极高
编排规模单机集群单机集群
学习曲线
生产部署小型大型小型中型
配置格式YAMLYAMLYAMLYAML

选型建议:本地开发/小型部署选 Docker Compose;大规模生产集群选 Kubernetes;无 Docker 环境选 Podman Compose。


参考资料Docker Compose 文档 | Compose Spec | GitHub