
Docker Compose
- 142 installs
- 36 repo stars
- Updated July 14, 2026
- oimiragieo/agent-studio
Scaffold, validate, and run multi-service local stacks via Docker Compose so agents can boot databases, APIs, and workers consistently before integration or end-to-end testing.
About
docker-compose skill guides agents through creating and operating Docker Compose setups—defining services, networks, and volumes—so full-stack features can be developed and verified locally with repeatable container orchestration.
- Generate or edit compose YAML for local dev
- Start, stop, and inspect multi-container stacks
- Wire env vars, volumes, and networks
- Debug service startup and port conflicts
- Mirror production-like topology on a laptop
Docker Compose by the numbers
- 142 all-time installs (skills.sh)
- Ranked #467 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oimiragieo/agent-studio --skill docker-composeAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 142 |
|---|---|
| repo stars | ★ 36 |
| Last updated | July 14, 2026 |
| Repository | oimiragieo/agent-studio ↗ |
What it does
Scaffold, validate, and run multi-service local stacks via Docker Compose so agents can boot databases, APIs, and workers consistently before integration or end-to-end testing.
Files
Docker Compose Skill
Installation
The skill invokes docker compose. Easiest: install Docker Desktop (includes Docker Engine + Compose):
- Windows: Docker Desktop for Windows (WSL 2 or Hyper-V)
- Mac: Docker Desktop for Mac (Apple Silicon or Intel)
- Linux: Docker Desktop for Linux or Docker Engine + Compose plugin from Docker's repo
Verify: docker compose version
Cheat Sheet & Best Practices
Commands: docker compose up -d / down; docker compose ps / logs -f <service>; docker compose exec <service> sh; docker compose build --no-cache; docker compose -f compose.prod.yaml config — validate.
YAML: Use named volumes for DBs (postgres_data:/var/lib/postgresql/data). Use healthchecks (healthcheck: with test, interval, timeout, retries). One network default; reference services by name (e.g. http://api:3000). Use env_file or environment; keep secrets in secrets:.
Hacks: -f compose.yaml -f override.yaml merges files (later overrides). Use --project-name for isolation. Prefer build: context: . dockerfile: Dockerfile for dev; pin image tags in prod. Run docker compose config before up to catch errors.
Certifications & Training
Docker Certified Associate (DCA): Orchestration 25%, Image/Registry 20%, Install/Config 15%, Networking 15%, Security 15%, Storage 10%. Free: Official DCA Study Guide, Coursera DCA Prep (audit). Skill data: Compose YAML (services, volumes, networks, healthchecks), CLI (up/down/ps/logs/exec).
Hooks & Workflows
Suggested hooks: Pre-up: docker compose config (validate). Post-down: optional cleanup. Use when devops or devops-troubleshooter is routed.
Workflows: Use with devops (primary), devops-troubleshooter (primary). Flow: validate compose → up/down/exec per task. See operations/incident-response for container debugging.
Overview
This skill provides comprehensive Docker Compose management, enabling AI agents to orchestrate multi-container applications, manage services, inspect logs, and troubleshoot containerized environments with progressive disclosure for optimal context usage.
Context Savings: ~92% reduction
- MCP Mode: ~25,000 tokens always loaded (multiple tools + schemas)
- Skill Mode: ~700 tokens metadata + on-demand loading
When to Use
- Managing local development environments
- Orchestrating multi-container applications
- Debugging service connectivity and networking
- Monitoring container logs and health
- Building and updating service images
- Testing containerized application stacks
- Troubleshooting service failures
- Managing application lifecycle (start, stop, restart)
Requirements
- Docker Engine installed and running
- Docker Compose V2 (
docker composeplugin — V1docker-composeis end-of-life) - Valid
compose.yaml(preferred) orcompose.yml/docker-compose.ymlin project - Appropriate permissions for Docker socket access
Quick Reference
# List running services
docker compose ps
# View service logs
docker compose logs <service>
# Start services
docker compose up -d
# Stop services
docker compose down
# Rebuild services
docker compose build
# Execute command in container
docker compose exec <service> <command>
# Live development reloading (Compose Watch)
docker compose watch
# Start with a profile active
docker compose --profile debug up -d
# Validate merged config
docker compose config2026 Feature Highlights
compose.yaml — Canonical Filename
Docker Compose V2 prefers compose.yaml (and compose.yml) over the legacy docker-compose.yml. The version: top-level field is deprecated and should be omitted entirely in new files.
# compose.yaml (preferred — no version: field needed)
services:
web:
build: .
ports:
- '8080:80'
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: example
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Compose Watch — Live Development Reloading
Compose Watch (GA as of Compose 2.22+) replaces the manual rebuild-restart cycle during development. Configure a develop.watch block per service. Three actions are available:
| Action | Behavior |
|---|---|
sync | Instantly copies changed files into the running container |
rebuild | Triggers docker compose build + recreates the container |
sync+restart | Syncs files then restarts the container process (no full rebuild) |
services:
api:
build: .
ports:
- '3000:3000'
develop:
watch:
# Sync source instantly — no rebuild needed for interpreted code
- action: sync
path: ./src
target: /app/src
ignore:
- node_modules/
# Rebuild when dependency manifest changes
- action: rebuild
path: package.json
# Restart only when config changes
- action: sync+restart
path: ./config
target: /app/configStart with:
# Watch mode (keeps output in foreground)
docker compose watch
# Or combined with up
docker compose up --watchWhen to use each action:
sync— interpreted languages (Node.js, Python, Ruby) where the runtime picks up changessync+restart— config or template files that require a process restart but not a full rebuildrebuild— dependency manifest changes (package.json,requirements.txt,go.mod)
Profiles — Environment-Specific Services
Profiles allow a single compose.yaml to serve multiple environments. Services without a profile always start. Services with profiles only start when that profile is activated.
services:
# Always starts — no profile
api:
build: .
ports:
- '3000:3000'
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 3s
retries: 5
volumes:
- db_data:/var/lib/postgresql/data
# Only with --profile debug
pgadmin:
image: dpage/pgadmin4:latest
profiles: ['debug']
ports:
- '5050:80'
environment:
PGADMIN_DEFAULT_EMAIL: admin@admin.com
PGADMIN_DEFAULT_PASSWORD: admin
# Only with --profile monitoring
prometheus:
image: prom/prometheus:latest
profiles: ['monitoring']
ports:
- '9090:9090'
grafana:
image: grafana/grafana:latest
profiles: ['monitoring']
ports:
- '3001:3000'
volumes:
db_data:# Default: api + db only
docker compose up -d
# Debug: api + db + pgadmin
docker compose --profile debug up -d
# Monitoring: api + db + prometheus + grafana
docker compose --profile monitoring up -d
# Multiple profiles
docker compose --profile debug --profile monitoring up -d
# Via environment variable
COMPOSE_PROFILES=debug,monitoring docker compose up -dProfile naming rules: [a-zA-Z0-9][a-zA-Z0-9_.-]+ — lowercase kebab-case recommended.
Include — Composable Configs
The include top-level key (introduced in Compose 2.20) allows you to split large compose files into modular, team-owned pieces. Each included file is loaded with its own project directory context, resolving relative paths correctly.
# compose.yaml (root — application layer)
include:
- ./infra/compose.yaml # DB, Redis, message broker
- ./monitoring/compose.yaml # Prometheus, Grafana
services:
api:
build: .
depends_on:
- db # defined in infra/compose.yaml
- redis # defined in infra/compose.yaml# infra/compose.yaml (infrastructure layer — owned by platform team)
services:
db:
image: postgres:16-alpine
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 5s
timeout: 3s
retries: 5
volumes:
- db_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 3s
retries: 5
volumes:
db_data:include is recursive — included files can themselves include other files. Conflicts between resource names cause an error (no silent merging).
Healthcheck Best Practices
Always define healthchecks on stateful services so that depends_on: condition: service_healthy works correctly. Without healthchecks, dependent services may start before their dependency is ready.
services:
db:
image: postgres:16-alpine
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-postgres}']
interval: 10s # How often to check
timeout: 5s # Time to wait for response
retries: 5 # Failures before marking unhealthy
start_period: 30s # Grace period during container startup
redis:
image: redis:7-alpine
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 10s
timeout: 3s
retries: 3
api:
build: .
depends_on:
db:
condition: service_healthy # waits until db passes healthcheck
redis:
condition: service_healthyHealthcheck guidelines:
- Use
CMD(array form) notCMD-SHELL(string form) where possible — avoids shell injection risk - Use
CMD-SHELLonly when you need shell features (pg_isready,curl -f, etc.) - Set
start_periodfor services with slow startup (JVM apps, first-run migrations) - Avoid
curlin Alpine-based images unless explicitly installed; preferwget -q --spideror native checks - For HTTP services:
test: ["CMD-SHELL", "wget -q --spider http://localhost:3000/health || exit 1"]
Multi-Stage Build Pattern
Use multi-stage Dockerfiles to keep production images minimal and secure. Reference the specific build stage in compose.yaml for development.
# Dockerfile
# Stage 1: deps — install dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
# Stage 2: builder — compile/transpile
FROM deps AS builder
COPY . .
RUN npm run build
# Stage 3: runner — minimal production image
FROM node:20-alpine AS runner
RUN addgroup -g 1001 -S appgroup && adduser -S -u 1001 -G appgroup appuser
WORKDIR /app
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=deps --chown=appuser:appgroup /app/node_modules ./node_modules
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD wget -q --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/index.js"]# compose.yaml — dev targets the builder stage for faster iteration
services:
api:
build:
context: .
dockerfile: Dockerfile
target: builder # Stop at builder stage in dev (includes devDeps)
develop:
watch:
- action: sync
path: ./src
target: /app/src
ignore:
- node_modules/
- action: rebuild
path: package.json# compose.prod.yaml — production uses the full runner stage
services:
api:
build:
context: .
dockerfile: Dockerfile
target: runner # Minimal, non-root production image
restart: unless-stoppedResource Limits (Best Practice)
Always define resource limits to prevent container resource exhaustion:
services:
api:
image: myapp:latest
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
restart: unless-stoppedTools
The skill provides 15 tools across service management, monitoring, build operations, and troubleshooting categories:
Service Management (5 tools)
up
Start services defined in compose.yaml.
| Parameter | Type | Description | Default |
|---|---|---|---|
detached | boolean | Run in detached mode | true |
build | boolean | Build images before starting | false |
force_recreate | boolean | Recreate containers | false |
project_name | string | Project name override | directory name |
services | array | Specific services to start | all services |
profiles | array | Profiles to activate | none |
watch | boolean | Enable Compose Watch mode | false |
Example:
docker compose up -d
docker compose up --build
docker compose up web api
docker compose --profile debug up -d
docker compose up --watchSafety: Requires confirmation for production environments.
down
Stop and remove containers, networks, volumes.
| Parameter | Type | Description | Default |
|---|---|---|---|
volumes | boolean | Remove volumes (BLOCKED) | false |
remove_orphans | boolean | Remove orphaned containers | false |
project_name | string | Project name override | directory name |
Example:
docker compose down
docker compose down --remove-orphansSafety: Volume removal (-v flag) is BLOCKED by default. Requires confirmation.
start
Start existing containers without recreating them.
| Parameter | Type | Description | Default |
|---|---|---|---|
services | array | Specific services to start | all services |
project_name | string | Project name override | directory name |
Example:
docker compose start
docker compose start webstop
Stop running containers without removing them.
| Parameter | Type | Description | Default |
|---|---|---|---|
timeout | number | Shutdown timeout (seconds) | 10 |
services | array | Specific services to stop | all services |
project_name | string | Project name override | directory name |
Example:
docker compose stop
docker compose stop --timeout 30 webrestart
Restart services (stop + start).
| Parameter | Type | Description | Default |
|---|---|---|---|
timeout | number | Shutdown timeout (seconds) | 10 |
services | array | Specific services to restart | all services |
project_name | string | Project name override | directory name |
Example:
docker compose restart
docker compose restart apiStatus & Logs (3 tools)
ps
List containers with status information.
| Parameter | Type | Description | Default |
|---|---|---|---|
all | boolean | Show all containers (including stopped) | false |
services | array | Filter by services | all services |
project_name | string | Project name override | directory name |
Example:
docker compose ps
docker compose ps --allOutput Fields: NAME, IMAGE, STATUS, PORTS
logs
View service logs with streaming support.
| Parameter | Type | Description | Default |
|---|---|---|---|
services | array | Services to view logs for | all services |
follow | boolean | Follow log output (stream) | false |
tail | number | Number of lines to show | 100 |
timestamps | boolean | Show timestamps | false |
since | string | Show logs since timestamp/duration | none |
project_name | string | Project name override | directory name |
Example:
docker compose logs web
docker compose logs --tail 50 --follow api
docker compose logs --since "2026-01-01T10:00:00"Note: Follow mode automatically terminates after 60 seconds to prevent indefinite streaming.
top
Display running processes in containers.
| Parameter | Type | Description | Default |
|---|---|---|---|
services | array | Services to inspect | all services |
project_name | string | Project name override | directory name |
Example:
docker compose top
docker compose top webOutput: Process list with PID, USER, TIME, COMMAND
Build & Images (3 tools)
build
Build or rebuild service images.
| Parameter | Type | Description | Default |
|---|---|---|---|
no_cache | boolean | Build without cache | false |
pull | boolean | Pull newer image versions | false |
parallel | boolean | Build in parallel | true |
services | array | Services to build | all services |
project_name | string | Project name override | directory name |
Example:
docker compose build
docker compose build --no-cache web
docker compose build --pullSafety: Requires confirmation for no-cache builds (resource-intensive).
pull
Pull service images from registry.
| Parameter | Type | Description | Default |
|---|---|---|---|
ignore_pull_failures | boolean | Continue if pull fails | false |
services | array | Services to pull | all services |
project_name | string | Project name override | directory name |
Example:
docker compose pull
docker compose pull web apiSafety: Requires confirmation for production environments.
images
List images used by services.
| Parameter | Type | Description | Default |
|---|---|---|---|
project_name | string | Project name override | directory name |
Example:
docker compose imagesOutput Fields: CONTAINER, REPOSITORY, TAG, IMAGE ID, SIZE
Execution (2 tools)
exec
Execute a command in a running container.
| Parameter | Type | Description | Required |
|---|---|---|---|
service | string | Service name | Yes |
command | array | Command to execute | Yes |
user | string | User to execute as | container default |
workdir | string | Working directory | container default |
env | object | Environment variables | none |
project_name | string | Project name override | directory name |
Example:
docker compose exec web bash
docker compose exec -u root api ls -la /app
docker compose exec db psql -U postgresSafety:
- Destructive commands (
rm -rf,dd,mkfs) are BLOCKED - Root user execution requires confirmation
- Default timeout: 30 seconds
run
Run a one-off command in a new container.
| Parameter | Type | Description | Default |
|---|---|---|---|
service | string | Service to run | Required |
command | array | Command to execute | service default |
rm | boolean | Remove container after run | true |
no_deps | boolean | Don't start linked services | false |
user | string | User to execute as | container default |
env | object | Environment variables | none |
project_name | string | Project name override | directory name |
Example:
docker compose run --rm web npm test
docker compose run --no-deps api python manage.py migrateSafety: Requires confirmation for commands that modify data.
Configuration (2 tools)
config
Validate and view the Compose file configuration.
| Parameter | Type | Description | Default |
|---|---|---|---|
resolve_image_digests | boolean | Pin image tags to digests | false |
no_interpolate | boolean | Don't interpolate env vars | false |
project_name | string | Project name override | directory name |
Example:
docker compose config
docker compose config --resolve-image-digestsOutput: Parsed and merged Compose configuration
port
Print the public port binding for a service port.
| Parameter | Type | Description | Required |
|---|---|---|---|
service | string | Service name | Yes |
private_port | number | Container port | Yes |
protocol | string | Protocol (tcp/udp) | tcp |
project_name | string | Project name override | directory name |
Example:
docker compose port web 80
docker compose port db 5432Output: <host>:<port> binding
Common Workflows
Start a Development Environment
# 1. Validate configuration
docker compose config
# 2. Pull latest images
docker compose pull
# 3. Build custom images
docker compose build
# 4. Start services in detached mode
docker compose up -d
# 5. Check service status
docker compose ps
# 6. View logs
docker compose logs --tail 100Live Development with Compose Watch
# 1. Ensure develop.watch blocks are configured in compose.yaml
# 2. Start with watch mode (foreground, shows sync events)
docker compose watch
# 3. Or start detached then watch
docker compose up -d
docker compose watch --no-upTroubleshoot a Failing Service
# 1. Check container status
docker compose ps --all
# 2. View service logs
docker compose logs --tail 200 failing-service
# 3. Inspect running processes
docker compose top failing-service
# 4. Check configuration
docker compose config
# 5. Restart the service
docker compose restart failing-service
# 6. If needed, recreate container
docker compose up -d --force-recreate failing-serviceUpdate Service Images
# 1. Pull latest images
docker compose pull
# 2. Stop services
docker compose down
# 3. Rebuild if using custom Dockerfiles
docker compose build --pull
# 4. Start with new images
docker compose up -d
# 5. Verify services
docker compose psDebug Service Connectivity
# 1. Check running services
docker compose ps
# 2. Inspect port mappings
docker compose port web 80
docker compose port api 3000
# 3. Exec into container
docker compose exec web sh
# 4. Test connectivity (from inside container)
docker compose exec web curl api:3000/health
# 5. Check logs for errors
docker compose logs web apiClean Up Environment
# 1. Stop all services
docker compose down
# 2. Remove orphaned containers
docker compose down --remove-orphans
# 3. View images
docker compose images
# 4. Clean up (manual - volume removal BLOCKED)
# Volumes require manual cleanup with explicit confirmationUse Profiles for Environment-Specific Services
# Development: default services only
docker compose up -d
# Development + debug tools
docker compose --profile debug up -d
# Start monitoring stack
docker compose --profile monitoring up -d
# Via env var (useful in CI)
COMPOSE_PROFILES=monitoring docker compose up -d
# Stop and clean a specific profile
docker compose --profile debug downConfiguration
Environment Variables
| Variable | Description | Default |
|---|---|---|
COMPOSE_PROJECT_NAME | Default project name | directory name |
COMPOSE_FILE | Compose file path | compose.yaml |
COMPOSE_PROFILES | Comma-separated active profiles | (none) |
COMPOSE_PATH_SEPARATOR | Path separator for multiple files | : (Linux/Mac), ; (Windows) |
DOCKER_HOST | Docker daemon socket | unix:///var/run/docker.sock |
COMPOSE_HTTP_TIMEOUT | HTTP timeout for API calls | 60 |
COMPOSE_PARALLEL_LIMIT | Max parallel operations | unlimited |
Setup
1. Install Docker Engine:
# macOS
brew install --cask docker
# Linux (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Windows
# Download Docker Desktop from docker.com2. Verify Docker Compose:
# Check Docker version
docker --version
# Check Compose version (must be V2, e.g. 2.24+)
docker compose version3. Create compose.yaml (no version: field — V2 does not require it):
services:
web:
build: .
ports:
- '8080:80'
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: example
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U postgres']
interval: 10s
timeout: 5s
retries: 54. Test the skill:
docker compose config
docker compose psSafety Features
Blocked Operations
The following operations are BLOCKED by default to prevent accidental data loss:
- Volume removal:
docker compose down -v(BLOCKED - requires manual confirmation) - Full cleanup:
docker compose down -v --rmi all(BLOCKED - extremely destructive) - Destructive exec:
rm -rf,dd,mkfs,sudo rminside containers (BLOCKED) - Force removal:
docker compose rm -f(BLOCKED - use stop then rm)
Confirmation Required
These operations require explicit confirmation:
- Building with
--no-cache(resource-intensive) - Pulling images in production environments
- Starting services with
--force-recreate - Executing commands as root user
- Running commands that modify databases
- Stopping services with very short timeouts
Auto-Terminating Operations
The following operations auto-terminate to prevent resource issues:
- Log following (
--follow): 60-second timeout - Service execution (
exec): 30-second timeout - One-off commands (
run): 60-second timeout
Error Handling
Common Errors:
| Error | Cause | Fix |
|---|---|---|
docker: command not found | Docker not installed | Install Docker Engine |
Cannot connect to Docker daemon | Docker not running | Start Docker service |
network ... not found | Network cleanup issue | Run docker compose down then up |
port is already allocated | Port conflict | Change port mapping or stop conflicting service |
no configuration file provided | Missing compose file | Create compose.yaml |
service ... must be built | Image not built | Run docker compose build |
service unhealthy | Healthcheck failing | Check docker compose logs <service> |
include path not found | Missing included file | Verify paths in include: block |
Recovery:
- Validate configuration:
docker compose config - Check Docker status:
docker info - View service logs:
docker compose logs - Force recreate:
docker compose up -d --force-recreate - Clean restart:
docker compose down && docker compose up -d
Integration with Agents
This skill integrates with the following agents:
Primary Agents
- devops: Local development, CI/CD integration, container orchestration
- developer: Application development, testing, debugging
Secondary Agents
- qa: Integration testing, test environment setup
- incident-responder: Debugging production issues, service recovery
- cloud-integrator: Cloud deployment, migration to Kubernetes
- performance-engineer: Performance testing, resource optimization
Progressive Disclosure
The skill uses progressive disclosure to minimize context usage:
1. Initial Load: Only metadata and tool names (~700 tokens) 2. Tool Invocation: Specific tool schema loaded on-demand (~100-150 tokens) 3. Result Streaming: Large outputs (logs) streamed incrementally 4. Context Cleanup: Old results cleared after use
Context Optimization:
- Use
--tailto limit log output - Use service filters to target specific containers
- Prefer
psoverps --allfor active services only - Use
--sincefor time-bounded log queries
Troubleshooting
Skill Issues
Docker Compose not found:
# Check Docker Compose version
docker compose version
# V1 (docker-compose) is end-of-life — upgrade to V2
# Docker Compose V2 is integrated into Docker CLI as a pluginPermission denied:
# Add user to docker group (Linux)
sudo usermod -aG docker $USER
newgrp docker
# Verify permissions
docker psCompose file issues:
# Validate syntax
docker compose config
# Check for errors (quiet mode — exit code only)
docker compose config -q
# View resolved configuration
docker compose config --resolve-image-digestsNetwork issues:
# List networks
docker network ls
# Remove unused networks
docker network prune
# Recreate services
docker compose down
docker compose up -dHealthcheck failures:
# Inspect healthcheck status
docker inspect <container_id> | grep -A 10 Health
# View healthcheck output
docker compose logs <service>
# Manually run the healthcheck command
docker compose exec <service> pg_isready -U postgresCompose Watch not syncing:
# Verify develop.watch block is present in compose.yaml
docker compose config | grep -A 20 develop
# Ensure Compose version is 2.22+
docker compose version
# Watch requires build: attribute (not image: only)Performance Considerations
- Build caching: Use layer caching for faster builds; avoid
--no-cacheunless necessary - Multi-stage builds: Dramatically reduce production image size (often 80%+)
- Parallel operations: Docker Compose V2 parallelizes by default; use
COMPOSE_PARALLEL_LIMITto control - Resource limits: Define CPU/memory limits in compose file to prevent resource exhaustion
- Log rotation: Use logging drivers to prevent disk space issues
- Volume cleanup: Regularly clean unused volumes (requires manual confirmation)
- Compose Watch vs bind mounts: Prefer
develop.watchfor cross-platform development; bind mounts have I/O performance issues on macOS/Windows
Related
- Docker Compose Documentation: <https://docs.docker.com/compose/>
- Compose File Reference: <https://docs.docker.com/compose/compose-file/>
- Compose Watch Docs: <https://docs.docker.com/compose/how-tos/file-watch/>
- Compose Profiles Docs: <https://docs.docker.com/compose/how-tos/profiles/>
- Compose Include Docs: <https://docs.docker.com/compose/how-tos/multiple-compose-files/include/>
- Docker CLI: <https://docs.docker.com/engine/reference/commandline/cli/>
- Kubernetes Migration:
.claude/skills/kubernetes-flux/(Kubernetes orchestration)
Sources
- Docker Compose Documentation
- Docker Compose V2
- Compose Specification
- Docker Best Practices
- Use Compose Watch
- Use Compose Profiles
- Compose Include Directive
Related Skills
- `cloud-devops-expert` - Cloud platforms (AWS, GCP, Azure) and Terraform infrastructure
Iron Laws
1. ALWAYS use docker compose (V2 plugin) — never use docker-compose (V1 standalone), which is deprecated and will be removed. 2. NEVER include secrets or credentials directly in compose files or committed .env files — use external secret management or .env.example templates for documentation only. 3. ALWAYS define health checks on services that other services depend on — without health checks, dependent services start before their dependencies are actually ready. 4. NEVER expose a service port to the host unless it must be accessed from outside the compose network — unnecessary host port exposure increases attack surface. 5. ALWAYS specify resource limits (CPU and memory) on services intended for production — unlimited containers can starve other services and crash the host.
Anti-Patterns
| Anti-Pattern | Why It Fails | Correct Approach |
|---|---|---|
Using docker-compose V1 command | V1 is deprecated; missing V2 features (profiles, merge, watch) and will be removed | Use docker compose (space, not hyphen); verify docker compose version |
| Hardcoded secrets in compose file | Secrets committed to git are permanently exposed in history | Use environment variable references (${SECRET}) loaded from untracked .env |
| No health checks on database/cache services | App containers start before DB is ready; causes startup race conditions and crashes | Add healthcheck: with appropriate test commands; use depends_on: condition: service_healthy |
Exposing all ports to host (0.0.0.0) | Services accessible from any network interface including public interfaces | Bind to 127.0.0.1 for dev; use internal networks for service-to-service communication |
| No restart policy | Containers stay down after crash or host reboot in production | Use restart: unless-stopped for services that should auto-recover |
Memory Protocol (MANDATORY)
Before starting: Read .claude/context/memory/learnings.md
After completing:
- New pattern ->
.claude/context/memory/learnings.md - Issue found ->
.claude/context/memory/issues.md - Decision made ->
.claude/context/memory/decisions.md
ASSUME INTERRUPTION: If it's not in memory, it didn't happen.
Invoke the docker-compose skill and follow it exactly as presented to you
#!/usr/bin/env node
/**
* docker-compose - Post-Execute Hook
* Runs after the skill executes for cleanup, logging, or follow-up actions.
*/
const fs = require('fs');
const path = require('path');
const { safeParseJSON } = require('../../../lib/utils/safe-json.cjs');
// Parse hook input
const result = safeParseJSON(process.argv[2] || '{}');
console.log('📝 [DOCKER-COMPOSE] Post-execute processing...');
/**
* Process execution result
*/
function processResult(_result) {
// TODO: Add your post-processing logic here
return { success: true };
}
// Run post-processing
const outcome = processResult(result);
if (outcome.success) {
console.log('✅ [DOCKER-COMPOSE] Post-processing complete');
process.exit(0);
} else {
console.error('⚠️ [DOCKER-COMPOSE] Post-processing had issues');
process.exit(0);
}
#!/usr/bin/env node
/**
* docker-compose - Pre-Execute Hook
* Runs before the skill executes to validate input or prepare context.
*/
const fs = require('fs');
const path = require('path');
const { safeParseJSON } = require('../../../lib/utils/safe-json.cjs');
// Parse hook input
const input = safeParseJSON(process.argv[2] || '{}');
console.log('🔍 [DOCKER-COMPOSE] Pre-execute validation...');
/**
* Validate input before execution
*/
function validateInput(_input) {
const errors = [];
// TODO: Add your validation logic here
return errors;
}
// Run validation
const errors = validateInput(input);
if (errors.length > 0) {
console.error('❌ Validation failed:');
errors.forEach(e => console.error(' - ' + e));
process.exit(1);
}
console.log('✅ [DOCKER-COMPOSE] Validation passed');
process.exit(0);
docker-compose Research Requirements
Generated: 2026-02-28
Skill Description
Docker Compose container orchestration and management. Manage multi-container applications, services, networks, and volumes. Use for local development, testing, and orchestration of containerized applications.
Research Areas
- Current best practices for docker-compose
- Industry standards and tooling
- Integration patterns
Source References
- To be populated by skill-updater research phase
docker-compose Rules
Purpose
Docker Compose container orchestration and management. Manage multi-container applications, services, networks, and volumes. Use for local development, testing, and orchestration of containerized applications.
Best Practices
- Prefer compose.yaml (canonical V2 name) over docker-compose.yml
- Use
docker compose(V2 plugin) neverdocker-compose(V1 binary) - Verify compose.yaml exists before operations
- Use project names for isolation
- Check service status before destructive operations
- Avoid volume removal without confirmation
- Review logs before restarting failed services
- Define healthchecks on all stateful services
- Use profiles for environment-specific services
- Use watch + develop block for live development reloading
Integration Points
See SKILL.md for complete documentation.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "docker-compose Input Schema",
"description": "Input validation schema for docker-compose skill",
"type": "object",
"required": [],
"properties": {},
"additionalProperties": true
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "docker-compose Output Schema",
"description": "Output validation schema for docker-compose skill",
"type": "object",
"required": ["success"],
"properties": {
"success": {
"type": "boolean",
"description": "Whether the skill executed successfully"
},
"result": {
"type": "object",
"description": "The skill execution result",
"additionalProperties": true
},
"error": {
"type": "string",
"description": "Error message if execution failed"
}
},
"additionalProperties": true
}
#!/usr/bin/env node
/**
* Docker Compose - Main Script
* Docker Compose container orchestration and management. Manage multi-container applications, services, networks, and volumes. Use for local development, testing, and orchestration of containerized applications.
*
* Usage:
* node main.cjs [options]
*
* Options:
* --help Show this help message
*/
const fs = require('fs');
const path = require('path');
// Find project root
function findProjectRoot() {
let dir = __dirname;
while (dir !== path.parse(dir).root) {
if (fs.existsSync(path.join(dir, '.claude'))) {
return dir;
}
dir = path.dirname(dir);
}
return process.cwd();
}
const PROJECT_ROOT = findProjectRoot();
// Parse command line arguments
const args = process.argv.slice(2);
const options = {};
for (let i = 0; i < args.length; i++) {
if (args[i].startsWith('--')) {
const key = args[i].slice(2);
const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[++i] : true;
options[key] = value;
}
}
/**
* Main execution
*/
function main() {
if (options.help) {
console.log(`
Docker Compose - Main Script
Usage:
node main.cjs [options]
Options:
--help Show this help message
`);
process.exit(0);
}
const { spawn } = require('child_process');
const composeArgs = args.filter(a => a !== '--help');
const child = spawn('docker', ['compose', ...composeArgs], {
stdio: 'inherit',
cwd: PROJECT_ROOT,
shell: false,
windowsHide: true,
});
child.on('close', (code, signal) => {
if (code === 127)
console.error(
'Docker not found. Install: see this skill\'s SKILL.md, section "Installation".'
);
if (code !== null && code !== undefined) process.exit(code);
if (signal) process.exit(1);
process.exit(0);
});
}
main();
docker-compose Implementation Template
Goal
- Define target outcome and acceptance criteria.
TDD
1. Red 2. Green 3. Refactor
Verification
- lint
- format
- targeted tests