Docker Compose多容器编排实战:自动化部署与网络配置指南

Docker Compose是Docker自动化部署中最常用的多容器编排工具。相比手写docker run命令,Compose通过声明式配置文件管理容器生命周期,在DevOps实践中承担着本地开发环境搭建和CI/CD流水线集成的核心角色。本文以一个Web应用+数据库+缓存的典型三容器架构为例,拆解Compose的配置方法和排障思路。

Docker Compose编排文件结构与核心配置

Compose文件使用YAML格式,顶层结构包含services、networks、volumes三大部分。一个典型的LNMP应用编排文件如下:

# docker-compose.yml
services:
  web:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./html:/usr/share/nginx/html:ro
      - ./nginx/logs:/var/log/nginx
    depends_on:
      app:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - frontend

  app:
    build: ./app
    environment:
      - DB_HOST=mysql
      - DB_PORT=3306
      - REDIS_HOST=redis
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s
    restart: unless-stopped
    networks:
      - frontend
      - backend

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}
      MYSQL_DATABASE: appdb
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d:ro
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: unless-stopped
    networks:
      - backend

  redis:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - backend

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

volumes:
  mysql_data:
  redis_data:

这个配置的关键设计点在于网络隔离。frontend网络对外暴露80和443端口,backend网络标记为internal: true,外部无法直接访问MySQL和Redis容器。app容器同时接入两个网络,充当网关角色。

多容器网络隔离与通信方案

Docker Compose默认创建bridge网络。容器间通过服务名解析对方IP,DNS解析由Docker内置DNS服务器完成。上面的配置中,app容器可以通过mysql:3306连接数据库,通过redis:6379连接缓存,无需知道具体IP。

网络隔离的验证方法:

# 从web容器测试能否直连mysql(应该失败)
docker compose exec web ping mysql
# 输出: ping: bad address 'mysql'

# 从app容器测试连接mysql(应该成功)
docker compose exec app ping mysql
# 输出: 64 bytes from mysql (172.20.0.3): seq=1 ttl=64 time=0.123 ms

如果容器间无法通信,排查步骤:用docker network ls确认网络存在,用docker network inspect查看容器是否正确接入网络,用docker compose exec检查DNS解析是否正常。常见原因是容器没有加入同一个网络,或者depends_on配置导致启动顺序问题。

数据持久化与Volume挂载策略

Docker容器的文件系统是临时的,容器删除后数据丢失。数据持久化有三种方式:命名Volume、绑定挂载(Bind Mount)、tmpfs挂载。

命名Volume由Docker管理,适合数据库数据等不需要直接访问的场景。绑定挂载将宿主机目录映射到容器内,适合配置文件和日志等需要直接查看的场景。tmpfs挂载数据存放在内存中,适合临时文件。

# Volume备份脚本
#!/bin/bash
BACKUP_DIR="/data/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)

docker compose exec mysql mysqldump -u root -p"$DB_ROOT_PASS" appdb \
  | gzip > "$BACKUP_DIR/appdb_$DATE.sql.gz"

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

绑定挂载的权限问题是最常见的坑。容器内进程以特定用户运行时,宿主机目录的权限可能不匹配。解决方法是在Dockerfile中创建与宿主机UID一致的用户,或者在docker-compose.yml中指定user参数。

环境变量管理与配置分离

敏感信息不应硬编码在Compose文件中。使用.env文件和变量引用实现配置分离:

# .env 文件
DB_ROOT_PASS=Str0ngP@ssw0rd
APP_SECRET=your-app-secret-key
MYSQL_VERSION=8.0
# docker-compose.yml 中引用
services:
  mysql:
    image: mysql:${MYSQL_VERSION}
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}

.env文件不要提交到Git仓库,在.gitignore中排除。不同环境(开发、测试、生产)使用不同的.env文件。CI/CD流水线中通过环境变量注入生产环境的配置。

健康检查与自动重启机制

healthcheck配置让Docker能判断容器是否真正可用。上面的app容器配置了HTTP健康检查端点,每10秒检查一次。depends_on配合condition: service_healthy,确保app容器健康后web容器才启动。

restart策略的选择:always策略在容器退出后总是重启,包括手动stop后重启Docker时也会启动。unless-stopped策略在手动stop后不会自动启动,更适合需要人工干预的场景。no策略是默认值,容器退出后不重启。

# 查看容器健康状态
docker compose ps
# NAME   STATUS                   PORTS
# web    Up 2 minutes (healthy)   0.0.0.0:80->80/tcp
# app    Up 3 minutes (healthy)
# mysql  Up 3 minutes (healthy)
# redis  Up 3 minutes (healthy)

# 查看健康检查日志
docker inspect --format='{{json .State.Health}}' app

Docker Compose在CI/CD流水线中的集成

在CI/CD流水线中,Docker Compose用于拉起测试环境,运行测试后销毁。典型的GitHub Actions配置:

# .github/workflows/test.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Start services
        run: docker compose up -d
      - name: Wait for healthy
        run: |
          timeout 60 bash -c 'until \
            docker compose ps | grep -c "healthy" | grep -q 4; \
            do sleep 2; done'
      - name: Run tests
        run: docker compose exec -T app npm test
      - name: Tear down
        if: always
        run: docker compose down -v

日志收集方面,Docker Compose默认使用json-file日志驱动,日志无限制增长会撑满磁盘。生产环境需要配置日志轮转:

# docker-compose.yml 日志配置
services:
  app:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

或者切换到fluentd或syslog日志驱动,将日志统一发送到日志分析平台。监控告警体系可以对接cAdvisor采集容器指标,配合Prometheus + Grafana实现容器层面的监控可视化。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/dockercompose-duo-rong-qi-bian-pai-shi-zhan-zi-dong-hua-bu/

(0)
小编小编
上一篇 3小时前
下一篇 3小时前

相关推荐