Stage 4 · Provision
Docker Compose
Profiles & Overrides
Use Compose profiles, override files, extension fields, and project names for flexible setups.
Compose Profiles
Profiles let you selectively start services. Services without a profile always start. Services with a profile only start when you activate that profile. This is useful for dev tools, debug utilities, and optional services.
services:
api:
image: myapp
# No profile — always starts
db:
image: postgres:16-alpine
# No profile — always starts
adminer:
image: adminer:latest
profiles:
- debug
test-runner:
image: myapp-test
profiles:
- test
profiler:
image: myapp-profiler
profiles:
- debug
- testdocker compose up starts only api and db. docker compose --profile debug up starts api, db, adminer, and profiler. You can activate multiple profiles.
# Start default services only
docker compose up
# Start with debug tools
docker compose --profile debug up
# Start with test tools
docker compose --profile test up
# Start everything
docker compose --profile debug --profile test up
# Or use COMPOSE_PROFILES environment variable
COMPOSE_PROFILES=debug docker compose upProfiles are a clean way to keep development tools out of your production configuration while still having them available when needed.
Override Files
Override files let you customize a base Compose configuration for different environments. The -f flag specifies multiple files. Compose merges them in order, with later files overriding earlier ones.
# Base configuration
docker compose -f compose.yaml up
# Base + production overrides
docker compose -f compose.yaml -f compose.prod.yaml up
# Base + local overrides
docker compose -f compose.yaml -f compose.local.yaml upThe base compose.yaml defines common services. Override files customize environment variables, ports, volumes, and other settings for specific environments.
services:
api:
environment:
NODE_ENV: production
DATABASE_URL: postgres://prod-db:5432/app
deploy:
replicas: 3
resources:
limits:
cpus: "1.0"
memory: 512M
db:
ports: [] # Remove port mapping in production
# Remove dev tools entirely
adminer: null
redis-commander: nullcompose.prod.yaml overrides specific keys from the base file. It sets production environment variables, adds resource limits, removes port mappings, and excludes development tools.
Use compose.override.yaml (auto-loaded), compose.prod.yaml, compose.dev.yaml, and compose.test.yaml. Compose automatically loads compose.override.yaml if it exists.
Extension Fields
Extension fields (x-) let you define reusable configuration blocks. These fields are ignored by Compose but can be referenced using YAML anchors. They reduce duplication across services.
x-common-env: &common-env
DATABASE_URL: postgres://db:5432/app
REDIS_URL: redis://cache:6379
LOG_LEVEL: info
services:
api:
image: myapp-api
environment:
<<: *common-env
PORT: 3000
worker:
image: myapp-worker
environment:
<<: *common-env
CONCURRENCY: 5The x-common-env extension defines shared environment variables. Both api and worker inherit them using YAML anchors. Changes to x-common-env apply to all services that reference it.
Project Names
Docker Compose uses the project name to namespace resources. Containers, networks, and volumes are prefixed with the project name. Changing the project name lets you run multiple instances of the same stack.
# Default project name: directory name
docker compose up
# Custom project name
docker compose -p myproject up
# Run multiple instances
docker compose -p app-v1 up -d
docker compose -p app-v2 up -d
# List projects
docker compose ls
# Stop a specific project
docker compose -p app-v1 downThe project name prefixes all resource names. app-v1_web_1 and app-v2_web_1 are separate containers. This enables blue-green deployments and parallel testing.
Multiple Environments
# Development
docker compose -f compose.yaml -f compose.dev.yaml up
# Staging
docker compose -f compose.yaml -f compose.staging.yaml up
# Production
docker compose -f compose.yaml -f compose.prod.yaml up
# Test
docker compose -f compose.yaml -f compose.test.yaml run testsEach override file customizes the base configuration for its environment. The base file stays the same; only the override file changes.
Merge Rules
Compose merges override files using specific rules. Scalars are replaced. Sequences are merged or replaced depending on the key. Mappings are deep-merged. Understanding these rules prevents unexpected behavior.
Not all keys merge the way you expect. For example, if the base file has ports: [8080:80] and the override has ports: [8081:80], the result is both ports. Use ports: [] in the override to clear ports instead.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.