We use cookies to enhance your experience on the site
CodeWorlds

Docker Compose — The Road Network of the Empire

A single container is like a single legionary camp. But a true Empire needs a network of roads connecting many camps — API, database, cache, reverse proxy. Docker Compose is a tool that allows you to define and run multiple containers simultaneously.

What is Docker Compose?

Docker Compose uses a

docker-compose.yml
file in YAML format to define services, networks, and volumes. With a single command you launch the entire infrastructure.

1# Basic docker-compose.yml structure
2version: '3.8'
3
4services:
5  api:
6    # Our NestJS application
7  mongodb:
8    # MongoDB database
9  redis:
10    # Redis cache
11
12volumes:
13  # Persistent data
14
15networks:
16  # Communication networks

Full Docker Compose Configuration

1version: '3.8'
2
3services:
4  # ===========================================
5  # API Service — Main Fortress (Praetorium)
6  # ===========================================
7  api:
8    build:
9      context: .
10      dockerfile: Dockerfile
11      target: production
12    container_name: roman-imperium-api
13    ports:
14      - '4000:4000'
15    environment:
16      - NODE_ENV=production
17      - DATABASE=mongodb://mongodb:27017/roman-imperium
18      - REDIS_HOST=redis
19      - REDIS_PORT=6379
20      - PORT=4000
21    depends_on:
22      mongodb:
23        condition: service_healthy
24      redis:
25        condition: service_started
26    networks:
27      - imperium-network
28    restart: unless-stopped
29    healthcheck:
30      test: ['CMD', 'curl', '-f', 'http://localhost:4000/health']
31      interval: 30s
32      timeout: 10s
33      retries: 3
34      start_period: 40s
35
36  # ===========================================
37  # MongoDB — Archive of the Empire
38  # ===========================================
39  mongodb:
40    image: mongo:7.0
41    container_name: roman-imperium-db
42    ports:
43      - '27017:27017'
44    environment:
45      - MONGO_INITDB_ROOT_USERNAME=imperator
46      - MONGO_INITDB_ROOT_PASSWORD=roma_aeterna_2024
47      - MONGO_INITDB_DATABASE=roman-imperium
48    volumes:
49      - mongodb-data:/data/db
50    networks:
51      - imperium-network
52    restart: unless-stopped
53    healthcheck:
54      test: echo 'db.runCommand("ping").ok' | mongosh --quiet
55      interval: 10s
56      timeout: 5s
57      retries: 5
58
59  # ===========================================
60  # Redis — Swift Courier (Cursus Velox)
61  # ===========================================
62  redis:
63    image: redis:7-alpine
64    container_name: roman-imperium-cache
65    ports:
66      - '6379:6379'
67    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
68    volumes:
69      - redis-data:/data
70    networks:
71      - imperium-network
72    restart: unless-stopped
73
74# ===========================================
75# Volumes — Warehouses of the Empire
76# ===========================================
77volumes:
78  mongodb-data:
79    driver: local
80  redis-data:
81    driver: local
82
83# ===========================================
84# Networks — Roads of the Empire
85# ===========================================
86networks:
87  imperium-network:
88    driver: bridge

Key Configuration Elements

Services

Each service is a separate container. The most important fields:

1const serviceFields = {
2  build: 'Building from Dockerfile (or image for ready-made images)',
3  ports: 'Port mapping host:container',
4  environment: 'Environment variables',
5  depends_on: 'Dependencies between services',
6  volumes: 'Mounting volumes',
7  networks: 'Network assignment',
8  restart: 'Restart policy (always, unless-stopped, on-failure)',
9  healthcheck: 'Service health checking',
10};

depends_on — Startup Order

depends_on
defines that the API service should wait for MongoDB and Redis:

1depends_on:
2  mongodb:
3    condition: service_healthy  # Wait for health check
4  redis:
5    condition: service_started  # Wait for startup

Volumes — Persistent Data

Without volumes, data disappears when the container stops. Volumes are like underground warehouses — they survive even the destruction of the camp:

1volumes:
2  mongodb-data:
3    driver: local  # Data stored on the host

Networks — Communication

Containers on the same network can communicate by service name:

1// In the 'api' container we can connect to MongoDB like this:
2const mongoUrl = 'mongodb://mongodb:27017/roman-imperium';
3// 'mongodb' is the service name in docker-compose!

Docker Compose Commands

1# Start all services
2docker compose up -d
3
4# Build and start
5docker compose up --build -d
6
7# Stop everything
8docker compose down
9
10# Stop and remove volumes (WARNING: deletes data!)
11docker compose down -v
12
13# Show logs
14docker compose logs -f api
15
16# Check status
17docker compose ps
18
19# Restart a single service
20docker compose restart api

Docker Compose is the roads connecting our camps into one powerful Empire. With a single command we deploy the entire infrastructure!

Go to CodeWorlds