Skip to content

Docker Compose 快速入门 ​

Docker Compose 是定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用程序的服务,然后使用一个简单的命令创建并启动所有服务。

目录 ​

  1. Compose 概述
  2. 安装 Docker Compose
  3. 第一个 Compose 应用
  4. 核心概念
  5. 常用命令
  6. 实战示例

Compose 概述 ​

1.1 什么是 Docker Compose ​

Docker Compose 是 Docker 官方提供的容器编排工具,主要特点:

Docker Compose 特点:

┌─────────────────────────────────────────┐
│  1. 单一配置文件                         │
│     - docker-compose.yml                │
│     - 声明式服务定义                      │
├─────────────────────────────────────────┤
│  2. 一键启动/停止                        │
│     - docker-compose up                 │
│     - docker-compose down               │
├─────────────────────────────────────────┤
│  3. 服务自动编排                         │
│     - 自动处理依赖关系                    │
│     - 自动创建网络和卷                    │
├─────────────────────────────────────────┤
│  4. 开发环境友好                         │
│     - 代码热重载                         │
│     - 环境变量管理                        │
└─────────────────────────────────────────┘

1.2 Compose 适用场景 ​

场景说明
开发环境本地开发、调试
测试环境自动化测试
单机部署单主机生产环境
CI/CD持续集成/部署
演示环境快速搭建演示

1.3 Compose vs Swarm vs Kubernetes ​

特性ComposeSwarmKubernetes
复杂度低中高
多主机❌✅✅
自动扩缩容❌✅✅
服务发现基础完整完整
适用场景开发/测试小型生产大型生产

安装 Docker Compose ​

2.1 Docker Desktop ​

Docker Desktop 已包含 Docker Compose:

bash
# 验证安装
docker-compose --version
# 或
docker compose version

2.2 Linux 安装 ​

bash
# 下载 Docker Compose 插件
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
mkdir -p $DOCKER_CONFIG/cli-plugins
curl -SL https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 \
  -o $DOCKER_CONFIG/cli-plugins/docker-compose

# 添加执行权限
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

# 验证安装
docker compose version

2.3 独立安装(旧版本) ​

bash
# 下载
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" \
  -o /usr/local/bin/docker-compose

# 添加权限
chmod +x /usr/local/bin/docker-compose

# 创建软链接
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# 验证
docker-compose --version

第一个 Compose 应用 ​

3.1 项目结构 ​

my-compose-app/
├── docker-compose.yml
├── web/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
│       └── index.js
└── README.md

3.2 Web 应用代码 ​

javascript
// web/src/index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Hello from Docker Compose!',
    timestamp: new Date().toISOString()
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
json
// web/package.json
{
  "name": "web",
  "version": "1.0.0",
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}

3.3 Dockerfile ​

dockerfile
# web/Dockerfile
FROM node:18-alpine

WORKDIR /app

# 安装依赖
COPY package*.json ./
RUN npm ci --only=production

# 复制应用代码
COPY src/ ./src/

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

EXPOSE 3000

CMD ["npm", "start"]

3.4 Compose 文件 ​

yaml
# docker-compose.yml
version: '3.8'

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - PORT=3000
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

volumes:
  redis-data:

3.5 启动应用 ​

bash
# 进入项目目录
cd my-compose-app

# 启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 测试应用
curl http://localhost:3000

核心概念 ​

4.1 Services(服务) ​

服务是 Compose 应用的基本单元:

yaml
services:
  # Web 服务
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    
  # 数据库服务
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
    
  # 缓存服务
  cache:
    image: redis:7-alpine

4.2 Networks(网络) ​

Compose 自动创建网络,服务间可以通过服务名通信:

yaml
services:
  web:
    image: nginx:alpine
    networks:
      - frontend
      - backend
  
  api:
    image: myapi:latest
    networks:
      - backend
  
  db:
    image: postgres:15-alpine
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true  # 无外部访问

4.3 Volumes(卷) ​

数据持久化和共享:

yaml
services:
  db:
    image: postgres:15-alpine
    volumes:
      # 命名卷
      - db-data:/var/lib/postgresql/data
      # 绑定挂载
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
      # 临时卷
      - type: tmpfs
        target: /tmp
        tmpfs:
          size: 100M

volumes:
  db-data:
    driver: local

4.4 环境变量 ​

yaml
services:
  web:
    image: myapp:latest
    environment:
      # 直接设置
      NODE_ENV: production
      # 引用主机环境变量
      API_KEY: ${API_KEY}
      # 带默认值
      PORT: ${PORT:-3000}
      # 必需变量
      DATABASE_URL: ${DATABASE_URL:?DATABASE_URL is required}
    env_file:
      - .env
      - .env.local

常用命令 ​

5.1 生命周期管理 ​

bash
# 启动服务
docker-compose up              # 前台运行
docker-compose up -d           # 后台运行
docker-compose up --build      # 重新构建
docker-compose up --force-recreate  # 强制重新创建

# 停止服务
docker-compose stop            # 停止
docker-compose down            # 停止并删除
docker-compose down -v         # 同时删除卷
docker-compose down --rmi all  # 同时删除镜像

# 重启服务
docker-compose restart         # 重启所有
docker-compose restart web     # 重启指定服务

5.2 查看状态 ​

bash
# 查看服务状态
docker-compose ps
docker-compose ps -q           # 只显示 ID

# 查看日志
docker-compose logs            # 所有服务
docker-compose logs web        # 指定服务
docker-compose logs -f         # 实时跟踪
docker-compose logs --tail 100 # 最后 100 行

# 查看进程
docker-compose top

# 查看事件
docker-compose events

5.3 服务操作 ​

bash
# 构建服务
docker-compose build           # 构建所有
docker-compose build web       # 构建指定服务
docker-compose build --no-cache # 不使用缓存

# 拉取镜像
docker-compose pull

# 推送镜像
docker-compose push

# 扩展服务
docker-compose up -d --scale web=3

# 在容器中执行命令
docker-compose exec web bash
docker-compose exec -T web ps aux

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

5.4 配置管理 ​

bash
# 验证配置
docker-compose config          # 查看完整配置
docker-compose config -q       # 只验证,不输出

# 查看环境变量
docker-compose config --environment

实战示例 ​

6.1 Web + API + 数据库 ​

yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      - api
    networks:
      - frontend

  api:
    build: ./api
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - DB_USER=api
      - DB_PASS=${DB_PASSWORD}
      - REDIS_HOST=redis
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    environment:
      POSTGRES_USER: api
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U api -d app"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5
    networks:
      - backend

volumes:
  db-data:
  redis-data:

networks:
  frontend:
  backend:
    internal: true

6.2 开发环境配置 ​

yaml
# docker-compose.yml
version: '3.8'

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

  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    ports:
      - "5000:5000"
    volumes:
      - ./api:/app
      - /app/__pycache__
    environment:
      - FLASK_ENV=development
      - FLASK_DEBUG=1
    command: flask run --host=0.0.0.0 --reload

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

volumes:
  db-data:

6.3 生产环境配置 ​

yaml
# docker-compose.prod.yml
version: '3.8'

services:
  web:
    build:
      context: ./web
      dockerfile: Dockerfile
    restart: always
    deploy:
      replicas: 2
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    restart: always
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
      restart_policy:
        condition: on-failure
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

  db:
    restart: always
    deploy:
      placement:
        constraints:
          - node.role == manager

部署命令:

bash
# 生产部署
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

# 或使用环境变量
COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml docker-compose up -d

下一步 ​

基于 MIT 许可发布