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.
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 networks1version: '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: bridgeEach 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 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 startupWithout 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 hostContainers 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!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 apiDocker Compose is the roads connecting our camps into one powerful Empire. With a single command we deploy the entire infrastructure!