01What Profiles Solve
Not every service needs to run in every environment. You might want debugging tools in development but not production, or optional monitoring that's off by default. Profiles let you define service groups that only start when explicitly requested.
02Defining Profiles
Add a profiles key to any service. Services with profiles won't start by default—you must explicitly enable their profile. Services without profiles always start.
1services: 2 # Always starts (no profile)3 app: 4 image: myapp:latest5 ports: 6 - "8080:8080"78 # Always starts (no profile)9 db: 10 image: postgres:16-alpine11 volumes: 12 - db_data:/var/lib/postgresql/data1314 # Only starts with --profile debug15 debugger: 16 image: busybox17 profiles: ["debug"]18 command: sleep infinity1920 # Only starts with --profile monitoring21 prometheus: 22 image: prom/prometheus:latest23 profiles: ["monitoring"]24 ports: 25 - "9090:9090"2627 # Starts with EITHER debug OR monitoring profile28 grafana: 29 image: grafana/grafana:latest30 profiles: ["debug", "monitoring"]31 ports: 32 - "3000:3000"3334volumes: 35 db_data: A service can belong to multiple profiles. It starts if ANY of its profiles are activated.
03Running with Profiles
Use the --profile flag (repeatable) or COMPOSE_PROFILES environment variable to activate profiles.
1# Start only default services (app, db)2docker compose up -d34# Start default + debug services5docker compose --profile debug up -d67# Start default + monitoring services8docker compose --profile monitoring up -d910# Start multiple profiles11docker compose --profile debug --profile monitoring up -d1213# Using environment variable14export COMPOSE_PROFILES=debug,monitoring15docker compose up -d1617# In .env file18COMPOSE_PROFILES=monitoring04Development vs Production Profiles
A common pattern: development tools in dev profile, production optimizations in prod profile.
1services: 2 app: 3 image: myapp:latest4 ports: 5 - "8080:8080"6 environment: 7 - DEBUG=${DEBUG:-false}89 db: 10 image: postgres:16-alpine1112 # Development tools13 mailhog: 14 image: mailhog/mailhog15 profiles: ["dev"]16 ports: 17 - "1025:1025" # SMTP18 - "8025:8025" # Web UI1920 adminer: 21 image: adminer22 profiles: ["dev"]23 ports: 24 - "8081:8080"2526 # Production services27 redis: 28 image: redis:alpine29 profiles: ["prod"]3031 nginx: 32 image: nginx:alpine33 profiles: ["prod"]34 ports: 35 - "80:80"36 - "443:443"37 volumes: 38 - ./nginx.conf:/etc/nginx/nginx.conf:roRun with profile: docker compose --profile dev up -d (development) or docker compose --profile prod up -d (production)
05Profiles and Dependencies
When a profiled service depends on another profiled service, both profiles must be active. Be careful with cross-profile dependencies.
1services: 2 app: 3 image: myapp:latest4 depends_on: 5 - db67 db: 8 image: postgres:16-alpine910 # This won't work without the monitoring profile active11 grafana: 12 image: grafana/grafana13 profiles: ["monitoring"]14 depends_on: 15 - prometheus1617 prometheus: 18 image: prom/prometheus19 profiles: ["monitoring"]2021 # Better: depend on non-profiled services when possible22 metrics-exporter: 23 image: prom/node-exporter24 profiles: ["monitoring"]25 # No dependency on prometheus - works independentlyIf service A (profile: debug) depends on service B (profile: monitoring), you must enable BOTH profiles or A won't start.
06Practical Profile Patterns
Real-world profile configurations for common scenarios.
1services: 2 app: 3 image: myapp:latest45 db: 6 image: postgres:16-alpine78 # Testing: Run integration tests9 test-runner: 10 image: myapp:latest11 profiles: ["test"]12 command: pytest13 depends_on: 14 - db1516 # Seeding: Load sample data17 seeder: 18 image: myapp:latest19 profiles: ["seed"]20 command: python seed_data.py21 depends_on: 22 - db2324 # Backup: On-demand database backup25 backup: 26 image: postgres:16-alpine27 profiles: ["backup"]28 volumes: 29 - ./backups:/backups30 command: pg_dump -h db -U postgres mydb > /backups/backup.sql31 depends_on: 32 - db3334 # Debugging: Interactive shell35 shell: 36 image: myapp:latest37 profiles: ["shell"]38 stdin_open: true39 tty: true40 command: /bin/bash41 depends_on: 42 - dbRun these profiles on-demand: --profile test for tests, --profile seed for seeding, --profile backup for backups, --profile shell for interactive access.