Skip to content

🎼 Docker Compose

Why Do You Need Compose?

If your application requires multiple containers working together (e.g., a web app + database + cache), starting them one by one manually is exhausting. Docker Compose is the orchestra conductor — define all services in a single YAML file and launch everything with one command.

docker-compose.yml Basic Syntax

yaml
# docker-compose.yml (Compose V2 no longer requires the version field)

services:
  # Web application service
  web:
    build: .                          # Build from the current directory
    ports:
      - "8080:3000"                   # Port mapping
    environment:
      - NODE_ENV=production
      - DB_HOST=db
      - REDIS_HOST=redis
    depends_on:
      - db
      - redis
    restart: unless-stopped

  # Database service
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: myapp
    volumes:
      - mysql-data:/var/lib/mysql
    restart: unless-stopped

  # Cache service
  redis:
    image: redis:7-alpine
    restart: unless-stopped

# Declare named volumes
volumes:
  mysql-data:

Common Compose Commands

bash
# Start all services (run in the background)
docker compose up -d
[+] Running 4/4
 Network myproject_default    Created
 Container myproject-db-1     Started
 Container myproject-redis-1  Started
 Container myproject-web-1    Started

# View service status
docker compose ps
NAME                SERVICE    STATUS    PORTS
myproject-db-1      db         running   3306/tcp
myproject-redis-1   redis      running   6379/tcp
myproject-web-1     web        running   0.0.0.0:8080->3000/tcp

# View logs
docker compose logs -f web

# Stop all services
docker compose down

# Stop and remove volumes (⚠️ data will be lost!)
docker compose down -v

# Rebuild and start
docker compose up -d --build

# Restart a specific service
docker compose restart web

# Scale the number of service instances (start 3 web instances)
docker compose up -d --scale web=3

Network and Volume Configuration

yaml
services:
  nginx:
    image: nginx
    networks:
      - frontend
      - backend
    ports:
      - "80:80"

  app:
    build: ./app
    networks:
      - backend
    volumes:
      - app-data:/app/data

  db:
    image: mysql:8.0
    networks:
      - backend
    volumes:
      - db-data:/var/lib/mysql

networks:
  frontend:     # Frontend network
  backend:      # Backend network (isolated)

volumes:
  app-data:
  db-data:

> 💡 Tip: > 💡 Network isolation is important! The database is only on the backend network and cannot be accessed directly from outside. Only nginx is on both networks, enabling it to forward requests.