Get Started
Back to Skill Shed
DevOps

Docker Compose Builder

Prompte27 February 2026IntermediateClaude Code, Codex, Cursor, Windsurf, Aider
dockerdocker-composecontainersdevopsinfrastructure

What This Skill Does

Guides your AI coding assistant to produce well-structured Docker Compose configurations. Services are properly networked, volumes are correctly mounted, health checks ensure dependency ordering, and environment variables are managed securely.

When to Use It

Activate this skill when setting up or modifying multi-container environments:

  • Creating a local development environment with database, cache, and app services
  • Setting up a staging environment that mirrors production
  • Adding new services (message queues, search engines, monitoring) to an existing stack
  • Debugging container networking or dependency ordering issues

What Changes

Your AI assistant will:

  • Define services with explicit dependencies and health checks
  • Use named volumes for persistent data and bind mounts for development
  • Create isolated networks for service groups that need to communicate
  • Never hardcode secrets — use .env files or Docker secrets
  • Add restart policies and resource limits for production readiness

Skill File

docker-compose-builder.skill.md
---
name: docker-compose-builder
description: >
  Build production-ready Docker Compose configurations. Define services with
  health checks, proper networking, named volumes, and secure environment
  variable handling. Never hardcode secrets.
---

# Docker Compose Builder

You build Docker Compose configurations that are production-ready, secure, and well-organised.

## File Structure

Always use the modern `compose.yaml` filename (not `docker-compose.yml`):

```
project/
  compose.yaml            # Main compose file
  compose.override.yaml   # Dev-specific overrides (auto-loaded)
  compose.prod.yaml       # Production overrides
  .env                    # Environment variables (git-ignored)
  .env.example            # Template for required variables
```

## Service Definition Rules

### 1. Always Include Health Checks

```yaml
services:
  postgres:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
```

### 2. Use depends_on with Conditions

```yaml
services:
  api:
    build: .
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
```

Never rely on `depends_on` without `condition: service_healthy` — it only guarantees start order, not readiness.

### 3. Networking

- Create explicit named networks for service groups
- Services that don't need to communicate should be on different networks
- Never use `network_mode: host` unless absolutely necessary

```yaml
networks:
  backend:
    driver: bridge
  monitoring:
    driver: bridge

services:
  api:
    networks: [backend]
  postgres:
    networks: [backend]
  grafana:
    networks: [monitoring, backend]  # needs access to both
```

### 4. Volume Management

```yaml
volumes:
  postgres_data:      # Named volume for persistent data
  redis_data:

services:
  postgres:
    volumes:
      - postgres_data:/var/lib/postgresql/data  # Persistent
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro  # Init script, read-only
```

Rules:
- **Named volumes** for data that must persist (databases, uploads)
- **Bind mounts** for development (source code with hot reload)
- **`:ro` flag** on volumes that should not be written to
- **tmpfs** for temporary data that should not persist

### 5. Environment Variables

```yaml
services:
  api:
    env_file:
      - .env              # Shared defaults
      - .env.local         # Local overrides (git-ignored)
    environment:
      - NODE_ENV=production                 # Non-sensitive, inline is fine
      - DATABASE_URL                        # Value comes from .env file
```

Rules:
- Never hardcode passwords, API keys, or secrets in compose files
- Use `env_file` to load from `.env` (git-ignored)
- Provide `.env.example` with placeholder values and comments
- For production, use Docker secrets or an external secret manager

### 6. Production Settings

```yaml
services:
  api:
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "0.5"
        reservations:
          memory: 256M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
```

## Common Service Templates

### PostgreSQL

```yaml
postgres:
  image: postgres:16-alpine
  volumes:
    - postgres_data:/var/lib/postgresql/data
  environment:
    POSTGRES_USER: ${POSTGRES_USER}
    POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    POSTGRES_DB: ${POSTGRES_DB}
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
    interval: 10s
    timeout: 5s
    retries: 5
  ports:
    - "${POSTGRES_PORT:-5432}:5432"
```

### Redis

```yaml
redis:
  image: redis:7-alpine
  command: redis-server --requirepass ${REDIS_PASSWORD}
  volumes:
    - redis_data:/data
  healthcheck:
    test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
    interval: 10s
    timeout: 5s
    retries: 5
```

## Anti-Patterns to Reject

1. **`latest` tag** — Always pin image versions (`postgres:16-alpine`, not `postgres:latest`)
2. **Missing health checks** — Every service that takes time to start needs one
3. **Secrets in compose.yaml** — These files are committed to git
4. **No restart policy** — Containers should recover from crashes
5. **Exposing unnecessary ports** — Only expose ports that external clients need

Install

Claude Code

Save to your project's .claude/skills/ directory. Claude Code picks it up automatically.

Save to:
.claude/skills/docker-compose-builder.skill.md
Or use the command line:
mkdir -p .claude/skills/ && curl -o .claude/skills/docker-compose-builder.skill.md https://prompte.app/skill-shed/docker-compose-builder/raw

Explore more skills

Browse the full library of curated skills for your AI coding CLI.