mcpField
D
docker-compose-setup

docker-compose-setup

github.com/seb1n云与 DevOps232121 次安装11 周前更新
代码仓库

关于 docker-compose-setup

这项技能用于通过 Docker Compose 设计和配置多容器应用栈。内容涵盖服务依赖、网络、持久化存储、健康检查,以及开发和生产环境的不同设置。

主要功能

  1. 01梳理服务及其依赖
  2. 02配置镜像、端口和变量
  3. 03设置网络与服务发现
  4. 04管理持久化卷和挂载
  5. 05添加健康检查与启动顺序
  6. 06创建环境专属覆盖配置

适用场景

  1. 01定义多服务应用栈
  2. 02持久保存数据库和上传数据
  3. 03按依赖协调服务启动
  4. 04区分开发与生产设置

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill docker-compose-setup

安装后在 Claude Code 中输入/docker-compose-setup确认已加载。

详细介绍

Docker Compose 配置

此技能可让 Agent 使用 Docker Compose 设计和配置多容器应用程序堆栈。Agent 可以编排 Web 服务器、数据库、缓存、后台工作进程和反向代理等服务,并正确配置网络、卷管理、健康检查以及特定环境的覆盖配置。Agent 了解开发和生产环境配置,并能生成符合 Docker 最佳实践的 compose 文件。

工作流

  1. 分析应用程序堆栈: Agent 会检查项目架构,以确定所有必需服务及其依赖项。这包括主应用程序容器、数据库(PostgreSQL、MySQL、MongoDB)、缓存(Redis、Memcached)、消息队列(RabbitMQ、Kafka)、后台工作进程以及反向代理(Nginx、Traefik)。Agent 会梳理服务间的依赖关系,以确定启动顺序和健康检查要求。

  2. 定义服务和镜像: 对于每项服务,Agent 会指定 Docker 镜像或构建上下文、公开的端口、环境变量和资源限制。应用程序服务通常使用指向本地 Dockerfile 的 build 指令,而基础设施服务则使用带固定版本标签的官方镜像。Agent 会避免在生产环境中使用 latest 标签,以确保部署可复现。

  3. 配置网络和服务发现: Agent 会创建命名 Docker 网络,以隔离不同服务层之间的流量(例如,为代理和应用创建 frontend 网络,为应用和数据库创建 backend 网络)。服务使用 compose 服务名称作为 DNS 主机名进行通信,无需硬编码 IP 地址。

  4. 设置卷和持久化: Agent 会为必须在容器重启后保留的数据定义命名卷,例如数据库存储和文件上传。对于开发环境,会使用绑定挂载将主机源代码映射到容器中,以支持热重载。Agent 会确保卷权限和所有权针对容器运行时用户进行了正确配置。

  5. 添加健康检查并设置依赖顺序: Agent 会为关键服务配置健康检查,使依赖服务在其依赖项真正就绪后再启动,而不只是等待其启动。这可以避免应用程序容器在数据库虽已启动但尚未接受连接时发生崩溃等常见问题。使用带有 condition: service_healthy 的 depends_on 指令可确保正确的启动顺序。

  6. 创建特定环境的覆盖配置: Agent 会生成基础 docker-compose.yml,用于共享配置,并生成覆盖文件(开发环境使用 docker-compose.override.yml,生产环境使用 docker-compose.prod.yml),以便按环境自定义设置。开发环境覆盖配置包括绑定挂载、调试端口和详细日志记录;生产环境覆盖配置则包括资源限制、重启策略和经过优化的日志驱动程序。

支持的技术

  • Compose 版本: Docker Compose V2(集成的 Docker CLI 插件)
  • 应用程序运行时: Node.js、Python、Ruby、Go、Java、PHP、.NET
  • 数据库: PostgreSQL、MySQL、MariaDB、MongoDB、Redis、Elasticsearch
  • 反向代理: Nginx、Traefik、Caddy、HAProxy
  • 消息队列: RabbitMQ、Kafka、NATS
  • 监控: Prometheus、Grafana、cAdvisor

用法

向 Agent 提供应用程序堆栈的说明,包括所需的服务、它们之间的关系,以及配置用于开发还是生产环境。

示例提示词:

Create a docker-compose setup for my Node.js app with:
- PostgreSQL database with persistent storage
- Redis for session caching
- Nginx reverse proxy with SSL termination
- A Celery-like background worker process
- Development setup with hot reloading

示例

示例 1:全栈 Web 应用程序(Node.js + PostgreSQL + Redis + Nginx)
services:
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/certs:/etc/nginx/certs:ro
    depends_on:
      app:
        condition: service_healthy
    networks:
      - frontend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost/health"]
      interval: 30s
      timeout: 5s
      retries: 3

  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      NODE_ENV: production
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
      SESSION_SECRET: ${SESSION_SECRET}
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - frontend
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://localhost:3000/health').then(r => r.ok ? process.exit(0) : process.exit(1))"]
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 30s

  worker:
    build:
      context: .
      dockerfile: Dockerfile
    command: node worker.js
    environment:
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - backend
    restart: unless-stopped

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    networks:
      - backend
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3

volumes:
  postgres_data:
  redis_data:

networks:
  frontend:
  backend:
示例 2:开发与生产环境的覆盖配置

docker-compose.yml(基础共享配置):

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      DATABASE_URL: postgres://appuser:${DB_PASSWORD}@postgres:5432/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - backend

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - backend
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d myapp"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

networks:
  backend:

docker-compose.override.yml(开发环境——自动加载):

services:
  app:
    build:
      target: development
    ports:
      - "3000:3000"
      - "9229:9229"   # Node.js debug port
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      NODE_ENV: development
      DEBUG: "app:*"
    command: npm run dev

  postgres:
    ports:
      - "5432:5432"   # Expose DB to host for local tooling

docker-compose.prod.yml(生产环境——通过 -f 使用):

services:
  app:
    build:
      target: production
    restart: unless-stopped
    environment:
      NODE_ENV: production
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
        reservations:
          cpus: "0.5"
          memory: 256M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  postgres:
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 1G

使用以下命令运行生产环境:docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

最佳实践

  • 使用命名卷保存持久化数据: 不要依赖容器内部存储来保存数据库或上传文件。命名卷在容器重新创建后仍会保留,也可以单独备份。
  • 固定镜像版本: 始终指定明确的镜像标签(例如 postgres:16-alpine),而不是 latest,以避免镜像更新时出现意外的重大变更。
  • 为每项服务配置健康检查: 健康检查可让 Docker 检测容器是否处于不健康状态,并支持使用 depends_on 和 condition: service_healthy 实现可靠的启动顺序。如果没有健康检查,依赖服务可能会在其依赖项就绪前启动。
  • 使用 .env 文件保存密钥: 将数据库密码和 API 密钥等敏感值存储在 .env 文件中,并通过 .gitignore 将该文件排除在版本控制之外。在 compose 文件中使用 ${VARIABLE} 语法引用变量。
  • 按层划分网络: 使用不同的网络隔离流量。反向代理不应能够直接访问数据库。这样可以限制容器遭到入侵后的影响范围。
  • 通过覆盖配置保持 compose 文件 DRY: 使用基础配置加覆盖配置的模式,而不是为每个环境复制整个 compose 文件。这样可以确保共享的服务定义保持同步。

边缘情况

  • 主机端口冲突: 如果主机端口已被占用(例如,另一项服务正在使用 5432 端口),Docker Compose 将无法绑定端口。请使用唯一的主机端口,或者为只需通过 Docker 网络与容器通信的服务设置 ports: []。
  • 卷权限不匹配: 以非 root 用户身份运行的容器,如果主机目录权限受限,可能无法写入挂载的卷。请在 compose 文件中使用 user: 指令,或在 Dockerfile 的入口点中使用 chown,使 UID/GID 保持一致。
  • 构建缓存失效: 在 Dockerfile 前面的部分更改 COPY 或 ADD 指令,会使之后所有层的缓存失效。请按更改频率从低到高排列 Dockerfile 指令(先列依赖项,再列源代码),以最大限度地复用缓存。
  • 启动期间的容器 DNS 解析: 服务可能会在依赖容器分配 IP 地址之前解析其 DNS 名称,从而导致连接失败。使用带有 depends_on 条件的健康检查可以避免此问题,但仍建议在应用程序层实现重试逻辑。
  • 孤立的容器和卷: 从 compose 文件中移除某项服务后再运行 docker compose up,会留下仍在运行的孤立容器。请使用 docker compose up --remove-orphans,并定期运行 docker volume prune 清理未使用的卷。

评论

支持 Markdown