domains / devops / docker-compose-orchestration / docker-compose

docker-compose

Skill card

combined

The sickn33 copy is a security-hardened reproduction of the BagelHole skill. It preserves the same structure and examples but adds an 'Execution Scope' section with authorization and credential-handling constraints, and modifies the examples to bind ports to 127.0.0.1 and use environment variable substitution for passwords. The BagelHole copy is the original procedural source but lacks these security constraints. Because the copies disagree on the safety of the examples (exposed ports vs. localhost-only) and the sickn33 copy adds material constraints not present in the original, crowning one would hide the security-hardened alternative.

Repositories

RepositoryPath
BagelHole/DevOps-Security-Agent-Skillsdevops/containers/docker-compose/SKILL.md
sickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/docker-compose/SKILL.md

Other copies

RoleRepositoryPath
peerBagelHole/DevOps-Security-Agent-Skillsdevops/containers/docker-compose/SKILL.md
peersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/docker-compose/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills/skills/docker-compose/SKILL.md
adaptersickn33/agentic-awesome-skillsskills/docker-compose/SKILL.md

Combined skill

---
name: docker-compose
description: Define and run multi-container Docker applications using Docker Compose with security best practices.
license: MIT
metadata:
  author: devops-skills
  version: "1.1"
---

# Docker Compose

Orchestrate multi-container applications with declarative YAML configuration.

## When to Use This Skill

Use this skill when:
- Running multi-container applications locally
- Setting up development environments
- Defining service dependencies and networking
- Managing application stacks with multiple services

## Execution Scope

Confirm the selected Docker context and project before any operation. Build instructions execute contributed commands; inspect the Dockerfile, build context, scripts and downloaded dependencies first. Image publication, shared-container stops and volume deletion need authorization for the exact target. Do not expose environment values, image history or logs containing credentials.

## Prerequisites

- Docker Engine with Compose plugin (v2)
- Basic Docker knowledge
- YAML syntax understanding

## Basic Configuration

### Simple Application Stack

```yaml
# docker-compose.yml
services:
  web:
    build: .
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      - NODE_ENV=development
      - DATABASE_URL=postgres://postgres:${POSTGRES_PASSWORD:?set a local fixture password}@db:5432/myapp
    depends_on:
      - db
      - redis

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set a local fixture password}
      POSTGRES_DB: myapp
    volumes:
      - postgres-data:/var/lib/postgresql/data
    ports:
      - "127.0.0.1:5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "127.0.0.1:6379:6379"

volumes:
  postgres-data:
```

## Service Configuration

### Build Options

```yaml
services:
  app:
    build:
      context: ./app
      dockerfile: Dockerfile.dev
      args:
        NODE_VERSION: "20"
      target: development
      cache_from:
        - myapp:cache
    image: myapp:dev
```

### Environment Variables

```yaml
services:
  app:
    environment:
      - NODE_ENV=production
      - API_KEY=${API_KEY}  # From shell or .env file
    env_file:
      - .env
      - .env.local
```

### Port Mapping

```yaml
services:
  web:
    ports:
      - "127.0.0.1:3000:3000"           # Bind to localhost only
      - "127.0.0.1:9229:9229" # Bind to localhost only
      - "8080-8090:8080-8090" # Port range
    expose:
      - "3000"                # Internal only (no host binding)
```

### Volume Mounts

```yaml
services:
  app:
    volumes:
      # Named volume
      - app-data:/app/data
      # Bind mount
      - ./src:/app/src
      # Read-only bind mount
      - ./config:/app/config:ro
      # Anonymous volume (for node_modules)
      - /app/node_modules

volumes:
  app-data:
    driver: local
```

### Dependencies

```yaml
services:
  web:
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:15
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
```

## Networking

### Custom Networks

```yaml
services:
  frontend:
    networks:
      - frontend-net

  backend:
    networks:
      - frontend-net
      - backend-net

  db:
    networks:
      - backend-net

networks:
  frontend-net:
    driver: bridge
  backend-net:
    driver: bridge
    internal: true  # No external access
```

### Network Aliases

```yaml
services:
  db:
    networks:
      backend:
        aliases:
          - database
          - postgres

networks:
  backend:
```

## Resource Limits

```yaml
services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 256M
```

## Multiple Compose Files

### Override Files

```yaml
# docker-compose.yml (base)
services:
  web:
    image: myapp:latest
    ports:
      - "127.0.0.1:3000:3000"

# docker-compose.override.yml (development - auto-loaded)
services:
  web:
    build: .
    volumes:
      - ./src:/app/src
    environment:
      - DEBUG=true

# docker-compose.prod.yml (production)
services:
  web:
    deploy:
      replicas: 3
    environment:
      - DEBUG=false
```

### Using Multiple Files

```bash
# Development (uses override automatically)
docker compose up

# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

# Merge and view final config
docker compose -f docker-compose.yml -f docker-compose.prod.yml config
```

## Profiles

```yaml
services:
  web:
    image: myapp

  db:
    image: postgres:15

  debug:
    image: busybox
    profiles:
      - debug

  monitoring:
    image: prometheus
    profiles:
      - monitoring
```

```bash
# Run without profiles (web, db only)
docker compose up

# Run with debug profile
docker compose --profile debug up

# Run with multiple profiles
docker compose --profile debug --profile monitoring up
```

## Commands

### Lifecycle

```bash
# Start services
docker compose up -d

# Start specific service
docker compose up -d web

# Stop services
docker compose stop

# Stop and remove containers
docker compose down

# Destructive: deletes project data volumes; require exact-scope approval and backups
docker compose down -v --rmi all

# Restart services
docker compose restart web
```

### Building

```bash
# Build images
docker compose build

# Build without cache
docker compose build --no-cache

# Build and start
docker compose up --build

# Pull latest images
docker compose pull
```

### Monitoring

```bash
# View logs
docker compose logs -f

# View specific service logs
docker compose logs -f web

# View running services
docker compose ps

# View resource usage
docker compose top
```

### Execution

```bash
# Run command in new container
docker compose run --rm web npm test

# Execute in running container
docker compose exec web /bin/sh

# Scale service
docker compose up -d --scale worker=3
```

## Development Workflow

### Watch Mode (Compose v2.22+)

```yaml
services:
  web:
    build: .
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
        - action: rebuild
          path: ./package.json
```

```bash
docker compose watch
```