docker-compose

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Docker Compose — 多容器编排与 Compose 文件

Docker Compose — 多容器编排与 Compose 文件

Expert guidance for writing production-grade Docker Compose configurations.
编写生产级 Docker Compose 配置的专业指南。

When to Use

适用场景

ALWAYS use this skill when the user mentions:
  • "docker compose", "docker-compose.yml", "compose 文件"
  • "compose 怎么写", "compose 配置"
  • "多容器", "multi-container", "服务编排"
  • "depends_on", "profiles", "override"
  • "compose network", "compose volume"
当用户提及以下内容时,请务必使用本技能:
  • "docker compose"、"docker-compose.yml"、"compose 文件"
  • "compose 怎么写"、"compose 配置"
  • "多容器"、"multi-container"、"服务编排"
  • "depends_on"、"profiles"、"override"
  • "compose 网络"、"compose 卷"

Complete File Structure

完整文件结构

yaml
undefined
yaml
undefined

compose.yml

compose.yml

name: myapp
services: # Container definitions networks: # Network topology volumes: # Persistent storage secrets: # Sensitive data (Swarm) configs: # Non-sensitive configs (Swarm)
undefined
name: myapp
services: # 容器定义 networks: # 网络拓扑 volumes: # 持久化存储 secrets: # 敏感数据(Swarm 模式) configs: # 非敏感配置(Swarm 模式)
undefined

Services — Core Configuration

服务——核心配置

yaml
services:
  web:
    image: myapp:${TAG:-latest}     # Pull from registry
    # build: .                      # Or build from Dockerfile
    # build:                        # Build with options
    #   context: .
    #   dockerfile: Dockerfile.prod

    container_name: myapp-web       # Explicit name (optional)
    hostname: web

    ports:
      - "8080:8080"                 # host:container
      - "127.0.0.1:8443:443"       # bind to localhost
      - "8080:8080/udp"            # UDP

    environment:
      - NODE_ENV=production
      - DB_HOST=db                  # Service name = hostname!
    # env_file: .env.production    # Load from file

    volumes:
      - app-logs:/var/log/app       # Named volume
      - ./config:/etc/app:ro        # Bind mount (read-only)
      - /tmp/app:/tmp               # Bind mount (read-write)

    depends_on:
      db:
        condition: service_healthy  # Wait for health check
      redis:
        condition: service_started

    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 10s

    restart: unless-stopped

    deploy:                         # Swarm-only
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

    profiles:                       # Optional service
      - debug
yaml
services:
  web:
    image: myapp:${TAG:-latest}     # 从镜像仓库拉取
    # build: .                      # 或从 Dockerfile 构建
    # build:                        # 带参数构建
    #   context: .
    #   dockerfile: Dockerfile.prod

    container_name: myapp-web       # 显式容器名称(可选)
    hostname: web

    ports:
      - "8080:8080"                 # 主机端口:容器端口
      - "127.0.0.1:8443:443"       # 绑定到本地主机
      - "8080:8080/udp"            # UDP 协议

    environment:
      - NODE_ENV=production
      - DB_HOST=db                  # 服务名称=主机名!
    # env_file: .env.production    # 从文件加载环境变量

    volumes:
      - app-logs:/var/log/app       # 命名卷
      - ./config:/etc/app:ro        # 绑定挂载(只读)
      - /tmp/app:/tmp               # 绑定挂载(读写)

    depends_on:
      db:
        condition: service_healthy  # 等待健康检查通过
      redis:
        condition: service_started

    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 10s

    restart: unless-stopped

    deploy:                         # 仅 Swarm 模式生效
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

    profiles:                       # 可选服务
      - debug

Networking

网络配置

Default Network (Auto-Created)

默认网络(自动创建)

yaml
undefined
yaml
undefined

Compose auto-creates a default bridge network.

Compose 会自动创建默认桥接网络。

All services can reach each other by service name.

所有服务可通过服务名称互相访问。

services: web: ports: ["8080:8080"] db: # No ports exposed externally — only accessible by 'web'
undefined
services: web: ports: ["8080:8080"] db: # 不暴露外部端口 — 仅可被 'web' 访问
undefined

Custom Networks

自定义网络

yaml
networks:
  frontend:                        # Public-facing
  backend:
    internal: true                 # No external access

services:
  web:
    networks: [frontend, backend]  # In both networks
  db:
    networks: [backend]            # Backend only (isolated)
  cache:
    networks: [backend]
yaml
networks:
  frontend:                        # 面向公网
  backend:
    internal: true                 # 禁止外部访问

services:
  web:
    networks: [frontend, backend]  # 同时加入两个网络
  db:
    networks: [backend]            # 仅加入后端网络(隔离)
  cache:
    networks: [backend]

Environment Variables

环境变量

Approaches

实现方式

MethodWhereBest For
environment:
In compose.ymlSimple, few vars
env_file:
External
.env.prod
Many vars, env-specific
.env
file
Project root (auto-loaded)Default values,
$VARIABLE
substitution
方式位置适用场景
environment:
在 compose.yml 中简单场景、少量变量
env_file:
外部
.env.prod
文件
大量变量、环境专属
.env
文件
项目根目录(自动加载)默认值、
$VARIABLE
变量替换

.env File (Auto-Loaded)

.env 文件(自动加载)

bash
undefined
bash
undefined

.env — auto-loaded by docker compose

.env — 被 docker compose 自动加载

TAG=v1.2.3 DB_PASSWORD=secret123

```yaml
TAG=v1.2.3 DB_PASSWORD=secret123

```yaml

compose.yml — uses ${TAG} and ${DB_PASSWORD}

compose.yml — 使用 ${TAG} 和 ${DB_PASSWORD}

services: web: image: myapp:${TAG:-latest} db: environment: POSTGRES_PASSWORD: ${DB_PASSWORD}
undefined
services: web: image: myapp:${TAG:-latest} db: environment: POSTGRES_PASSWORD: ${DB_PASSWORD}
undefined

env_file

env_file

bash
undefined
bash
undefined

.env.production

.env.production

DB_HOST=prod-db.example.com DB_PORT=5432

```yaml
services:
  web:
    env_file: .env.production
DB_HOST=prod-db.example.com DB_PORT=5432

```yaml
services:
  web:
    env_file: .env.production

Depends On — Service Order

服务依赖——启动顺序

yaml
services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  web:
    depends_on:
      db:
        condition: service_healthy   # Wait for DB to be ready
      redis:
        condition: service_started   # Wait for Redis to start
yaml
services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  web:
    depends_on:
      db:
        condition: service_healthy   # 等待数据库就绪
      redis:
        condition: service_started   # 等待 Redis 启动

Profiles — Optional Services

Profiles——可选服务

yaml
services:
  app:
    image: myapp

  debug-tools:
    image: nicolaka/netshoot
    command: sleep infinity
    profiles: [debug]                # Only starts with --profile

  elasticsearch:
    image: elasticsearch:8.15.0
    profiles: [analytics]            # Only starts with --profile
bash
docker compose --profile debug up    # Starts app + debug-tools
docker compose --profile analytics up # Starts app + elasticsearch
yaml
services:
  app:
    image: myapp

  debug-tools:
    image: nicolaka/netshoot
    command: sleep infinity
    profiles: [debug]                # 仅通过 --profile 参数启动

  elasticsearch:
    image: elasticsearch:8.15.0
    profiles: [analytics]            # 仅通过 --profile 参数启动
bash
docker compose --profile debug up    # 启动 app + debug-tools
docker compose --profile analytics up # 启动 app + elasticsearch

Multi-Environment with Override

多环境覆盖配置

compose.yml                # Base configuration
compose.override.yml       # Local dev overrides (auto-applied)
compose.prod.yml           # Production overrides
bash
undefined
compose.yml                # 基础配置
compose.override.yml       # 本地开发覆盖配置(自动应用)
compose.prod.yml           # 生产环境覆盖配置
bash
undefined

Local: compose.yml + compose.override.yml (auto)

本地环境:compose.yml + compose.override.yml(自动合并)

docker compose up -d
docker compose up -d

Production: explicit files

生产环境:指定配置文件

docker compose -f compose.yml -f compose.prod.yml up -d
undefined
docker compose -f compose.yml -f compose.prod.yml up -d
undefined

Migration to Kubernetes

迁移至 Kubernetes

bash
kompose convert -f compose.yml   # Generates K8s YAML files
kubectl apply -f .
bash
kompose convert -f compose.yml   # 生成 K8s YAML 文件
kubectl apply -f .

Workflow — 推荐编排流程

Workflow — 推荐编排流程

Step 1: 规划服务: 列出所有服务、端口、数据卷、环境变量 Step 2: 编写 compose.yml: 定义 services/networks/volumes Step 3: 配置依赖: depends_on + condition: service_healthy Step 4: 本地验证:
docker compose up -d
docker compose ps
docker compose logs
Step 5: 生产部署: 添加 resource limits、restart policy、日志轮转 →
docker compose -f compose.yml -f compose.prod.yml up -d
Step 1: 规划服务: 列出所有服务、端口、数据卷、环境变量 Step 2: 编写 compose.yml: 定义 services/networks/volumes Step 3: 配置依赖: depends_on + condition: service_healthy Step 4: 本地验证:
docker compose up -d
docker compose ps
docker compose logs
Step 5: 生产部署: 添加资源限制(resource limits)、重启策略(restart policy)、日志轮转 →
docker compose -f compose.yml -f compose.prod.yml up -d

Gotchas — Common Pitfalls

常见陷阱

  • depends_on without healthcheck:
    depends_on
    only waits for container START, not READY. → Recovery: Always add
    condition: service_healthy
    +
    healthcheck:
    block; use
    docker compose ps
    to verify health status.
  • Port conflict: Multiple services can't bind the same host port. → Recovery: Use different host ports or remove
    ports:
    for internal-only services (they communicate via service name).
  • Bind mount paths: Relative paths are resolved from the compose file location. → Recovery: Use
    ./config
    not
    config/
    ; verify with
    docker compose config
    to see resolved paths.
  • .env
    file security
    :
    .env
    files often contain secrets. → Recovery: Add
    .env
    to
    .gitignore
    ; use Docker secrets for Swarm; use
    .env.example
    with placeholder values.
  • docker compose
    vs
    docker-compose
    : Modern syntax is
    docker compose
    (plugin). → Recovery:
    docker-compose
    (standalone binary) is deprecated; always use
    docker compose
    (with space).
  • 未配置健康检查的 depends_on
    depends_on
    仅等待容器启动,而非就绪状态。→ 解决方法:务必添加
    condition: service_healthy
    +
    healthcheck:
    块;使用
    docker compose ps
    验证健康状态。
  • 端口冲突:多个服务无法绑定同一主机端口。→ 解决方法:使用不同主机端口,或为仅内部访问的服务移除
    ports:
    配置(服务间通过名称通信)。
  • 绑定挂载路径:相对路径从 compose 文件所在位置解析。→ 解决方法:使用
    ./config
    而非
    config/
    ;通过
    docker compose config
    验证解析后的路径。
  • .env
    文件安全
    .env
    文件常包含敏感信息。→ 解决方法:将
    .env
    添加至
    .gitignore
    ;Swarm 模式使用 Docker secrets;提供
    .env.example
    包含占位符值。
  • docker compose
    vs
    docker-compose
    :现代语法为
    docker compose
    (插件形式)。→ 解决方法
    docker-compose
    (独立二进制文件)已废弃;请始终使用带空格的
    docker compose

Boundary — 能力边界(适用与不适用场景)

Boundary — 能力边界(适用与不适用场景)

分类场景说明
✅ 能做多容器应用编排services/networks/volumes/secrets/configs 完整定义
✅ 能做环境管理.env / env_file / override 文件策略
✅ 能做依赖控制depends_on + healthcheck + profiles
⚠️ 需条件多主机部署迁移到 Swarm(
docker stack deploy
)或 K8s
⚠️ 需条件滚动更新/自动扩缩Compose 不支持,需 Swarm 或 K8s
❌ 超范围编写 Dockerfile使用
docker-dockerfile
❌ 超范围K8s 部署使用
kompose convert
+ K8s 技能
❌ 超范围云服务编排(Terraform)IaaC 工具
分类场景说明
✅ 能做多容器应用编排services/networks/volumes/secrets/configs 完整定义
✅ 能做环境管理.env / env_file / override 文件策略
✅ 能做依赖控制depends_on + healthcheck + profiles
⚠️ 需条件多主机部署迁移到 Swarm(
docker stack deploy
)或 K8s
⚠️ 需条件滚动更新/自动扩缩Compose 不支持,需 Swarm 或 K8s
❌ 超范围编写 Dockerfile使用
docker-dockerfile
❌ 超范围K8s 部署使用
kompose convert
+ K8s 技能
❌ 超范围云服务编排(Terraform)基础设施即代码工具

When NOT to Use This Skill

不适用场景

❌ Skip✅ Use Instead
Single-container apps
docker-run
Writing Dockerfile
docker-dockerfile
Kubernetes deploymentK8s manifests / Helm charts
Docker basics
docker-basics
❌ 不使用✅ 替代技能
单容器应用
docker-run
编写 Dockerfile
docker-dockerfile
Kubernetes 部署K8s 清单 / Helm 图表
Docker 基础
docker-basics

Security & Stability

安全与稳定性

  • Use
    internal: true
    for backend networks to prevent external access.
  • Never commit
    .env
    files with secrets. Use CI secrets or Docker Swarm secrets.
  • Production Compose on single host: combine with systemd for auto-start on boot.
  • Multi-host production: migrate to Swarm (
    docker stack deploy
    ) or Kubernetes.
  • 为后端网络设置
    internal: true
    ,防止外部访问。
  • 切勿提交包含敏感信息的
    .env
    文件。使用 CI 密钥或 Docker Swarm 密钥。
  • 单主机生产环境 Compose:结合 systemd 实现开机自启。
  • 多主机生产环境:迁移至 Swarm(
    docker stack deploy
    )或 Kubernetes。

📚 官方文档参考

📚 官方文档参考

🧭 Docker Skills Journey

🧭 Docker 技能路径

📍 You are here:
docker-compose
— 多容器编排
← Previous:
docker-buildx
/
docker-networking
→ Next:
docker-production
/
docker-cicd
📍 当前位置:
docker-compose
— 多容器编排
← 上一阶段:
docker-buildx
/
docker-networking
→ 下一阶段:
docker-production
/
docker-cicd