3. Docker Compose 基础:语法、命令与网络模式

在支付订单系统的本地开发环境中,通常需要同时启动 MySQL、Redis、RocketMQ、Nacos 等多个中间件。手动使用 docker run 逐个启动不仅效率低下,而且难以管理容器间的依赖与网络。Docker Compose 通过一个声明式的 docker-compose.yml 文件,允许你一键定义和运行多容器应用,是本地调试中间件栈的核心工具。

3.1 docker-compose.yml 核心语法

docker-compose.yml 使用 YAML 格式,遵循 version → services → networks → volumes 的顶层结构。以下是一个支付订单系统本地调试环境的典型配置示例:

version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: pay-mysql
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: payment_db
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init-sql:/docker-entrypoint-initdb.d
    networks:
      - pay-net
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: pay-redis
    ports:
      - "6379:6379"
    networks:
      - pay-net

  rocketmq-namesrv:
    image: apache/rocketmq:4.9.4
    container_name: rmq-namesrv
    ports:
      - "9876:9876"
    environment:
      JAVA_OPT_EXT: "-server -Xms256m -Xmx256m"
    command: sh mqnamesrv
    networks:
      - pay-net

  rocketmq-broker:
    image: apache/rocketmq:4.9.4
    container_name: rmq-broker
    ports:
      - "10911:10911"
      - "10909:10909"
    environment:
      JAVA_OPT_EXT: "-server -Xms512m -Xmx512m"
      NAMESRV_ADDR: rocketmq-namesrv:9876
    depends_on:
      - rocketmq-namesrv
    volumes:
      - ./broker.conf:/etc/rocketmq/broker.conf
    command: sh mqbroker -c /etc/rocketmq/broker.conf
    networks:
      - pay-net

  nacos:
    image: nacos/nacos-server:2.2.3
    container_name: pay-nacos
    ports:
      - "8848:8848"
    environment:
      MODE: standalone
      MYSQL_SERVICE_HOST: mysql
      MYSQL_SERVICE_DB_NAME: nacos_config
      MYSQL_SERVICE_USER: root
      MYSQL_SERVICE_PASSWORD: root123
    depends_on:
      mysql:
        condition: service_healthy
    networks:
      - pay-net

networks:
  pay-net:
    driver: bridge

volumes:
  mysql-data:
关键字段说明:
  • image:指定镜像名称及标签,生产环境应锁定具体版本号。
  • ports:"宿主机端口:容器端口",用于本地访问中间件。
  • environment:传递环境变量,如数据库密码、JVM参数。
  • volumes:持久化数据或挂载配置文件,避免容器重启后数据丢失。
  • depends_on:控制启动顺序,但仅等待容器启动,不保证服务就绪;需配合 healthcheck 使用。
  • networks:将服务加入自定义网络,实现服务名互通。

3.2 常用命令:up / down / logs / exec

掌握以下四个核心命令,即可完成日常的中间件环境启停与调试:

命令 功能 支付场景示例
docker-compose up -d 后台启动所有服务 启动 MySQL + Redis + RocketMQ + Nacos
docker-compose down 停止并移除容器、网络 清理本地调试环境,释放端口
docker-compose logs -f 实时跟踪所有服务日志 排查 Broker 注册失败或 Nacos 连接异常
docker-compose exec <service> <cmd> 在运行中的容器内执行命令 exec mysql mysql -uroot -p 进入数据库
调试技巧: 使用 docker-compose logs -f rocketmq-broker 单独跟踪某个服务的日志;使用 docker-compose exec redis redis-cli 直接进入 Redis 命令行验证缓存数据。

3.3 网络模式选择:bridge vs host

网络模式决定了容器之间、容器与宿主机之间的通信方式。在支付订单系统的本地调试中,最常用的是 bridge 和 host 两种模式。

Docker Compose 网络模式对比 Bridge 模式(默认) 容器 A (MySQL) 容器 B (Redis) 服务名互通 容器 C (Nacos) 容器 D (Broker) 通过 docker0 网桥与宿主机通信 Host 模式 容器 A (MySQL) 容器 B (Redis) 容器 C (Nacos) 容器 D (Broker) 直接使用宿主机网络栈,无端口映射
特性 Bridge 模式 Host 模式
网络隔离 容器拥有独立网络命名空间,通过 docker0 桥接 容器共享宿主机网络命名空间,无隔离
端口映射 需要 ports 显式映射 容器直接使用宿主机端口,无需映射
服务发现 支持 Docker DNS,通过服务名访问 只能通过 localhost 或宿主机 IP 访问
性能 有少量 NAT 开销 无网络开销,性能最佳
适用场景 推荐用于本地调试,多容器协作 对网络性能要求极高,或容器数量少
避坑指南:
  • 在 Bridge 模式下,容器间通过 服务名(如 mysql)而非 localhost 连接。支付应用配置数据库地址应为 jdbc:mysql://mysql:3306/payment_db。
  • Host 模式在 macOS 和 Windows 上存在兼容性问题,因为 Docker Desktop 运行在虚拟机中,Host 模式实际指向虚拟机而非宿主机。建议在 Linux 开发机上使用。
  • 如果多个中间件使用相同端口(如多个 Broker),必须使用 Bridge 模式并映射不同宿主机端口。

3.4 本地调试网络拓扑

以下 SVG 展示了支付订单系统在 Docker Compose 环境下的完整网络拓扑,所有中间件通过自定义 Bridge 网络 pay-net 互联:

支付订单系统本地调试网络拓扑 支付应用 (App) MySQL 8.0 Redis 7 RocketMQ Nacos 自定义 Bridge 网络:pay-net 宿主机端口映射 3306 → MySQL | 6379 → Redis | 9876/10911 → RocketMQ | 8848 → Nacos
实战要点:
  • 支付应用通过 mysql:3306、redis:6379、rocketmq-broker:10911、nacos:8848 访问中间件,无需关心宿主机 IP。
  • 使用 docker-compose up -d 启动后,可通过 docker-compose ps 确认所有服务状态为 Up。
  • 若需重置数据,执行 docker-compose down -v 会同时删除 volumes,谨慎使用。