强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Docker 完全指南 / 09 - Compose 基础

09 - Compose 基础

使用 Docker Compose 定义和管理多容器应用,实现一键启动开发环境。


9.1 Docker Compose 简介

Docker Compose 是一个多容器编排工具,使用 YAML 文件定义应用的服务、网络和卷,然后用一条命令启动整个应用栈。

传统方式 (繁琐):
  docker network create my-net
  docker volume create db-data
  docker run -d --name db --network my-net -v db-data:/var/lib/mysql ...
  docker run -d --name redis --network my-net ...
  docker run -d --name app --network my-net -p 8080:80 ...

Compose 方式 (简洁):
  docker compose up -d    # 一条命令搞定一切

Compose 文件版本演进

版本说明
Compose V1docker-compose 命令,Python 实现,已废弃
Compose V2docker compose 命令(无连字符),Go 实现,当前主流
Compose Spec2020 年合并入 Docker 规范,无需指定 version 字段
# 检查 Compose 版本
docker compose version

# V1 (已废弃)
docker-compose --version

# V2 (推荐)
docker compose version

9.2 compose.yaml 文件结构

基本结构

# compose.yaml (或 docker-compose.yml)

services:       # 服务定义
  web:
    ...
  db:
    ...

networks:       # 网络定义(可选)
  ...

volumes:        # 卷定义(可选)
  ...

configs:        # 配置定义(可选)
  ...

secrets:        # 密钥定义(可选)
  ...

最小示例

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
# 启动
docker compose up -d

# 查看状态
docker compose ps

# 停止
docker compose down

9.3 服务配置详解

完整服务配置

services:
  web:
    # 镜像来源 (二选一)
    image: nginx:alpine
    # build: ./web          # 从 Dockerfile 构建

    # 容器名称
    container_name: my-web

    # 端口映射
    ports:
      - "8080:80"
      - "8443:443"
      - "127.0.0.1:9090:9090"

    # 环境变量
    environment:
      - NODE_ENV=production
      - DB_HOST=db
    # 或使用文件
    # env_file:
    #   - .env

    # 数据卷
    volumes:
      - ./html:/usr/share/nginx/html:ro
      - nginx-logs:/var/log/nginx

    # 网络
    networks:
      - frontend

    # 依赖关系
    depends_on:
      - db
      - redis

    # 重启策略
    restart: unless-stopped

    # 资源限制
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

    # 健康检查
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

    # 日志配置
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

    # 标签
    labels:
      - "traefik.enable=true"
      - "app.version=1.0"

常用配置项速查

配置项说明示例
image使用的镜像nginx:alpine
build从 Dockerfile 构建./app 或详细配置
ports端口映射"8080:80"
environment环境变量KEY=value
env_file环境变量文件.env
volumes数据卷/挂载data:/app/data
networks加入的网络frontend
depends_on启动依赖[db, redis]
restart重启策略unless-stopped
command覆盖默认命令["npm", "start"]
entrypoint覆盖入口点/entrypoint.sh
working_dir工作目录/app
user运行用户node:node
stdin_open打开 stdintrue
tty分配 TTYtrue
profiles配置文件组[debug, test]

9.4 实战:Web + DB 应用栈

目录结构

my-project/
├── compose.yaml
├── .env
├── app/
│   ├── Dockerfile
│   └── src/
│       └── ...
└── db/
    └── init.sql

compose.yaml

services:
  # ---- 应用服务 ----
  app:
    build: ./app
    container_name: my-app
    ports:
      - "8080:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=5432
      - DB_NAME=${POSTGRES_DB}
      - DB_USER=${POSTGRES_USER}
      - DB_PASS=${POSTGRES_PASSWORD}
    volumes:
      - ./app/src:/app/src:ro
      - app-uploads:/app/uploads
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - frontend
      - backend

  # ---- 数据库服务 ----
  db:
    image: postgres:16-alpine
    container_name: my-db
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    volumes:
      - pg-data:/var/lib/postgresql/data
      - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - backend

  # ---- Redis 缓存 ----
  redis:
    image: redis:7-alpine
    container_name: my-redis
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    restart: unless-stopped
    networks:
      - backend

# ---- 网络定义 ----
networks:
  frontend:
  backend:

# ---- 卷定义 ----
volumes:
  pg-data:
  redis-data:
  app-uploads:

.env 文件

# .env
POSTGRES_USER=admin
POSTGRES_PASSWORD=supersecret
POSTGRES_DB=myapp

启动与管理

# 一键启动所有服务
docker compose up -d

# 查看服务状态
docker compose ps

# 查看日志
docker compose logs
docker compose logs -f app     # 跟踪指定服务日志
docker compose logs --tail 50  # 最近 50 行

# 查看资源使用
docker compose top
docker stats

# 进入容器
docker compose exec app sh
docker compose exec db psql -U admin -d myapp

# 停止所有服务
docker compose down

# 停止并删除卷(数据会丢失!)
docker compose down -v

9.5 构建配置

基本构建

services:
  app:
    build:
      context: ./app
      dockerfile: Dockerfile
    image: my-app:latest

详细构建配置

services:
  app:
    build:
      context: .
      dockerfile: docker/Dockerfile.prod
      target: production           # 多阶段构建目标
      args:                        # 构建参数
        NODE_ENV: production
        APP_VERSION: "1.0.0"
      cache_from:                  # 缓存来源
        - my-app:latest
      labels:                      # 镜像标签
        - "app.version=1.0.0"
      platforms:                   # 多架构
        - linux/amd64
        - linux/arm64
    image: my-app:latest           # 构建后的镜像名
# 构建镜像
docker compose build

# 强制重建(不使用缓存)
docker compose build --no-cache

# 构建并启动
docker compose up --build

# 仅构建指定服务
docker compose build app

9.6 网络配置

默认网络

# 不定义 networks 时,Compose 自动创建默认网络
# 网络名: <项目名>_default
services:
  web:
    image: nginx:alpine
  db:
    image: postgres:16
# web 和 db 自动在同一默认网络中,可通过服务名访问

自定义网络

services:
  web:
    networks:
      - frontend
  api:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # 仅内部通信,无法访问外部网络

9.7 依赖管理

depends_on

services:
  app:
    depends_on:
      db:
        condition: service_healthy    # 等待健康检查通过
      redis:
        condition: service_started    # 仅等待启动
      migration:
        condition: service_completed_successfully  # 等待完成

  migration:
    build: ./app
    command: python manage.py migrate
    depends_on:
      db:
        condition: service_healthy

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

  redis:
    image: redis:7-alpine

depends_on 条件

条件说明
service_started服务已启动(默认)
service_healthy服务健康检查通过
service_completed_successfully服务成功退出(退出码 0)

9.8 环境变量

方式一: environment 字段

services:
  app:
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - SECRET_KEY=abc123

方式二: env_file 字段

services:
  app:
    env_file:
      - .env
      - .env.local    # 可指定多个文件

方式三: .env 文件(自动加载)

Compose 会自动加载项目目录下的 .env 文件中的变量,用于 compose.yaml 中的变量替换。

# .env
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret

# compose.yaml
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

变量优先级

优先级从高到低:
  1. docker compose run -e 设置的变量
  2. Shell 环境变量 (export)
  3. env_file 文件中的变量
  4. compose.yaml 中 environment 字段
  5. Dockerfile 中 ENV 定义的变量
  6. .env 文件中的变量(仅用于 compose.yaml 变量替换)

9.9 Compose 命令大全

生命周期命令

# 创建并启动所有服务
docker compose up -d

# 创建并启动指定服务
docker compose up -d app db

# 强制重建镜像并启动
docker compose up --build --force-recreate

# 停止所有服务
docker compose stop

# 停止并删除容器、网络
docker compose down

# 停止并删除容器、网络、卷
docker compose down -v

# 停止并删除容器、网络、卷、镜像
docker compose down -v --rmi all

# 重启服务
docker compose restart app

# 暂停/恢复服务
docker compose pause
docker compose unpause

查看命令

# 查看服务状态
docker compose ps
docker compose ps -a  # 包含已停止的

# 查看日志
docker compose logs -f --tail 100

# 查看进程
docker compose top

# 查看资源使用
docker compose stats

# 验证配置文件
docker compose config

# 列出镜像
docker compose images

执行命令

# 在运行中的容器内执行命令
docker compose exec app bash
docker compose exec db psql -U admin

# 运行一次性命令(创建新容器)
docker compose run --rm app python manage.py test
docker compose run --rm app npm install

# exec vs run 的区别:
# exec: 进入已运行的容器
# run:  创建新容器执行命令(使用 --rm 自动清理)

9.10 Compose 配置文件名

# 默认查找顺序:
# 1. compose.yaml (推荐)
# 2. compose.yml
# 3. docker-compose.yaml
# 4. docker-compose.yml

# 指定配置文件
docker compose -f compose.prod.yaml up -d

# 使用多个配置文件(合并)
docker compose -f compose.yaml -f compose.prod.yaml up -d

# 指定项目名称
docker compose -p my-project up -d

要点回顾

要点核心内容
compose.yaml定义服务、网络、卷的声明式配置文件
服务发现同一 Compose 项目中的服务可通过服务名互相访问
depends_on控制服务启动顺序,支持健康检查条件
环境变量支持 environment、env_file、.env 三种方式
常用命令up -d 启动、down 停止、logs -f 日志、exec 执行

注意事项

文件名推荐: 新项目使用 compose.yaml(无 docker- 前缀),这是 Docker 官方推荐的命名。

不要存储密码: .env 文件不要提交到 Git。使用 .env.example 作为模板,并在 .gitignore 中排除 .env

depends_on 不等待就绪: service_started 仅表示容器已启动,不代表应用已就绪。务必配合健康检查使用 service_healthy


下一步

10 - Compose 进阶:学习多环境配置、Profiles、扩展字段等高级特性。