跳转到内容

Docker Compose 实战教程:从零掌握多容器应用编排(2026版)

本文为你系统介绍 Docker Compose 的基础概念、YAML 语法、多容器编排技巧及生产环境最佳实践,让你快速掌握容器化应用部署。

💡 提示:本文已更新到 2026 年 5 月,包含 Docker Compose V2 的最新特性和实际项目案例。

了解 Docker Compose 的基本概念

Docker Compose 是 Docker 官方提供的 多容器应用编排工具,通过单个 YAML 文件定义复杂的应用架构,实现一键部署和管理。

什么是容器编排?

容器编排(Container Orchestration) 是指自动化管理多个容器的生命周期:

传统方式:手动管理每个容器

    docker run container1
    docker run container2
    docker run container3
    ...(繁琐且易出错)

容器编排:统一管理和调度

    docker-compose up
    ✅ 自动启动所有容器
    ✅ 自动配置网络
    ✅ 自动挂载数据卷
    ✅ 自动处理依赖关系

Docker Compose 的核心价值:

  • 简化部署:一条命令启动整个应用栈
  • 环境一致性:开发、测试、生产环境完全一致
  • 版本控制:配置文件可纳入 Git 管理
  • 易于协作:团队成员共享相同的配置

核心特点

  • 声明式配置:用 YAML 描述期望状态

    • 清晰易读
    • 版本可控
    • 便于审查
  • 多容器管理:同时管理多个相关容器

    • Web 应用 + 数据库 + 缓存
    • 微服务架构
    • 完整的技术栈
  • 依赖管理:自动处理容器启动顺序

    • 先启动数据库
    • 再启动应用服务
    • 最后启动反向代理
  • 环境隔离:不同项目互不干扰

    • 独立网络空间
    • 独立数据卷
    • 独立资源限制

发展历程

版本发布时间主要特点
Compose V12014 年Python 编写,docker-compose 命令
Compose V22021 年Go 重写,docker compose 子命令
Compose Spec2020 年标准化规范,跨平台兼容
Compose V2.20+2024 年性能优化,Watch 模式

目前主流使用的是 Docker Compose V2,作为 Docker CLI 的子命令集成,性能更优,功能更强。

Docker 生态简介

公司名称:Docker Inc.
成立时间:2013 年
创始人:Solomon Hykes
总部:美国旧金山
主要产品:Docker Engine, Docker Desktop, Docker Hub, Docker Compose
使命:让开发者能够轻松构建、分享和运行任何应用
用户规模:全球超过 1300 万开发者

安装与配置

系统要求

最低配置:

  • CPU:2 核心
  • 内存:4 GB
  • 磁盘:20 GB 可用空间
  • 操作系统:Linux / macOS / Windows 10+

推荐配置:

  • CPU:4 核心+
  • 内存:8 GB+
  • 磁盘:SSD 50 GB+
  • 网络:稳定的互联网连接

前置条件

在开始之前,确保已安装:

bash
# 检查 Docker 是否安装
docker --version
# 输出:Docker version 24.0.7, build afdd53b

# 检查 Docker 是否运行
docker info
# 应该显示系统信息,无错误

# 检查 Docker Compose 是否已集成(V2)
docker compose version
# 输出:Docker Compose version v2.21.0

⚠️ 注意:Docker Desktop 默认包含 Compose V2。如果使用旧版 docker-compose 命令,建议升级到 V2。

各平台安装方法

Linux 系统

bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install docker-compose-plugin

# CentOS/RHEL
sudo yum install docker-compose-plugin

# 验证安装
docker compose version

macOS 系统

bash
# 通过 Docker Desktop 安装(推荐)
# 1. 下载 Docker Desktop for Mac
# 2. 安装后自动包含 Compose V2

# 或通过 Homebrew
brew install --cask docker

# 验证
docker compose version

Windows 系统

powershell
# 通过 Docker Desktop 安装(推荐)
# 1. 下载 Docker Desktop for Windows
# 2. 启用 WSL 2 后端
# 3. 安装后自动包含 Compose V2

# 验证
docker compose version

从 V1 迁移到 V2

如果你仍在使用旧版 docker-compose

bash
# 旧命令(V1)
docker-compose up -d

# 新命令(V2)
docker compose up -d

# 兼容性提示
# V2 完全兼容 V1 的配置文件格式
# 只需将命令中的连字符改为空格

编写 docker-compose.yml 文件

YAML 基础语法

YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化格式。

基本规则:

yaml
# 注释以 # 开头
key: value          # 键值对
list:               # 列表
  - item1
  - item2
nested:             # 嵌套对象
  key1: value1
  key2: value2

注意事项:

  • ✅ 使用空格缩进(通常 2 个空格)
  • ❌ 不要使用 Tab 缩进
  • ✅ 字符串可以不加引号
  • ✅ 特殊字符需要加引号

配置文件结构

一个标准的 docker-compose.yml 包含以下部分:

yaml
version: '3.8'              # 配置文件版本(可选,V2 可省略)

services:                   # 服务定义(必需)
  web:                      # 服务名称
    image: nginx:latest     # 使用的镜像
    ports:                  # 端口映射
      - "80:80"
    volumes:                # 数据卷挂载
      - ./html:/usr/share/nginx/html
    networks:               # 网络连接
      - frontend
    depends_on:             # 依赖关系
      - db
    environment:            # 环境变量
      - NGINX_HOST=localhost

  db:                       # 第二个服务
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend

volumes:                    # 命名数据卷定义
  db_data:

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

核心配置项详解

1. services(服务定义)

每个服务代表一个容器:

yaml
services:
  # 基本服务
  app:
    image: node:18-alpine
    command: npm start
    working_dir: /app
    
  # 从 Dockerfile 构建
  api:
    build:
      context: ./api           # 构建上下文
      dockerfile: Dockerfile   # Dockerfile 路径
      args:                    # 构建参数
        NODE_ENV: production

2. image(镜像指定)

yaml
services:
  # 使用官方镜像
  web:
    image: nginx:latest
    
  # 指定版本
  db:
    image: postgres:15.4
    
  # 使用私有仓库
  app:
    image: registry.example.com/myapp:v1.0

3. build(从 Dockerfile 构建)

yaml
services:
  app:
    build:
      context: .                    # 当前目录
      dockerfile: Dockerfile.prod   # 指定 Dockerfile
      target: production            # 多阶段构建的目标阶段
      args:                         # 构建时变量
        VERSION: 1.0.0

对应的 Dockerfile

dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine AS production
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

4. ports(端口映射)

yaml
services:
  web:
    ports:
      - "80:80"              # host:container
      - "443:443"
      - "8080-8090:8080-8090"  # 端口范围
      
  # 只暴露给其他容器(不映射到主机)
  db:
    expose:
      - "3306"

端口映射说明:

"8080:80" 表示:
  主机端口 8080 → 容器端口 80
  
访问 http://localhost:8080 
实际访问的是容器内的 80 端口

5. volumes(数据卷挂载)

yaml
services:
  app:
    volumes:
      # 绑定挂载(Bind Mount)
      - ./src:/app/src
      
      # 命名卷(Named Volume)
      - app_data:/app/data
      
      # 只读挂载
      - ./config:/app/config:ro

volumes:
  app_data:    # 定义命名卷

数据卷类型对比:

类型语法适用场景持久化
绑定挂载./host:/container开发环境代码同步取决于主机
命名卷volume_name:/container数据库数据✅ 是
tmpfstype: tmpfs临时文件❌ 否

6. environment(环境变量)

yaml
services:
  app:
    environment:
      # 方式一:列表格式
      - NODE_ENV=production
      - DB_HOST=db
      - DB_PORT=3306
      
      # 方式二:字典格式
      # NODE_ENV: production
      # DB_HOST: db
      
  db:
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}  # 从 .env 文件读取
      MYSQL_DATABASE: myapp

7. networks(网络配置)

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

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

8. depends_on(依赖关系)

yaml
services:
  web:
    depends_on:
      - api
      
  api:
    depends_on:
      db:
        condition: service_healthy    # 等待健康检查通过
      redis:
        condition: service_started    # 等待容器启动
        
  db:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

9. restart(重启策略)

yaml
services:
  app:
    restart: unless-stopped    # 除非手动停止,否则总是重启
    
  # 其他选项:
  # no: 不自动重启(默认)
  # always: 总是重启
  # on-failure: 只在失败时重启
  # on-failure:3: 最多重试 3 次

10. resources(资源限制)

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '0.5'        # 最多使用 0.5 个 CPU
          memory: 512M       # 最多使用 512MB 内存
        reservations:
          cpus: '0.25'       # 预留 0.25 个 CPU
          memory: 256M       # 预留 256MB 内存

完整示例:WordPress 博客

yaml
version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_content:/var/www/html/wp-content
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - wp_network

  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
    networks:
      - wp_network

volumes:
  wp_content:
  db_data:

networks:
  wp_network:
    driver: bridge

配套的 .env 文件:

bash
DB_PASSWORD=my_secure_password
DB_ROOT_PASSWORD=my_root_password

管理容器生命周期

常用命令

启动服务

bash
# 前台启动(日志输出到终端)
docker compose up

# 后台启动(推荐)
docker compose up -d

# 重新构建并启动
docker compose up -d --build

# 仅启动特定服务
docker compose up -d web db

# 强制重新创建容器
docker compose up -d --force-recreate

查看状态

bash
# 查看所有服务状态
docker compose ps

# 输出示例:
# NAME                IMAGE          COMMAND                  STATUS
# myapp-web-1         nginx:latest   "/docker-entrypoint.…"   Up 2 hours
# myapp-db-1          mysql:8.0      "docker-entrypoint.s…"   Up 2 hours (healthy)

# 查看实时日志
docker compose logs -f

# 查看特定服务的日志
docker compose logs -f web

# 查看资源使用情况
docker compose stats

停止服务

bash
# 停止服务(保留容器和数据)
docker compose stop

# 停止并删除容器
docker compose down

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

# 停止并删除所有内容(包括镜像)
docker compose down --rmi all

重启服务

bash
# 重启所有服务
docker compose restart

# 重启特定服务
docker compose restart web

# 重启并重新构建
docker compose up -d --build

执行命令

bash
# 在运行中的容器内执行命令
docker compose exec web bash

# 进入数据库容器
docker compose exec db mysql -u root -p

# 运行一次性命令
docker compose run --rm web npm test

# 在新容器中执行(不依赖正在运行的服务)
docker compose run app python manage.py migrate

实用技巧

1. 查看配置

bash
# 查看解析后的配置
docker compose config

# 查看服务列表
docker compose config --services

# 验证配置文件
docker compose config --quiet && echo "配置有效"

2. 扩展服务

bash
# 横向扩展(增加容器实例)
docker compose up -d --scale web=3

# 查看扩展后的状态
docker compose ps
# 会显示 web-1, web-2, web-3

3. 暂停和恢复

bash
# 暂停服务
docker compose pause

# 恢复服务
docker compose unpause

4. 拉取最新镜像

bash
# 拉取所有服务的最新镜像
docker compose pull

# 拉取特定服务的镜像
docker compose pull web

网络配置与数据卷管理

网络模式

Docker Compose 支持多种网络模式:

1. 默认桥接网络

yaml
services:
  web:
    image: nginx
  db:
    image: mysql

特点:

  • 自动创建默认网络
  • 服务间可通过服务名互相访问
  • 外部需要通过端口映射访问

2. 自定义网络

yaml
services:
  frontend:
    networks:
      - public
      
  backend:
    networks:
      - public
      - private
      
  database:
    networks:
      - private

networks:
  public:
    driver: bridge
  private:
    driver: bridge
    internal: true    # 内部网络,外部不可达

优势:

  • 网络隔离,提高安全性
  • 精细控制服务间通信
  • 模拟真实生产环境

3. Host 网络

yaml
services:
  app:
    network_mode: host

特点:

  • 容器直接使用主机网络
  • 无需端口映射
  • 性能最好,但隔离性差

4. None 网络

yaml
services:
  isolated_service:
    network_mode: none

特点:

  • 完全隔离,无网络连接
  • 适用于不需要网络的批处理任务

服务间通信

yaml
services:
  web:
    image: nginx
    networks:
      - frontend
      
  api:
    image: node:18
    networks:
      - frontend
      - backend
      
  db:
    image: postgres
    networks:
      - backend

networks:
  frontend:
  backend:

访问方式:

javascript
// 在 web 容器中访问 api
fetch('http://api:3000/data')

// 在 api 容器中访问 db
const pg = new Client({
  host: 'db',      // 使用服务名作为主机名
  port: 5432,
  database: 'mydb'
})

数据卷类型

1. 命名卷(推荐用于数据持久化)

yaml
services:
  db:
    image: postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
    driver: local

优点:

  • Docker 管理,位置透明
  • 备份和迁移方便
  • 性能较好

2. 绑定挂载(适合开发)

yaml
services:
  app:
    image: node:18
    volumes:
      - ./src:/app/src      # 代码热重载
      - ./config:/app/config:ro  # 只读配置

优点:

  • 主机文件实时同步
  • 便于调试和开发
  • 可直接编辑文件

3. tmpfs(临时存储)

yaml
services:
  app:
    image: node:18
    tmpfs:
      - /tmp
      - /cache

优点:

  • 存储在内存中,速度快
  • 容器停止后自动清除
  • 适合缓存和临时文件

数据卷操作

bash
# 列出所有数据卷
docker volume ls

# 查看数据卷详情
docker volume inspect myapp_postgres_data

# 备份数据卷
docker run --rm \
  -v myapp_postgres_data:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/db-backup.tar.gz -C /data .

# 恢复数据卷
docker run --rm \
  -v myapp_postgres_data:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/db-backup.tar.gz -C /data

# 删除未使用的数据卷
docker volume prune

环境变量管理

.env 文件

在项目根目录创建 .env 文件:

bash
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=myapp
DB_USER=admin
DB_PASSWORD=secret123

# 应用配置
APP_ENV=production
APP_DEBUG=false
APP_PORT=8080

# API 密钥
API_KEY=your_api_key_here
SECRET_KEY=your_secret_key

docker-compose.yml 中使用:

yaml
services:
  app:
    image: myapp:latest
    environment:
      - DB_HOST=${DB_HOST}
      - DB_PORT=${DB_PORT}
      - DB_NAME=${DB_NAME}
      - APP_ENV=${APP_ENV}

多环境配置

方案一:多个 .env 文件

bash
# .env.development
APP_ENV=development
DEBUG=true
DB_HOST=localhost

# .env.production
APP_ENV=production
DEBUG=false
DB_HOST=db.production.com

使用时指定:

bash
# 开发环境
docker compose --env-file .env.development up -d

# 生产环境
docker compose --env-file .env.production up -d

方案二:覆盖配置文件

yaml
# docker-compose.yml(基础配置)
services:
  app:
    image: myapp:latest
    environment:
      - APP_ENV=development

# docker-compose.prod.yml(生产覆盖)
services:
  app:
    environment:
      - APP_ENV=production
    deploy:
      resources:
        limits:
          memory: 1G

合并使用:

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

变量替换和默认值

yaml
services:
  app:
    environment:
      # 使用默认值
      - APP_PORT=${APP_PORT:-8080}
      
      # 必需变量(未设置会报错)
      - SECRET_KEY=${SECRET_KEY:?必须设置 SECRET_KEY}
      
      # 可选变量
      - OPTIONAL_VAR=${OPTIONAL_VAR:-}

敏感信息管理

❌ 不安全的方式:

yaml
# 不要直接在配置文件中写密码
environment:
  - DB_PASSWORD=super_secret

✅ 推荐的方式:

方式一:使用 Docker Secrets(Swarm 模式)

yaml
services:
  app:
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt

方式二:使用外部密钥管理服务

yaml
services:
  app:
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
    volumes:
      - /path/to/secrets:/run/secrets:ro

方式三:使用 HashiCorp Vault

yaml
services:
  vault-agent:
    image: hashicorp/vault
    environment:
      VAULT_ADDR: https://vault.example.com

生产环境最佳实践

安全加固

1. 非 root 用户运行

yaml
services:
  app:
    image: myapp:latest
    user: "1000:1000"    # UID:GID

在 Dockerfile 中:

dockerfile
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

2. 只读文件系统

yaml
services:
  app:
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache
    volumes:
      - app_data:/app/data:rw    # 仅需要写入的目录

3. 移除不必要的权限

yaml
services:
  app:
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE    # 仅添加需要的权限

4. 健康检查

yaml
services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
      
  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

5. 资源限制

yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

性能优化

1. 使用多阶段构建

dockerfile
# 构建阶段
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

2. 使用 .dockerignore

gitignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
dist

3. 缓存优化

yaml
services:
  app:
    build:
      context: .
      cache_from:
        - myapp:latest
        - myapp:cache

4. 日志管理

yaml
services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

监控和日志

1. 集成 Prometheus

yaml
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
      
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

2. 集中式日志

yaml
services:
  app:
    logging:
      driver: fluentd
      options:
        fluentd-address: localhost:24224
        tag: docker.app
        
  fluentd:
    image: fluent/fluentd
    ports:
      - "24224:24224"
    volumes:
      - ./fluent.conf:/fluentd/etc/fluent.conf

备份策略

自动备份脚本

bash
#!/bin/bash
# backup.sh

BACKUP_DIR="./backups"
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p $BACKUP_DIR

# 备份数据库
docker compose exec -T db pg_dump -U postgres mydb > $BACKUP_DIR/db_$DATE.sql

# 备份数据卷
docker run --rm \
  -v myapp_app_data:/data \
  -v $(pwd)/$BACKUP_DIR:/backup \
  alpine tar czf /backup/app_data_$DATE.tar.gz -C /data .

# 保留最近 7 天的备份
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "备份完成:$DATE"

设置定时任务:

bash
# 每天凌晨 2 点执行备份
crontab -e
0 2 * * * /path/to/backup.sh

CI/CD 集成

GitHub Actions 示例

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
          
      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          push: true
          tags: myapp:latest
          
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /opt/myapp
            docker compose pull
            docker compose up -d
            docker system prune -f

实际项目案例

案例 1:全栈应用(React + Node.js + PostgreSQL)

yaml
version: '3.8'

services:
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:80"
    depends_on:
      backend:
        condition: service_healthy
    networks:
      - app_network
    restart: unless-stopped

  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - app_network
    restart: unless-stopped

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app_network
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app_network
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - frontend
      - backend
    networks:
      - app_network
    restart: unless-stopped

volumes:
  postgres_data:
  redis_data:

networks:
  app_network:
    driver: bridge

案例 2:微服务架构

yaml
version: '3.8'

services:
  api-gateway:
    image: kong:latest
    ports:
      - "8000:8000"
      - "8443:8443"
    environment:
      KONG_DATABASE: postgres
      KONG_PG_HOST: kong-db
    depends_on:
      kong-db:
        condition: service_healthy
    networks:
      - gateway_network

  user-service:
    build: ./services/user
    environment:
      - SERVICE_NAME=user-service
      - PORT=3001
    networks:
      - services_network

  order-service:
    build: ./services/order
    environment:
      - SERVICE_NAME=order-service
      - PORT=3002
    networks:
      - services_network

  product-service:
    build: ./services/product
    environment:
      - SERVICE_NAME=product-service
      - PORT=3003
    networks:
      - services_network

  message-queue:
    image: rabbitmq:3-management
    ports:
      - "5672:5672"
      - "15672:15672"
    networks:
      - services_network

  kong-db:
    image: postgres:15
    environment:
      POSTGRES_DB: kong
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kong
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U kong"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - gateway_network

networks:
  gateway_network:
  services_network:

案例 3:开发环境

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - WATCHPACK_POLLING=true
    command: npm run dev
    stdin_open: true
    tty: true

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: devdb
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: dev
    ports:
      - "5432:5432"
    volumes:
      - dev_db_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"
      - "8025:8025"

volumes:
  dev_db_data:

常见问题 FAQ

Q1: Docker Compose 和 Kubernetes 有什么区别?

A:

  • Docker Compose:适合单机部署,简单易用,适合开发和小型项目
  • Kubernetes:适合集群部署,功能强大,适合大规模生产环境

选择建议:

  • 单机应用 → Docker Compose
  • 多节点集群 → Kubernetes
  • 从小规模开始 → 先用 Compose,后期迁移到 K8s

Q2: 如何调试容器?

A:

bash
# 查看日志
docker compose logs -f service_name

# 进入容器
docker compose exec service_name bash

# 查看容器详细信息
docker inspect container_id

# 查看资源使用
docker stats

Q3: 数据卷满了怎么办?

A:

bash
# 清理未使用的数据卷
docker volume prune

# 查看数据卷大小
docker system df -v

# 手动清理
docker compose down -v    # 删除所有数据卷(谨慎使用)

Q4: 如何更新服务?

A:

bash
# 拉取最新镜像
docker compose pull

# 重新创建容器
docker compose up -d

# 或者一步完成
docker compose up -d --pull always

Q5: 如何实现零停机更新?

A:

yaml
services:
  app:
    deploy:
      replicas: 3
      update_config:
        parallelism: 1      # 每次更新 1 个
        delay: 10s          # 更新间隔
        order: start-first  # 先启动新容器

⚠️ 注意:这需要 Docker Swarm 模式,普通 Compose 不支持。可以使用负载均衡器实现类似效果。

总结

通过本文的介绍,相信你已经全面掌握了 Docker Compose 的核心知识:

核心要点回顾

Docker Compose 是什么

  • 多容器应用编排工具
  • 通过 YAML 文件定义应用架构
  • 一键部署和管理复杂应用

核心功能

  • 服务定义和配置
  • 网络和存储管理
  • 环境变量管理
  • 容器生命周期控制

最佳实践

  • 安全加固(非 root、只读文件系统)
  • 性能优化(多阶段构建、缓存)
  • 监控和日志
  • 备份策略

实际应用

  • 全栈应用部署
  • 微服务架构
  • 开发环境配置

下一步行动

如果你准备好开始使用 Docker Compose:

👉 立即实践:Docker 入门教程

这里有 Docker 的基础知识,帮助你更好地理解容器化技术!

相关资源

官方文档:

📚 Docker Compose 官方文档
   https://docs.docker.com/compose/

📚 Docker 最佳实践
   https://docs.docker.com/develop/

📚 Compose 文件参考
   https://docs.docker.com/compose/compose-file/

本站相关教程:

📖 [Docker 安装指南](/fe/docker/install.md)
📖 [Docker 容器管理](/fe/docker/container.md)
📖 [Docker 镜像管理](/fe/docker/mirror.md)
📖 [Jellyfin 媒体服务器部署](/vps/serve/jellyfin-docker.md)
📖 [Vaultwarden 密码管理器](/vps/serve/vaultwarden-guide.md)

希望这份教程能帮助你高效使用 Docker Compose!如有任何问题,欢迎查看我们的其他相关教程。


延伸阅读

免责声明

本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。