Below are examples of docker-compose.yaml files demonstrating common configurations, including a version utilizing secrets for sensitive data.
This example showcases many core features of Docker Compose for defining a multi-container application.
# Docker Compose file version is implicit in modern Compose files
# This file defines a multi-container application setup
services:
# Main application service
app:
# Build the image from a Dockerfile in the current directory
build:
context: .
dockerfile: ./Dockerfile
# Build arguments that can be passed to the Dockerfile during build
args:
BUILD_ENV: production
# Or use a pre-built image instead of building
# image: myapp:latest
# Container name (optional, otherwise generated automatically)
container_name: my-application
# Restart policy (never, always, on-failure, unless-stopped)
restart: unless-stopped
# Port mapping - HOST:CONTAINER format
ports:
- "8080:80"
- "443:443"
# Environment variables
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_USER=user
- DB_PASSWORD=password # Note: Avoid hardcoding secrets here in real projects
# Or use an env file instead
# env_file:
# - .env
# Mount volumes - HOST:CONTAINER format
volumes:
- ./app:/app # Mount local code for development (if needed)
- app-data:/var/data # Mount named volume
# Define dependencies - this service will start after db
depends_on:
db:
condition: service_healthy # Wait until db is healthy
# Connect to these networks
networks:
- frontend
- backend
# Health check to determine if container is running properly
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Resource constraints (optional, mainly for Swarm/Kubernetes via Compose)
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
# Database service
db:
image: postgres:14
container_name: database
restart: always
# Expose ports only to other services on the same Docker network, not to host
expose:
- "5432"
# Environment variables specific to this service
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password # Note: Avoid hardcoding secrets
- POSTGRES_DB=mydb
# Persist database data using a named volume
volumes:
- db-data:/var/lib/postgresql/data
# Health check for database
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# Redis cache service example
cache:
image: redis:alpine
container_name: redis-cache
restart: always
networks:
- backend
# Command to run when container starts
command: redis-server --save 60 1 --loglevel warning
# Define named volumes for persistent data
volumes:
app-data:
# You can specify driver and options for volumes
driver: local
db-data:
driver: local
# Define networks for isolation between services
networks:
frontend:
# You can use the default bridge driver
driver: bridge
backend:
driver: bridge
# Optional network configuration
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
app, db, cache).
[Services]
Dockerfile using build context, dockerfile path, and build args.postgres:14, redis:alpine).container_name for predictable naming.restart: unless-stopped).ports) or only to other services (expose).environment (or env_file)../app:/app - often for dev) and named volumes (db-data:/var/...) for persistence.
[Volumes]
depends_on with condition: service_healthy to control startup sequence.
[Startup Order]
networks (frontend, backend) for service isolation and communication.
[Networking]
healthcheck to verify container health before marking it as ready or restarting it.deploy.resources.limits for controlling CPU/memory (primarily for Swarm).cache service.You can customize this template based on your specific application needs. For more detailed information about specific Compose file options, refer to the Compose file reference.
This version demonstrates how to securely manage sensitive data like passwords and API keys using Docker secrets, avoiding hardcoding them in the Compose file or environment variables.
# Docker Compose file version is implicit in modern Compose files
# This file defines a multi-container application setup using secrets
services:
# Main application service
app:
build:
context: .
dockerfile: ./Dockerfile
args:
BUILD_ENV: production
# Build secrets - available only during build time (requires BuildKit)
secrets:
- build_secret
container_name: my-application
restart: unless-stopped
ports:
- "8080:80"
- "443:443"
# Environment variables
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_USER=user
# Reference to secret file path instead of hardcoded password
- DB_PASSWORD_FILE=/run/secrets/db_password # App reads password from this file
volumes:
- ./app:/app
- app-data:/var/data
depends_on:
db:
condition: service_healthy
networks:
- frontend
- backend
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
# Secrets to be mounted into the running container's filesystem
secrets:
- db_password # Grant access to the 'db_password' secret
- api_key # Grant access to the 'api_key' secret
# Database service
db:
image: postgres:14
container_name: database
restart: always
expose:
- "5432"
# Environment variables specific to this service
environment:
- POSTGRES_USER=user
# Reference to secret file instead of hardcoded password
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password # Postgres reads password from this file
- POSTGRES_DB=mydb
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# Secrets for the database service
secrets:
- db_password # Grant access to the 'db_password' secret
# Redis cache service example (unchanged from previous example)
cache:
image: redis:alpine
container_name: redis-cache
restart: always
networks:
- backend
command: redis-server --save 60 1 --loglevel warning
# Define named volumes for persistent data (unchanged)
volumes:
app-data:
driver: local
db-data:
driver: local
# Define networks for isolation between services (unchanged)
networks:
frontend:
driver: bridge
backend:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
# Define secrets for sensitive data (top-level declaration)
secrets:
# File-based secret (read from a file on the host)
db_password:
file: ./secrets/db_password.txt # Path to the secret file on the host
# Environment variable-based secret (reads from host environment)
api_key:
environment: API_KEY_ENV_VAR # Name of host env var containing the secret
# External secret (managed outside of Compose, e.g., by Swarm)
# ssl_cert:
# external: true
# Build-time only secret (defined here, used in service build section)
build_secret:
file: ./secrets/build_secret.txt
secrets Block: Defines all secrets available to the Compose application. Specifies how each secret is sourced (file, environment, external).
[Secrets]
secrets Block: Grants specific services access to secrets defined in the top-level block. Secrets granted here are mounted into the container's filesystem at /run/secrets/<secret_name> by default.DB_PASSWORD_FILE=/run/secrets/db_password for the app service, POSTGRES_PASSWORD_FILE=/run/secrets/db_password for the db service). The application code or entrypoint script needs to be adapted to read the secret from this file path.build.secrets section allows securely passing secrets *during* the image build process (using RUN --mount=type=secret... in the Dockerfile). These secrets are *not* available in the final image or running container unless explicitly copied. This requires Docker BuildKit.Important: Ensure the source files (like ./secrets/db_password.txt) or environment variables (like API_KEY_ENV_VAR) exist on the host machine where you run docker compose up, and protect these source files appropriately (e.g., add them to .gitignore).