Extension fields aren’t just for YAML reusability - they’re powerful metadata carriers that tools can leverage for platform-specific configurations!
Extension fields as metadata
Any key starting with x- is ignored by Compose but preserved in the configuration:
# Top-level metadata
x-project-version: "2.1.0"
x-team: "platform-engineering"
x-environment: "production"
x-region: "us-east-1"
services:
api:
image: myapi:latest
# Service-level metadata
x-tier: "frontend"
x-cost-center: "engineering"
x-sla: "99.9"
x-owner: "api-team@company.com"
Compose Bridge and Kubernetes integration
Extension fields can provide hints for Kubernetes deployment:
# Kubernetes-specific metadata
x-kubernetes:
namespace: production
ingress-class: nginx
storage-class: fast-ssd
services:
web:
image: webapp:v2
x-kubernetes:
replicas: 3
node-selector:
zone: us-east-1a
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
x-deploy:
update-strategy: "RollingUpdate"
max-surge: 1
max-unavailable: 0
Platform-specific configurations
Different deployment platforms can read their own extension fields:
# Multi-platform metadata
services:
database:
image: postgres:15
# AWS-specific
x-aws:
instance-type: "db.r5.large"
backup-retention: 7
multi-az: true
# Azure-specific
x-azure:
sku: "GP_Gen5_4"
backup-redundancy: "Geo"
# GCP-specific
x-gcp:
machine-type: "db-n1-standard-4"
backup-location: "us-central1"
high-availability: true
Tool integration examples
CI/CD pipelines:
services:
app:
build: .
x-ci:
test-command: "npm test"
coverage-threshold: 80
deploy-branch: "main"
rollback-on-failure: true
Monitoring and observability:
services:
api:
image: api:latest
x-monitoring:
alert-threshold-cpu: 80
alert-threshold-memory: 90
dashboard-url: "https://grafana.company.com/d/api-metrics"
slo-target: 99.95
Cost tracking:
services:
worker:
image: worker:latest
x-cost:
center: "CC-1234"
project: "data-processing"
environment: "production"
estimated-monthly: 450
Using extension fields programmatically
Read and process metadata in your tools:
#!/bin/bash
# extract-metadata.sh
# Get service owner
docker compose config | yq '.services.api["x-owner"]'
# List all services with their tier
docker compose config | yq '.services | to_entries | .[] |
select(.value["x-tier"]) |
{service: .key, tier: .value["x-tier"]}'
# Extract Kubernetes annotations
docker compose config | yq '.services.web["x-kubernetes"].annotations'
Compose Bridge example
When using Compose Bridge to deploy to Kubernetes:
x-default-resources: &resources
limits:
cpu: "1"
memory: "512Mi"
requests:
cpu: "0.5"
memory: "256Mi"
services:
frontend:
image: frontend:v1
x-kubernetes:
service-type: "LoadBalancer"
ingress:
enabled: true
host: "app.example.com"
tls: true
deploy:
resources:
<<: *resources
backend:
image: backend:v1
x-kubernetes:
service-type: "ClusterIP"
pod-annotations:
linkerd.io/inject: enabled
deploy:
replicas: 3
Validation and schemas
Define schemas for your extension fields:
# compose-schema.yml
x-schema:
required-fields:
- x-owner
- x-environment
environments:
- development
- staging
- production
services:
app:
image: app:latest
x-owner: "platform-team"
x-environment: "production"
x-compliance:
gdpr: true
pci-dss: false
sox: true
Pro tip: Automated documentation
Generate documentation from extension fields:
#!/usr/bin/env python3
# generate-docs.py
import yaml
import json
def extract_service_metadata(compose_file):
with open(compose_file, 'r') as f:
config = yaml.safe_load(f)
docs = {
"project": {
"version": config.get('x-project-version', 'unknown'),
"team": config.get('x-team', 'unknown'),
"environment": config.get('x-environment', 'unknown')
},
"services": {}
}
for name, service in config.get('services', {}).items():
metadata = {k: v for k, v in service.items() if k.startswith('x-')}
if metadata:
docs['services'][name] = metadata
return docs
# Generate markdown documentation
metadata = extract_service_metadata('compose.yml')
print(f"# Service Catalog\n")
print(f"**Version:** {metadata['project']['version']}")
print(f"**Team:** {metadata['project']['team']}")
print(f"**Environment:** {metadata['project']['environment']}\n")
for service, data in metadata['services'].items():
print(f"## {service}")
for key, value in data.items():
print(f"- **{key[2:]}:** {value}")
Extension fields: Your bridge between Compose and the wider ecosystem!