Devkitr
Generators

Docker Compose Complete Guide — Services, Volumes & Networking

2026-03-0513 min readby Kashif

Docker Compose is a tool for defining and running multi-container applications using a YAML file. With a single docker compose up command, you can create and start all the services, networks, and volumes your application needs.


docker-compose.yml Structure


A Compose file has four top-level keys:


version: "3.9" # optional in Compose V2+

services: # container definitions

volumes: # named volumes

networks: # custom networks


Defining Services


Each service is a container. Here's a web app with PostgreSQL:


services:

web:

build: .

ports:

  • "3000:3000"
  • environment:

    DATABASE_URL: postgres://user:pass@db:5432/mydb

    depends_on:

    db:

    condition: service_healthy


    db:

    image: postgres:16-alpine

    environment:

    POSTGRES_USER: user

    POSTGRES_PASSWORD: pass

    POSTGRES_DB: mydb

    volumes:

  • pgdata:/var/lib/postgresql/data
  • healthcheck:

    test: ["CMD-SHELL", "pg_isready -U user -d mydb"]

    interval: 10s

    timeout: 5s

    retries: 5


    volumes:

    pgdata:


    Key Service Properties


    build vs image

  • build: . — build from Dockerfile in current directory
  • build: { context: ./app, dockerfile: Dockerfile.prod } — build with custom context
  • image: nginx:alpine — pull from Docker Hub

  • ports

    ports:

  • "3000:3000" # host:container
  • "127.0.0.1:5432:5432" # bind to localhost only

  • environment and env_file

    environment:

    NODE_ENV: production

    API_KEY: ${API_KEY} # from shell environment


    env_file:

  • .env
  • .env.production

  • volumes

    volumes:

  • pgdata:/var/lib/postgresql/data # named volume (persistent)
  • ./src:/app/src # bind mount (dev hot-reload)
  • /app/node_modules # anonymous (prevent overwrite)

  • depends_on with health checks

    depends_on:

    db:

    condition: service_healthy # wait for healthcheck to pass

    redis:

    condition: service_started # just wait for container start


    Networking


    By default, all services in a Compose file share one network and can reach each other by service name:


    # web can connect to db at host "db", port 5432

    environment:

    DATABASE_URL: postgres://user:pass@db:5432/mydb


    Custom networks isolate services:


    services:

    web:

    networks: [frontend, backend]

    db:

    networks: [backend]

    nginx:

    networks: [frontend]


    networks:

    frontend:

    backend:

    internal: true # no external internet access


    Common Service Templates


    Redis

    redis:

    image: redis:7-alpine

    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru

    ports:

  • "6379:6379"

  • MongoDB

    mongo:

    image: mongo:7

    environment:

    MONGO_INITDB_ROOT_USERNAME: admin

    MONGO_INITDB_ROOT_PASSWORD: secret

    volumes:

  • mongodata:/data/db

  • Nginx reverse proxy

    nginx:

    image: nginx:alpine

    ports:

  • "80:80"
  • "443:443"
  • volumes:

  • ./nginx.conf:/etc/nginx/nginx.conf:ro
  • ./certs:/etc/ssl/certs:ro
  • depends_on: [web]


    Compose Profiles (Selective Services)


    Profiles let you start only certain services:


    services:

    web:

    profiles: [] # always starts

    docs:

    profiles: ["docs"]

    debug:

    profiles: ["debug"]


    docker compose --profile docs up # starts web + docs

    docker compose --profile debug up # starts web + debug


    Essential Commands


    docker compose up -d # start in background

    docker compose down # stop and remove containers

    docker compose down -v # also remove volumes

    docker compose logs -f web # follow logs for a service

    docker compose exec web sh # shell into a running container

    docker compose ps # list running services

    docker compose build --no-cache # rebuild without cache


    Override Files


    docker-compose.override.yml is automatically merged with the base file:


    # docker-compose.override.yml (dev overrides)

    services:

    web:

    volumes:

  • ./src:/app/src # enable hot reload in dev
  • command: npm run dev


    Generate a ready-to-use docker-compose.yml with our Docker Compose Generator — pick your services and get the YAML instantly.


    Related Articles

    Back to Blog