Stop copy-pasting the same configuration. YAML anchors let you define once and reuse everywhere in your Compose files.
The basics
Define an anchor with & and reference it with *:
services:
web: &default-app
image: myapp:latest
environment:
NODE_ENV: production
LOG_LEVEL: info
networks:
- app-network
worker:
<<: *default-app # Inherit all settings from web
command: npm run worker
The worker service inherits everything from web, then overrides the command.
Common logging configuration
Share logging setup across all services:
x-logging: &default-logging
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
services:
web:
image: nginx
<<: *default-logging
api:
image: myapi:latest
<<: *default-logging
worker:
image: myworker:latest
<<: *default-logging
Shared environment variables
Perfect for microservices with common config:
x-common-variables: &common-variables
REDIS_URL: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
LOG_LEVEL: ${LOG_LEVEL:-info}
services:
api:
image: api:latest
environment:
<<: *common-variables
SERVICE_NAME: api
PORT: 8080
worker:
image: worker:latest
environment:
<<: *common-variables
SERVICE_NAME: worker
WORKER_CONCURRENCY: 10
Network and volume patterns
Reuse complex configurations:
x-app-service: &app-defaults
networks:
- frontend
- backend
volumes:
- ./shared:/app/shared:ro
- logs:/app/logs
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
services:
web:
<<: *app-defaults
image: web:latest
ports:
- "3000:3000"
api:
<<: *app-defaults
image: api:latest
ports:
- "8080:8080"
networks:
frontend:
backend:
volumes:
logs:
Build configuration reuse
Share build settings across services:
x-build-args: &build-args
NODE_VERSION: "20"
NPM_TOKEN: ${NPM_TOKEN}
services:
app:
build:
context: ./app
args:
<<: *build-args
worker:
build:
context: ./worker
args:
<<: *build-args
WORKER_MODE: "true"
View expanded configuration
Check how anchors expand:
docker compose config
This shows the final configuration with all anchors resolved.
Pro tip
Use the x- prefix for anchor-only blocks - Compose ignores top-level keys starting with x-:
x-healthcheck: &healthcheck
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 3s
retries: 3
services:
web:
image: web:latest
<<: *healthcheck
The x-healthcheck block exists only for the anchor, not as a service.