Compose File

Defines how docker should handle multi-container applications. You may have one or multiple of these files LINK. You can also use an include.

Config is defined in the working directory, with name compose.yaml

Service

With image

Defines the containers or services compose will run; each key becomes a service and a DNS hostname.

services:
  db: # <--- key or name of service
    image: postgres:16

(Build) With dockerfile

services:
  db:
    build:
      context: .
      dockerfile: ./src/location/Dockerfile

Container Name

services:
  db:
    image: postgres:16
    container_name: autofin-db

Health Checks

services:
  db:
    image: postgres:16
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 5s
      timeout: 3s
      retries: 20

Restart

services:
  db:
    restart: unless-stopped

Entry point

Overrides the image entry point (use sparingly; command is usually enough).

services:
  tool:
    image: alpine:3.20
    working_dir: /work
    entrypoint: ["sh", "-lc"]
    command: "echo hello"

Profiles

Lets you group services so they only run when a profile is enabled.

services:
  flyway:
    image: flyway/flyway:latest
    profiles:
      - tools

Note: that other services will also be started if they are specified in the depends on

Here you specify the profile you intend to start, in this case frontend and tools have both been enabled.

docker compose --profile frontend --profile tools up
# or
COMPOSE_PROFILES=frontend,tools docker compose up

Logging

Controls container log driver/options (usually you can ignore; helpful in some setups).

services:
  db:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Labels

Adds metadata to services/containers (used by tooling, routing, observability, etc.).

services:
  db:
    labels:
      com.autofin.component: "database"
      com.autofin.env: "dev"

Depends on

The older/simple form just orders startup (no health condition).

services:
  flyway:
    depends_on:
      - db

Secrets

Provides sensitive values as files inside containers (more “prod-ish” than .env).

services:
  app:
    image: alpine:3.20
    secrets:
      - db_password
secrets:
  db_password:
    file: ./secrets/db_password.txt

Environment

Create an environment file within the same working dir as compose.yaml. Values will automatically populate.

.env

POSTGRES_USER="name"
POSTGRES_PASSWORD="password"
POSTGRES_DB="db"

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}

Port mapping

services:
  db:
    image: postgres:16
    ports:
      - "5432:5432"

Volumes

Mounts storage. Named volumes persist data; bind mounts map host folders into containers.

services:
  db:
    volumes:
      - pgdata:/var/lib/postgresql/data

# or for the sake of more clarity
- type: bind
  source: ./database/flyway.conf
  target: /flyway/conf/flyway.conf
  read_only: true

volumes:
  pgdata:

Networks

Attaches services to specific networks. If omitted, Compose creates a default network automatically.

services:
  db:
    networks:
      - backend
  flyway:
    networks:
      - backend
networks:
  backend:

Versioning

No longer required, but some older docker versions require it.

version: "1.0"