Skip to content

Compose File Reference

The Docker Compose file (docker-compose.yml) defines the services, networks, and volumes for your multi-container application. This reference covers the most important configuration options.

File Structure

A Compose file has the following top-level elements:

yaml
# Optional: Compose specification version (not required in modern Compose)
# version: "3.9"  # Deprecated in Compose V2

# Service definitions
services:
  web:
    # ...service configuration
  api:
    # ...service configuration

# Network definitions
networks:
  frontend:
    # ...network configuration

# Volume definitions
volumes:
  data:
    # ...volume configuration

# Secret definitions
secrets:
  db-password:
    # ...secret configuration

# Config definitions
configs:
  app-config:
    # ...config configuration

Services

Services are the core of a Compose file. Each service defines a container that should be running.

Image Configuration

yaml
services:
  # Use a pre-built image
  web:
    image: nginx:1.25-alpine

  # Build from a Dockerfile
  api:
    build: ./api

  # Build with advanced options
  app:
    build:
      context: ./app
      dockerfile: Dockerfile.prod
      args:
        NODE_ENV: production
        VERSION: "2.0"
      target: production
      cache_from:
        - myuser/myapp:cache
      platforms:
        - linux/amd64
        - linux/arm64
      labels:
        com.example.description: "My App"

Build Configuration Options

OptionDescriptionExample
contextBuild context path or URL./app, https://github.com/user/repo.git
dockerfileAlternate Dockerfile pathDockerfile.prod
argsBuild-time argumentsNODE_ENV: production
targetMulti-stage build targetproduction
cache_fromCache sourcesmyuser/app:cache
cache_toCache destinationstype=registry,ref=cache:latest
platformsTarget platformslinux/amd64, linux/arm64
labelsImage labelsversion: "1.0"
no_cacheDisable build cachetrue
pullAlways pull base imagetrue

Port Mapping

yaml
services:
  web:
    ports:
      # Short syntax
      - "80:80"               # host:container
      - "443:443"
      - "8080:80"             # Different host port
      - "127.0.0.1:8080:80"  # Bind to localhost only
      - "3000"                # Random host port
      - "8080-8090:80-90"    # Port range

      # Long syntax
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

      - target: 443
        published: 443
        protocol: tcp

Environment Variables

yaml
services:
  api:
    # Map syntax
    environment:
      NODE_ENV: production
      DB_HOST: db
      DB_PORT: "5432"
      API_KEY: ${API_KEY}    # From shell or .env file

    # List syntax
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - API_KEY              # Pass through from host

    # From file(s)
    env_file:
      - .env
      - .env.local
      - path: .env.prod
        required: false       # Don't fail if missing

Volumes

yaml
services:
  app:
    volumes:
      # Named volume
      - data:/app/data

      # Bind mount (short syntax)
      - ./src:/app/src
      - ./config:/app/config:ro

      # Bind mount (long syntax)
      - type: bind
        source: ./logs
        target: /app/logs
        read_only: false

      # Named volume (long syntax)
      - type: volume
        source: data
        target: /app/data
        volume:
          nocopy: true

      # tmpfs mount
      - type: tmpfs
        target: /app/temp
        tmpfs:
          size: 100000000  # 100 MB
          mode: 1777

volumes:
  data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /srv/data

Dependencies

yaml
services:
  web:
    depends_on:
      # Simple form
      - api
      - db

  api:
    depends_on:
      # Conditional form (with health checks)
      db:
        condition: service_healthy
        restart: true
      redis:
        condition: service_started
      migrations:
        condition: service_completed_successfully

Dependency Conditions

ConditionDescription
service_startedWait for service to start (default)
service_healthyWait for service health check to pass
service_completed_successfullyWait for service to complete with exit code 0

Health Checks

yaml
services:
  api:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
      start_interval: 5s

  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
      interval: 10s
      timeout: 5s
      retries: 5

  disabled:
    healthcheck:
      disable: true

Restart Policies

yaml
services:
  web:
    restart: "no"              # Never restart (default)

  api:
    restart: always            # Always restart

  worker:
    restart: on-failure        # Restart on failure only

  db:
    restart: unless-stopped    # Restart unless explicitly stopped

Resource Limits

yaml
services:
  api:
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 512M
          pids: 100
        reservations:
          cpus: '0.25'
          memory: 128M

Command and Entrypoint

yaml
services:
  app:
    # Override the default command
    command: npm run dev

    # Shell form
    command: "echo hello && npm start"

    # Exec form (preferred)
    command: ["npm", "run", "dev"]

    # Override entrypoint
    entrypoint: ["python", "-u"]
    command: ["app.py", "--debug"]

Logging

yaml
services:
  api:
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
        compress: "true"

  silent:
    logging:
      driver: none

Container Configuration

yaml
services:
  app:
    container_name: my-app        # Fixed container name
    hostname: app-server          # Container hostname
    domainname: example.com       # Domain name
    working_dir: /app             # Working directory
    user: "1000:1000"             # Run as user:group
    stdin_open: true              # Equivalent to -i
    tty: true                     # Equivalent to -t
    init: true                    # Use init process (tini)
    read_only: true               # Read-only root filesystem
    privileged: false             # Never use in production
    stop_grace_period: 30s        # Time before SIGKILL
    stop_signal: SIGTERM          # Stop signal
    platform: linux/amd64         # Target platform

Security

yaml
services:
  app:
    security_opt:
      - no-new-privileges:true
      - seccomp:custom-profile.json

    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE

    read_only: true
    tmpfs:
      - /tmp
      - /var/run

    ulimits:
      nproc: 65535
      nofile:
        soft: 20000
        hard: 40000

Networks

yaml
networks:
  # Default network (auto-created)
  default:
    driver: bridge

  # Custom bridge network
  frontend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1

  # Internal network (no external access)
  backend:
    driver: bridge
    internal: true

  # External network (pre-existing)
  existing:
    external: true
    name: my-pre-existing-network

  # Network with labels
  labeled:
    driver: bridge
    labels:
      com.example.project: "myapp"

Volumes

yaml
volumes:
  # Simple named volume
  data:

  # Volume with driver options
  db-data:
    driver: local
    driver_opts:
      type: nfs
      o: "addr=192.168.1.100,rw"
      device: ":/exports/data"

  # External volume
  shared-data:
    external: true
    name: my-shared-volume

  # Volume with labels
  logs:
    labels:
      com.example.description: "Application logs"

Secrets and Configs

yaml
services:
  db:
    secrets:
      - db_password
      - source: db_root_password
        target: /run/secrets/root_pw
        uid: '103'
        gid: '103'
        mode: 0440

  web:
    configs:
      - source: nginx_config
        target: /etc/nginx/nginx.conf

secrets:
  db_password:
    file: ./secrets/db_password.txt
  db_root_password:
    environment: DB_ROOT_PASSWORD

configs:
  nginx_config:
    file: ./nginx/nginx.conf

Variable Substitution

yaml
services:
  web:
    image: nginx:${NGINX_VERSION:-1.25}
    ports:
      - "${WEB_PORT:-80}:80"

  db:
    image: postgres:${PG_VERSION:?PG_VERSION must be set}
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
SyntaxBehavior
${VAR}Value of VAR (empty if unset)
${VAR:-default}Value of VAR, or default if unset/empty
${VAR-default}Value of VAR, or default if unset
${VAR:?error}Value of VAR, or exit with error if unset/empty
${VAR?error}Value of VAR, or exit with error if unset

Complete Example

yaml
services:
  frontend:
    build:
      context: ./frontend
      target: production
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      api:
        condition: service_healthy
    networks:
      - frontend-net
    restart: unless-stopped

  api:
    build:
      context: ./api
      args:
        NODE_ENV: production
    ports:
      - "3000:3000"
    environment:
      - DB_HOST=db
      - REDIS_HOST=redis
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - frontend-net
      - backend-net
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

  db:
    image: postgres:16-alpine
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    environment:
      POSTGRES_USER: ${DB_USER}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: ${DB_NAME}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend-net
    restart: unless-stopped

  redis:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis-data:/data
    networks:
      - backend-net
    restart: unless-stopped

networks:
  frontend-net:
  backend-net:
    internal: true

volumes:
  db-data:
  redis-data:

Next Steps

基于 MIT 许可发布