mirror of
https://github.com/BagelHole/DevOps-Security-Agent-Skills.git
synced 2026-08-22 12:49:53 +02:00
459 lines
7.9 KiB
Markdown
459 lines
7.9 KiB
Markdown
---
|
|||
|
|
name: docker-compose
|
||
|
|
description: Define and run multi-container Docker applications using Docker Compose. Create compose files, manage service dependencies, configure networks and volumes, and orchestrate local development environments. Use when setting up multi-service applications or development environments.
|
||
|
|
license: MIT
|
||
|
|
metadata:
|
||
|
|
author: devops-skills
|
||
|
|
version: "1.0"
|
||
|
|
---
|
||
|
|
|
||
|
|
# 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
|
||
|
|
- Creating reproducible development setups
|
||
|
|
|
||
|
|
## Prerequisites
|
||
|
|
|
||
|
|
- Docker Engine with Compose plugin (v2)
|
||
|
|
- Basic Docker knowledge
|
||
|
|
- YAML syntax understanding
|
||
|
|
|
||
|
|
## Basic Configuration
|
||
|
|
|
||
|
|
### Simple Application Stack
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# docker-compose.yml
|
||
|
|
version: '3.8'
|
||
|
|
|
||
|
|
services:
|
||
|
|
web:
|
||
|
|
build: .
|
||
|
|
ports:
|
||
|
|
- "3000:3000"
|
||
|
|
environment:
|
||
|
|
- NODE_ENV=development
|
||
|
|
- DATABASE_URL=postgres://postgres:secret@db:5432/myapp
|
||
|
|
depends_on:
|
||
|
|
- db
|
||
|
|
- redis
|
||
|
|
|
||
|
|
db:
|
||
|
|
image: postgres:15-alpine
|
||
|
|
environment:
|
||
|
|
POSTGRES_USER: postgres
|
||
|
|
POSTGRES_PASSWORD: secret
|
||
|
|
POSTGRES_DB: myapp
|
||
|
|
volumes:
|
||
|
|
- postgres-data:/var/lib/postgresql/data
|
||
|
|
ports:
|
||
|
|
- "5432:5432"
|
||
|
|
|
||
|
|
redis:
|
||
|
|
image: redis:7-alpine
|
||
|
|
ports:
|
||
|
|
- "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:
|
||
|
|
- "3000:3000" # HOST:CONTAINER
|
||
|
|
- "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:
|
||
|
|
- "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
|
||
|
|
|
||
|
|
# Stop and remove everything including volumes
|
||
|
|
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
|
||
|
|
```
|
||
|
|
|
||
|
|
### Hot Reload Setup
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
services:
|
||
|
|
web:
|
||
|
|
build:
|
||
|
|
context: .
|
||
|
|
target: development
|
||
|
|
volumes:
|
||
|
|
- ./src:/app/src
|
||
|
|
- /app/node_modules
|
||
|
|
environment:
|
||
|
|
- CHOKIDAR_USEPOLLING=true
|
||
|
|
command: npm run dev
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Patterns
|
||
|
|
|
||
|
|
### Database Initialization
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
services:
|
||
|
|
db:
|
||
|
|
image: postgres:15
|
||
|
|
volumes:
|
||
|
|
- postgres-data:/var/lib/postgresql/data
|
||
|
|
- ./init-scripts:/docker-entrypoint-initdb.d:ro
|
||
|
|
environment:
|
||
|
|
POSTGRES_DB: myapp
|
||
|
|
```
|
||
|
|
|
||
|
|
### Reverse Proxy
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
services:
|
||
|
|
proxy:
|
||
|
|
image: traefik:v3.0
|
||
|
|
ports:
|
||
|
|
- "80:80"
|
||
|
|
- "443:443"
|
||
|
|
volumes:
|
||
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||
|
|
- ./traefik.yml:/etc/traefik/traefik.yml:ro
|
||
|
|
|
||
|
|
web:
|
||
|
|
labels:
|
||
|
|
- "traefik.enable=true"
|
||
|
|
- "traefik.http.routers.web.rule=Host(`app.localhost`)"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Common Issues
|
||
|
|
|
||
|
|
### Issue: Container Cannot Resolve Service Name
|
||
|
|
**Problem**: Service can't connect to another service by name
|
||
|
|
**Solution**: Ensure services are on the same network, check depends_on
|
||
|
|
|
||
|
|
### Issue: Volume Permissions
|
||
|
|
**Problem**: Container can't write to mounted volume
|
||
|
|
**Solution**: Match container user UID with host, or use named volumes
|
||
|
|
|
||
|
|
### Issue: Port Already in Use
|
||
|
|
**Problem**: Error binding to port
|
||
|
|
**Solution**: Change host port or stop conflicting service
|
||
|
|
|
||
|
|
### Issue: Changes Not Reflected
|
||
|
|
**Problem**: Code changes don't appear in container
|
||
|
|
**Solution**: Check volume mounts, rebuild if Dockerfile changed
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
- Use named volumes for persistent data
|
||
|
|
- Define healthchecks for database dependencies
|
||
|
|
- Use profiles to separate optional services
|
||
|
|
- Keep secrets in .env files (not committed)
|
||
|
|
- Use override files for environment-specific config
|
||
|
|
- Pin image versions for reproducibility
|
||
|
|
- Use networks to isolate service groups
|
||
|
|
- Leverage watch mode for development
|
||
|
|
|
||
|
|
## Related Skills
|
||
|
|
|
||
|
|
- [docker-management](../docker-management/) - Docker fundamentals
|
||
|
|
- [kubernetes-ops](../../orchestration/kubernetes-ops/) - Production orchestration
|
||
|
|
- [reverse-proxy](../../../infrastructure/networking/reverse-proxy/) - Production routing
|