Docker Compose
What is Docker Compose?
Docker Compose is a tool that makes life easier when you use multiple containers in one project. With Docker Compose, you can run multiple services at once using just one configuration file (docker-compose.yml).
Why Use Docker Compose?
Can run many containers with a single command
Configuration is cleaner and easier to understand
Can use environment variables for flexible settings
Easy to scale services
Simple Implementation
We’ll create a simple example: a Node.js app connected to a PostgreSQL database.
Folder Structure:
my_project/
│── docker-compose.yml
│── app/
│ ├── server.js
│ ├── package.jsondocker-compose.yml content:
services:
web:
image: node:21
container_name: web_app
working_dir: /app
volumes:
- .:/app # Mount the current folder to /app in the container
ports:
- "3000:3000" # hostPort:containerPort
command: "node server.js"
depends_on:
- db
db:
image: postgres:16
container_name: postgres_db
restart: always
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydatabase
ports:
- "5432:5432" # hostPort:containerPortpackage.json content:
{
"name": "web-app",
"version": "1.0.0",
"description": "Node.js app with PostgreSQL using Docker Compose",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.3",
"pg": "^8.11.3"
}
}server.js content:
const express = require('express');
const { Client } = require('pg');
const app = express();
const port = 3000;
// Database connection config
const db = new Client({
user: 'user',
host: 'db', // Matches the database service name in docker-compose.yml
database: 'mydatabase',
password: 'password',
port: 5432,
});
// Try to connect to the database
db.connect()
.then(() => console.log('Database connected!'))
.catch(err => console.error('Database connection failed:', err));
// Main endpoint
app.get('/', async (req, res) => {
try {
const result = await db.query('SELECT NOW()');
res.json({ message: 'Server is running!', time: result.rows[0].now });
} catch (err) {
res.status(500).json({ error: 'Failed to fetch time from database' });
}
});
// Start server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});Brief explanation:
web service → Runs the Node.js app inside a container and exposes port 3000
db service → PostgreSQL with default database settings
depends_on → Ensures the database service starts before the web service
Basic Docker Compose commands:
🚀 Start all containers:
docker compose up -d🛑 Stop all containers:
docker compose down📜 View container logs:
docker compose logs -fScaling with Docker Compose
If you want more than one instance of a certain service, use this command:
docker compose up --scale web=3 -dThis will run 3 instances of the web service, while the database remains a single instance.