如何编写 Docker Compose 文件

Docker Compose 是 Docker 官方提供的工具,用于定义和运行多容器应用程序。通过一个 YAML 格式的 docker-compose.yml 文件,你可以配置服务的镜像、端口、环境变量、网络和数据卷。


1. 什么是 Docker Compose?

Docker Compose 允许你通过单一配置文件管理多容器应用程序,简化开发、测试和部署流程。它支持:

  • 定义多个服务(如 Web 服务器、应用程序、数据库)。
  • 配置容器间的依赖、网络和数据持久化。
  • 一键启动、停止和管理所有容器。

适用场景

  • 开发:快速搭建本地开发环境。
  • 测试:模拟生产环境的多服务架构。
  • CI/CD:自动化部署和测试。
  • 生产:适合小型项目或快速原型。

2. 准备工作

确保安装:

  • Docker:运行容器的核心。
  • Docker Compose:通常随 Docker Desktop 安装,Linux 系统需单独安装。

验证安装:

docker --version
docker-compose --version

推荐使用代码编辑器(如 VS Code)以支持 YAML 语法高亮和验证。


3. 创建 Docker Compose 文件

3.1 文件名和格式

  • 默认文件名docker-compose.yml(或 .yaml)。
  • 格式:YAML 语法,缩进为 2 个空格,避免 Tab。
  • 验证工具:运行 docker-compose config 检查语法。

3.2 基本结构

顶级字段包括:

  • version:指定 Compose 文件格式版本。
  • services:定义容器服务。
  • networks:配置服务间网络。
  • volumes:定义数据持久化卷。

4. 编写一个基础 Docker Compose 文件

以下是一个示例,包含 Web 服务器、应用服务和数据库,展示常见配置:

version: '3.8'

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    networks:
      - app-network
    depends_on:
      - app
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/mydb
      - APP_ENV=production
    networks:
      - app-network
    depends_on:
      - db
    restart: always

  db:
    image: postgres:latest
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - app-network
    restart: always

volumes:
  db-data:
    name: db-data

networks:
  app-network:
    driver: bridge

5. 详细配置说明

5.1 version

  • 定义 Compose 文件格式版本,如 '3.8'
  • 版本影响支持的功能和语法:
    • 3.x:支持 Docker Swarm 和现代功能。
    • 推荐使用最新版本(截至 2025 年,'3.8' 或更高)。
  • 参考:Docker Compose 文件版本.

5.2 services

每个服务定义一个容器,常用配置包括:

5.2.1 image

  • 指定预构建镜像,如 nginx:latest(从 Docker Hub 拉取)。
  • 可使用私有仓库镜像:myregistry.com/myapp:1.0

5.2.2 build

  • 从 Dockerfile 构建镜像:
    • context:构建路径(如 . 表示当前目录)。
    • dockerfile:指定 Dockerfile 文件名。
    • 示例:
      build:
        context: ./app
        dockerfile: Dockerfile.prod
      

5.2.3 ports

  • 映射主机和容器端口,格式:"主机端口:容器端口"
  • 示例:"8080:80" 将主机的 8080 端口映射到容器的 80 端口。
  • 支持多个端口映射:
    ports:
      - "8080:80"
      - "8443:443"
    

5.2.4 environment

  • 设置容器环境变量,支持两种格式:
    • 键值对:- KEY=VALUE
    • 仅键(从 .env 文件读取):- KEY
  • 示例:
    environment:
      - APP_ENV=production
      - DEBUG=false
    

5.2.5 volumes

  • 挂载主机目录或命名卷:
    • 主机路径:./html:/usr/share/nginx/html:roro 表示只读)。
    • 命名卷:db-data:/var/lib/postgresql/data
  • 命名卷在 volumes 顶级字段定义,适合持久化数据。

5.2.6 depends_on

  • 指定服务启动顺序,如 web 依赖 app
  • 注意:仅控制启动顺序,不保证服务完全就绪(需配合健康检查)。

5.2.7 restart

  • 定义容器重启策略:
    • no:不重启(默认)。
    • always:始终重启。
    • on-failure:仅在失败时重启。
    • unless-stopped:除非手动停止,否则始终重启。

5.2.8 healthcheck

  • 检查容器健康状态:
    • test:执行的命令(如 pg_isreadycurl)。
    • interval:检查间隔。
    • timeout:超时时间。
    • retries:失败重试次数。

5.3 networks

网络配置决定容器间的通信方式。Docker 支持多种网络驱动程序,桥接模式(bridge)是最常用的。

5.3.1 桥接模式(bridge

  • 作用:在同一主机上创建隔离的网络,容器通过服务名(如 db)相互访问。
  • 特点
    • 默认网络模式,适合大多数单主机应用。
    • 容器通过服务名解析 IP,无需手动配置。
    • 隔离外部网络,需通过 ports 暴露到主机。
  • 配置
    networks:
      app-network:
        driver: bridge
    
  • 适用场景:Web 应用、微服务、开发测试环境。

5.3.2 其他网络模式

  • host
    • 作用:容器直接使用主机的网络栈,无隔离。
    • 特点
      • 性能最高,但安全性较低(无网络隔离)。
      • 无法自定义 ports,直接使用容器端口。
    • 配置
      networks:
        default:
          driver: host
      
    • 适用场景:需要高性能网络或调试网络问题。
  • overlay
    • 作用:支持跨主机容器通信,专为 Docker Swarm 设计。
    • 特点
      • 适合分布式集群环境。
      • 需要 Swarm 模式初始化。
    • 配置
      networks:
        swarm-network:
          driver: overlay
      
    • 适用场景:生产环境中的多主机部署。
  • macvlan
    • 作用:为容器分配独立 MAC 地址,像物理设备一样接入网络。
    • 特点
      • 容器拥有独立 IP,适合与外部设备直接通信。
      • 配置复杂,需指定子网和网关。
    • 配置
      networks:
        macvlan-network:
          driver: macvlan
          driver_opts:
            parent: eth0
      
    • 适用场景:物联网设备或需要独立 IP 的场景。
  • none
    • 作用:禁用网络,容器完全隔离。
    • 特点:无网络接口,仅本地通信。
    • 配置
      networks:
        none-network:
          driver: none
      
    • 适用场景:运行独立任务或安全敏感应用。

5.3.3 自定义网络

  • 默认网络:不定义 networks 时,Compose 创建一个默认桥接网络。
  • 自定义网络:推荐显式定义网络(如 app-network),便于管理和隔离。
  • 连接服务
    services:
      web:
        networks:
          - app-network
    

5.4 volumes

  • 类型
    • 命名卷:在 volumes 定义(如 db-data),数据持久化,适合数据库。
    • 绑定挂载:主机路径映射(如 ./html:/usr/share/nginx/html),适合开发时同步代码。
    • 临时卷:不定义在 volumes,容器删除后数据丢失。
  • 配置
    volumes:
      db-data:
        name: db-data
    

6. 高级配置

6.1 使用 .env 文件

将敏感信息放入 .env 文件:

# .env
POSTGRES_USER=user
POSTGRES_PASSWORD=password
POSTGRES_DB=mydb

在 Compose 文件中引用:

db:
  environment:
    - POSTGRES_USER=${POSTGRES_USER}
    - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    - POSTGRES_DB=${POSTGRES_DB}

6.2 资源限制

限制 CPU 和内存:

app:
  deploy:
    resources:
      limits:
        cpus: '0.5'
        memory: 512M
      reservations:
        cpus: '0.25'
        memory: 256M

6.3 健康检查

确保服务就绪:

db:
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U user"]
    interval: 10s
    timeout: 5s
    retries: 5

6.4 扩展配置

复用配置:

# common.yml
services:
  app:
    environment:
      - LOG_LEVEL=info

引用:

services:
  app:
    extends:
      file: common.yml
      service: app

6.5 环境特定配置

为不同环境创建文件:

  • docker-compose.dev.yml:开发环境,映射本地代码。
  • docker-compose.prod.yml:生产环境,优化性能。

合并运行:

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

7. 运行和管理 Docker Compose

7.1 常用命令

  • 启动docker-compose up -d(后台运行)。
  • 停止并删除docker-compose down(保留命名卷)。
  • 查看日志docker-compose logs -f(实时查看)。
  • 验证配置docker-compose config
  • 查看服务docker-compose ps
  • 进入容器docker exec -it <container_name> /bin/bash.

7.2 调试技巧

  • 检查网络docker network lsdocker network inspect <network_name>
  • 端口冲突:用 docker ps 检查占用端口。
  • 清理缓存docker-compose build --no-cache

8. 实际用例:WordPress 站点

搭建 WordPress 和 MySQL:

version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wp_user
      - WORDPRESS_DB_PASSWORD=wp_password
      - WORDPRESS_DB_NAME=wordpress
    networks:
      - wp-network
    depends_on:
      - db

  db:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wp_user
      - MYSQL_PASSWORD=wp_password
    volumes:
      - wp-data:/var/lib/mysql
    networks:
      - wp-network

volumes:
  wp-data:

networks:
  wp-network:
    driver: bridge

运行后,访问 http://localhost:8080 进入 WordPress 安装。


9. 最佳实践

  1. 版本控制:将 docker-compose.yml 纳入 Git。
  2. 环境隔离:使用不同 Compose 文件区分开发、测试、生产。
  3. 安全性
    • 使用 .env 文件存储敏感信息。
    • 设置 read_only 卷或非 root 用户。
  4. 网络优化:显式定义桥接网络,避免默认网络冲突。
  5. 文档化:为服务和配置添加注释。

10. 常见问题

  • 服务无法通信?确保服务在同一网络,使用服务名(如 db)而非 localhost
  • 端口冲突?检查主机端口占用,修改 ports
  • 数据丢失?使用命名卷而非临时卷。
  • 构建失败?检查 Dockerfile 路径,清理缓存。

11. 更多资源

梦葉樱 all right reserved,powered by Gitbook该文件最后修改时间: 2025-08-01 20:16:02

results matching ""

    No results matching ""