Docker Compose — Multi-Container Applications

25 minLesson 5 of 5

Learning Objectives

  • Write docker-compose.yml files to define multi-service applications
  • Configure ports, networks, volumes, and environment variables
  • Manage application lifecycle with docker compose commands
  • Understand service dependencies and health checks

What is Docker Compose?

Docker Compose lets you define and run multi-container applications in a single YAML file. Instead of running multiple docker run commands, you describe your entire stack and launch it with one command.

Basic docker-compose.yml

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"
 
  api:
    image: python:3.11-slim
    command: python -m http.server 5000
    ports:
      - "5000:5000"

Running It

# Start all services
docker compose up
 
# Start in background
docker compose up -d
 
# Stop all services
docker compose down
 
# View logs
docker compose logs -f
 
# List running services
docker compose ps

Complete Example: Web App Stack

services:
  # Frontend
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - api
    networks:
      - frontend
 
  # Backend API
  api:
    build: ./api
    ports:
      - "5000:5000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/app
      - REDIS_URL=redis://cache:6379
    depends_on:
      - db
      - cache
    networks:
      - frontend
      - backend
 
  # Database
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - backend
 
  # Cache
  cache:
    image: redis:7-alpine
    networks:
      - backend
 
volumes:
  db-data:
 
networks:
  frontend:
  backend:

Key Configuration Options

Ports

ports:
  - "8080:80"          # host:container
  - "443:443"
  - "5432:5432"

Environment Variables

# Inline
environment:
  - NODE_ENV=production
  - DB_HOST=database
 
# From file
env_file:
  - .env

Volumes

volumes:
  - ./src:/app/src          # Bind mount (development)
  - db-data:/var/lib/data   # Named volume (persistence)
  - /app/node_modules       # Anonymous volume (exclude from bind)

Build from Dockerfile

services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    image: my-api:latest  # Tag the built image

Dependencies

services:
  api:
    depends_on:
      - db
      - cache
  # db and cache start before api

Networks

services:
  web:
    networks:
      - public
  db:
    networks:
      - private
 
networks:
  public:
  private:
    internal: true  # No external access

Container Names

services:
  db:
    container_name: my-postgres

Docker Compose Commands

CommandPurpose
docker compose up -dStart all services (background)
docker compose downStop and remove all
docker compose down -vStop, remove, AND delete volumes
docker compose psList running services
docker compose logs -fFollow all logs
docker compose logs apiLogs for specific service
docker compose exec api bashShell into running service
docker compose buildRebuild images
docker compose pullPull latest images
docker compose restartRestart all services

Development Workflow

# docker-compose.yml (development)
services:
  api:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/app              # Live code reload
    environment:
      - FLASK_DEBUG=1
    command: flask run --host=0.0.0.0 --reload
# Start development environment
docker compose up -d
 
# View logs
docker compose logs -f api
 
# Rebuild after Dockerfile changes
docker compose up -d --build
 
# Clean everything
docker compose down -v

Summary

  • Docker Compose defines multi-container apps in docker-compose.yml
  • docker compose up -d starts everything, docker compose down stops it
  • Services communicate by name on shared networks
  • Volumes persist data, bind mounts enable live development
  • depends_on controls startup order
  • One file describes your entire application stack

Module Complete

You now have a solid Docker foundation:

  1. Container concepts and architecture
  2. Running and managing containers
  3. Networking and data persistence
  4. Building custom images with Dockerfiles
  5. Multi-container apps with Docker Compose

These skills are essential for Kubernetes, CI/CD pipelines, and production deployments — all coming up in the DevOps track.