Docker Compose Tutorial: Example with Multi-Service Applications
Docker Compose simplifies the process of managing multi-service applications by providing a straightforward way to define and orchestrate containerized services in a single YAML file. In this tutorial, you'll learn how to get started with Docker Compose and build a functional example featuring a multi-service application.
Understanding Docker Compose
Docker Compose is a tool designed to define and manage multi-container applications efficiently. At its core, Docker Compose allows you to define the services, networks, and volumes your application needs in a single docker-compose.yaml file. This enables seamless orchestration, letting you launch and manage your application stack with just one command.
Key components of Docker Compose:
- Services: Define individual containers that make up your application (e.g., a web server, database, or backend service).
- Networks: Allow services to communicate with each other securely and conveniently.
- Volumes: Provide persistent storage for data that needs to survive container restarts.
Prerequisites for Docker Compose Implementation
Before diving into the tutorial, ensure the following:
prerequisites
- Docker is installed and running on your system.
- Docker Compose is compatible with your Docker version. For Docker Desktop users, Docker Compose is built-in.
- If you're using macOS or Windows, install [Docker Desktop].
- Ensure your system is ready to execute Docker and terminal commands.
Setup Steps for a Docker Compose Example
This example demonstrates how to set up a three-tier architecture consisting of a backend API, a frontend application, and a PostgreSQL database.
Step 1: Prepare the Project Directory
Create a clean directory structure for your project.
file tree
project/
├── backend/
│ ├── Dockerfile
│ ├── app.py
│ └── requirements.txt
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ ├── package-lock.json
│ └── public/
├── .env
├── .gitignore
└── docker-compose.yamlStep 2: Backend Service Setup
Create the Dockerfile for the backend service inside the backend directory.
# backend/Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]Also, define your Python dependencies in the requirements.txt.
# backend/requirements.txt
fastapi==0.100.0
uvicorn[standard]==0.23.2
psycopg2-binary==2.9.6Add basic FastAPI code in app.py.
# backend/app.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def home():
return {"message": "Backend service is running!"}Step 3: Frontend Service Setup
Create the Dockerfile for the frontend service inside the frontend directory.
# frontend/Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "start"]Include a basic package.json for a React app in the frontend directory.
{
"name": "todo-frontend",
"version": "1.0.0",
"scripts": {
"start": "react-scripts start"
}
}Step 4: Define docker-compose.yaml
Create a docker-compose.yaml in the project root.
version: "3.8"
services:
db:
image: postgres:16
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: todo_db
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "admin"]
interval: 10s
retries: 5
backend:
build:
context: ./backend
ports:
- "8000:8000"
environment:
DB_HOST: db
DB_USER: admin
DB_PASSWORD: ${DB_PASSWORD}
DB_NAME: todo_db
depends_on:
db:
condition: service_healthy
frontend:
build:
context: ./frontend
ports:
- "3000:3000"
depends_on:
- backend
volumes:
db_data:Step 5: Protect Sensitive Data
To securely handle sensitive data like passwords, create a .env file and add it to .gitignore.
# .env
DB_PASSWORD=your_strong_password# .gitignore
.envStep 6: Launch the Application
Run the following commands to start the application.
Launch Docker Compose Stack
docker compose up --build
# The stack starts. Services will be built and containers created.Validating the Example Application Setup
Once the services are running, validate everything as follows:
Check running containers: IT_GUIDES_COMPONENT_3
Access services:
- Backend API:
http://localhost:8000. - Frontend UI:
http://localhost:3000.
- Backend API:
Access logs: IT_GUIDES_COMPONENT_4
Inspect the database: IT_GUIDES_COMPONENT_5
Useful Tips for Secure and Efficient Setup
FAQ
What is Docker Compose best used for?
Docker Compose is ideal for local development and testing of multi-service applications. It simplifies setup by managing all dependencies and services with a single configuration file.
Can Docker Compose be used in production environments?
While Docker Compose is excellent for local development, production-grade setups often require orchestrators like Kubernetes to handle scalability and robust network configurations.
How do you specify database credentials securely in Docker Compose?
Store sensitive data in an environment file (e.g., .env) and ensure the file is excluded from version control using .gitignore. You may also leverage Docker secrets for stricter security in production.
Official reference: Docker Compose documentation.