Skip to main content

How to run a multi-container app with Docker Compose

Docker Compose runs an app, database, and cache as services in one YAML file, wired by service name over a shared network. Add named volumes for persistence and health checks for ordered startup.

Difficulty
Beginner
Duration
35 minutes
Steps
6

Multi-container apps with Docker Compose

Docker Compose describes a multi-service application in a single YAML file. One command starts your app, its database, and supporting services together on a shared network. Compose is ideal for local development and small deployments.

Prerequisites

  • Docker Engine with the Compose plugin (docker compose version).
  • An application that depends on a database and optionally a cache.

Steps

1. Create a compose file

Create compose.yaml at the project root. The top-level keys are services, volumes, and networks.

2. Define the app service

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/app
      REDIS_URL: redis://cache:6379

Note that services reference each other by name (db, cache) over the default network.

3. Add database and cache services

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    volumes:
      - dbdata:/var/lib/postgresql/data
  cache:
    image: redis:7

4. Configure volumes for persistence

Named volumes survive container restarts:

volumes:
  dbdata:

Without this, database data is lost when the container is removed.

5. Add health checks and depends_on

Make the app wait until the database is ready:

  db:
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      retries: 5
  app:
    depends_on:
      db:
        condition: service_healthy

6. Start and inspect the stack

docker compose up -d
docker compose ps
docker compose logs -f app

Tear it down with docker compose down, or docker compose down -v to also remove volumes.

Verification

Run docker compose up -d and confirm all services report healthy with docker compose ps. Hit the app endpoint and verify it reads and writes to the database. Restart with docker compose restart and confirm data persists thanks to the named volume.

Next Steps

Split configuration into compose.override.yaml for local overrides, add a reverse proxy service, and when you outgrow a single host, translate the Compose services into Kubernetes manifests.

Prerequisites

  • Docker and Compose installed
  • An application that needs a database

Steps

  • 1
    Create a compose file
  • 2
    Define the app service
  • 3
    Add database and cache services
  • 4
    Configure volumes for persistence
  • 5
    Add health checks and depends_on
  • 6
    Start and inspect the stack

Category

Containers