Skip to content

Docker Compose

Compose基础

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

Compose的优势

1. 简化多容器管理

  • 一个命令启动所有服务
  • 统一的服务配置管理
  • 自动服务依赖处理

2. 环境一致性

  • 开发、测试、生产环境配置一致
  • 版本控制友好的配置文件
  • 可重复的部署过程

3. 服务编排

  • 定义服务间关系
  • 自动网络创建
  • 数据卷管理

Compose文件结构

基本结构

yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html

  database:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:

版本说明

版本Docker Engine版本主要特性
3.819.03.0+最新特性,推荐使用
3.718.06.0+支持deploy配置
3.618.02.0+支持外部网络
3.517.12.0+支持secrets

服务配置

基础配置

yaml
services:
  web:
    # 镜像配置
    image: nginx:alpine
    
    # 构建配置
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - VERSION=1.0
    
    # 容器名称
    container_name: my-web-app
    
    # 重启策略
    restart: unless-stopped
    
    # 环境变量
    environment:
      - NODE_ENV=production
      - PORT=3000
    
    # 环境变量文件
    env_file:
      - .env
      - .env.production

网络配置

yaml
services:
  web:
    image: nginx:alpine
    networks:
      - frontend
      - backend
  
  database:
    image: mysql:8.0
    networks:
      - backend

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true

数据卷配置

yaml
services:
  web:
    image: nginx:alpine
    volumes:
      # 命名数据卷
      - web-data:/usr/share/nginx/html
      # 绑定挂载
      - ./config:/etc/nginx/conf.d
      # 只读挂载
      - ./static:/usr/share/nginx/static:ro

  database:
    image: mysql:8.0
    volumes:
      - db-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

volumes:
  web-data:
  db-data:
    driver: local

端口配置

yaml
services:
  web:
    image: nginx:alpine
    ports:
      # 简单映射
      - "8080:80"
      # 指定IP
      - "127.0.0.1:8080:80"
      # 随机端口
      - "80"
      # UDP端口
      - "8080:80/udp"

Compose命令

基本命令

bash
# 启动服务
docker-compose up

# 后台启动服务
docker-compose up -d

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

# 启动特定服务
docker-compose up web database

# 停止服务
docker-compose down

# 停止并删除数据卷
docker-compose down -v

# 停止并删除镜像
docker-compose down --rmi all

服务管理

bash
# 启动服务
docker-compose start

# 停止服务
docker-compose stop

# 重启服务
docker-compose restart

# 重启特定服务
docker-compose restart web

# 查看服务状态
docker-compose ps

# 查看服务日志
docker-compose logs

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

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

服务操作

bash
# 进入服务容器
docker-compose exec web bash

# 在服务中执行命令
docker-compose exec web ls -la

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

# 构建服务
docker-compose build

# 拉取服务镜像
docker-compose pull

实践练习

练习1:基础Web应用

创建docker-compose.yml

yaml
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    restart: unless-stopped

  database:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myapp
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - "3306:3306"
    restart: unless-stopped

volumes:
  db-data:

创建html/index.html

html
<!DOCTYPE html>
<html>
<head>
    <title>Docker Compose练习</title>
</head>
<body>
    <h1>Hello Docker Compose!</h1>
    <p>这是一个多容器应用示例</p>
</body>
</html>

运行应用:

bash
# 启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs

# 停止服务
docker-compose down

练习2:Node.js应用

创建docker-compose.yml

yaml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
      - redis
    restart: unless-stopped

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped

  redis:
    image: redis:alpine
    volumes:
      - redis-data:/data
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app
    restart: unless-stopped

volumes:
  postgres-data:
  redis-data:

创建Dockerfile

dockerfile
FROM node:16-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

创建package.json

json
{
  "name": "docker-compose-app",
  "version": "1.0.0",
  "description": "Docker Compose练习应用",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.0",
    "pg": "^8.7.0",
    "redis": "^4.0.0"
  }
}

创建app.js

javascript
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

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

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

app.listen(port, '0.0.0.0', () => {
  console.log(`应用运行在端口 ${port}`);
});

练习3:开发环境配置

创建docker-compose.dev.yml

yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: myapp_dev
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres-dev-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    restart: unless-stopped

volumes:
  postgres-dev-data:

创建Dockerfile.dev

dockerfile
FROM node:16-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "run", "dev"]

高级配置

健康检查

yaml
services:
  web:
    image: nginx:alpine
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

资源限制

yaml
services:
  web:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

服务依赖

yaml
services:
  web:
    image: nginx:alpine
    depends_on:
      - database
      - redis
    condition: service_healthy

  database:
    image: mysql:8.0
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

环境管理

多环境配置

yaml
# docker-compose.yml (基础配置)
version: '3.8'

services:
  web:
    image: nginx:alpine
    ports:
      - "${PORT:-8080}:80"
    environment:
      - NODE_ENV=${NODE_ENV:-production}

# docker-compose.override.yml (开发环境)
version: '3.8'

services:
  web:
    volumes:
      - ./html:/usr/share/nginx/html
    ports:
      - "8080:80"

# docker-compose.prod.yml (生产环境)
version: '3.8'

services:
  web:
    restart: always
    deploy:
      replicas: 3

环境变量文件

创建.env

NODE_ENV=production
PORT=8080
DATABASE_URL=postgresql://user:password@db:5432/myapp

最佳实践

1. 文件组织

project/
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── .env
├── .env.example
├── Dockerfile
├── Dockerfile.dev
└── services/
    ├── web/
    ├── api/
    └── database/

2. 安全配置

yaml
services:
  web:
    image: nginx:alpine
    user: "1000:1000"
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache/nginx

3. 性能优化

yaml
services:
  web:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          memory: 512M
        reservations:
          memory: 256M

常见问题

1. 服务启动失败

bash
# 查看详细日志
docker-compose logs web

# 检查服务状态
docker-compose ps

# 重新构建服务
docker-compose up --build

2. 网络连接问题

bash
# 检查网络配置
docker-compose exec web ping database

# 查看网络信息
docker network ls
docker network inspect project_default

3. 数据卷问题

bash
# 检查数据卷
docker volume ls
docker volume inspect project_db-data

# 清理数据卷
docker-compose down -v

下一步

掌握Docker Compose后,您可以:

  1. 继续学习 Docker多阶段构建
  2. 学习Docker Swarm集群编排
  3. 探索Kubernetes容器编排

学习检查点

完成本章学习后,您应该能够:

  • [ ] 理解Docker Compose的基本概念和优势
  • [ ] 熟练编写docker-compose.yml文件
  • [ ] 掌握Compose命令的使用
  • [ ] 了解多环境配置管理
  • [ ] 解决Compose相关的常见问题