🧩 (Post 3): Docker Compose in Action: Building Multi-Container Apps!
In real-world applications, it's rare to run a single container. You usually have a web app, a database, maybe a caching layer or a reverse proxy. That’s where Docker Compose comes in — your best friend for orchestrating multi-container systems with ease.
📘 What is Docker Compose?
Docker Compose is a tool that lets you define and manage multi-container Docker applications using a single YAML file. With one command, you can bring up or tear down an entire environment.
Benefits:
- Declarative infrastructure
- Single file for configuration
- Built-in networking between containers
- Volume & env support baked-in
🧾 Writing a docker-compose.yml
Let’s build a stack with:
- 🔹 nginx as a reverse proxy
- 🔹 Node.js backend app
- 🔹 MongoDB database
🛠 Folder structure:
project/
├── nginx/
│ └── default.conf
├── app/
│ ├── Dockerfile
│ └── index.js
├── docker-compose.yml
└── .env
📄 docker-compose.yml
version: "3.9"
services:
app:
build: ./app
environment:
- MONGO_URL=mongodb://mongo:27017/mydb
depends_on:
- mongo
networks:
- backend
mongo:
image: mongo
volumes:
- mongodata:/data/db
networks:
- backend
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- backend
volumes:
mongodata:
networks:
backend:
🔁 Service Dependencies & Health Checks
depends_on ensures order, but doesn’t wait for readiness. To solve that:
Add a healthcheck to your app:
services:
app:
...
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
retries: 3
🔐 Environment Variables & .env
Create a .env file in the root directory:
PORT=3000
MONGO_URL=mongodb://mongo:27017/mydb
Reference inside docker-compose.yml like this:
environment:
- PORT=${PORT}
- MONGO_URL=${MONGO_URL}
🧱 App Dockerfile
# app/Dockerfile
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "index.js"]
🧩 Managing the Stack
🚀 Launch all containers:
docker-compose up
🔄 Rebuild after changes:
docker-compose up --build
🛑 Stop everything:
docker-compose down
📈 Scaling Services
You can run multiple containers of a service (useful for APIs):
docker-compose up --scale app=3
💡 Docker Compose will automatically load-balance traffic between them — if your reverse proxy (like Nginx) is configured to do so.
🌐 Sample NGINX Config
# nginx/default.conf
server {
listen 80;
location / {
proxy_pass http://app:3000;
}
}
This proxies incoming HTTP traffic to our Node.js backend container using its service name as a hostname. Docker’s internal DNS handles it.
📋 Summary
- 🧩 Docker Compose makes multi-container workflows elegant and maintainable.
- 🔁 Use
depends_on+healthcheckfor reliable startup sequences. - 🔐 Keep secrets and configs in
.envfiles. - 📦 Compose handles volumes, networks, and services all in one place.
- 🚀 Use
docker-compose up --scaleto run multiple replicas.
This was your first hands-on dive into orchestrating real-world, production-like setups with Docker Compose.
In our next post, we’ll dive into 📦 (Post 4): Docker Registries: Docker Hub, Private Registry & Image Sharing!
— Blog by Aelify (ML2AI.com)