Docker Compose — YAML Extensions
YAML extensions (the x- prefix) let you define reusable configuration blocks in your compose file — keeping it DRY (Don’t Repeat Yourself).
The Problem: Repetition
services:
api:
image: node:20-alpine
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
worker:
image: node:20-alpine
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
scheduler:
image: node:20-alpine
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
Three services, identical restart and logging config. Let’s DRY it up.
The Solution: x- Extensions
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
api:
<<: *common
image: node:20-alpine
worker:
<<: *common
image: node:20-alpine
command: node worker.js
scheduler:
<<: *common
image: node:20-alpine
command: node scheduler.js
How It Works
x-common:— Any top-level key starting withx-is an extension (ignored by Compose)&common— YAML anchor (names the block)<<: *common— YAML merge key (inserts the block)
Multiple Extensions
x-logging: &logging
logging:
driver: json-file
options:
max-size: "10m"
x-healthcheck: &healthcheck
healthcheck:
interval: 10s
timeout: 5s
retries: 3
services:
api:
<<: [*logging, *healthcheck]
image: myapi:latest
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/health"]
Verify Resolution
docker compose config
This outputs the fully resolved file with all extensions merged.
Rules
| Rule | Detail |
|---|---|
| Prefix | Must start with x- |
| Scope | Top-level only |
| Ignored by Compose | Yes (pure YAML feature) |
| Override | Local keys override merged values |
Summary
| Feature | Syntax |
|---|---|
| Define extension | x-name: &anchor |
| Use extension | <<: *anchor |
| Multiple | <<: [*a, *b] |
| Override | Local key wins over merged |
| Verify | docker compose config |
Quick Reference
| Item | Detail |
|---|---|
| x-name: | Extension block (ignored by Compose) |
| &anchor | YAML anchor (name the block) |
| «: *anchor | Merge the block into a service |
| Override | Local keys win over merged values |
| Verify | docker compose config |