How to Manage Multi-Container Apps with Docker Compose Profiles
Docker Compose profiles allow you to selectively start groups of services from a single compose file. Instead of maintaining separate compose files for development, testing, and production, you can define profiles that include or exclude services based on the deployment context. This is particularly useful for managing complex applications on your Breeze server.
Understanding Profiles
Services without a profile are always started. Services assigned to one or more profiles only start when that profile is explicitly activated:
services:
# Always starts (no profile assigned)
app:
image: myapp:latest
ports:
- "8080:8080"
depends_on:
- db
# Always starts (no profile assigned)
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${DB_PASS}
# Only starts with "dev" profile
adminer:
image: adminer:latest
profiles: ["dev"]
ports:
- "8081:8080"
# Only starts with "dev" profile
mailhog:
image: mailhog/mailhog:latest
profiles: ["dev"]
ports:
- "1025:1025"
- "8025:8025"
# Only starts with "monitoring" profile
prometheus:
image: prom/prometheus:latest
profiles: ["monitoring"]
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
# Only starts with "monitoring" profile
grafana:
image: grafana/grafana:latest
profiles: ["monitoring"]
ports:
- "3000:3000"
# Starts with either "testing" or "dev" profile
test-runner:
image: myapp:latest
profiles: ["testing", "dev"]
command: ["npm", "test"]
depends_on:
- db
volumes:
pgdata:
Activating Profiles
# Start only default services (app + db)
docker compose up -d
# Start with development tools
docker compose --profile dev up -d
# Start with monitoring stack
docker compose --profile monitoring up -d
# Combine multiple profiles
docker compose --profile dev --profile monitoring up -d
# Run tests
docker compose --profile testing run --rm test-runner
Using Environment Variables for Profiles
Set profiles via environment variable so you do not need to pass them every time:
# In your .env file
COMPOSE_PROFILES=dev,monitoring
# Now just run:
docker compose up -d
# Automatically activates dev and monitoring profiles
Profile-Specific Environment Files
Create separate .env files for each environment:
# .env.development
COMPOSE_PROFILES=dev
DB_PASS=devpassword
APP_DEBUG=true
# .env.production
COMPOSE_PROFILES=monitoring
DB_PASS=ProductionSecurePass!
APP_DEBUG=false
# Use with --env-file flag
docker compose --env-file .env.development up -d
docker compose --env-file .env.production up -d
Stopping Profile-Specific Services
# Stop only monitoring services
docker compose --profile monitoring down
# Stop everything including profiled services
docker compose --profile dev --profile monitoring down
Real-World Example: Full Application Stack
Here is a comprehensive example for a web application on your Breeze server:
services:
nginx:
image: nginx:alpine
ports: ["80:80", "443:443"]
volumes: ["./nginx.conf:/etc/nginx/nginx.conf:ro"]
api:
build: ./api
environment: ["DATABASE_URL=postgres://user:${DB_PASS}@db/app"]
worker:
build: ./worker
profiles: ["workers"]
deploy:
replicas: 3
db:
image: postgres:16
volumes: ["pgdata:/var/lib/postgresql/data"]
redis:
image: redis:7-alpine
seed:
build: ./api
profiles: ["setup"]
command: ["node", "seed.js"]
depends_on: [db]
Best Practices
- Keep core services profile-free so they always start regardless of environment
- Group related optional services under the same profile name
- Use
COMPOSE_PROFILESin.envfiles for per-environment defaults - A service can belong to multiple profiles for flexible activation
- Use profiles for development tools, monitoring, testing, and one-off tasks
- Document available profiles in your project for team visibility
Docker Compose profiles simplify multi-environment management on your Breeze server by keeping everything in a single, well-organized compose file.