Docker Compose 🚢
Outline
- [x] Introduction to Docker Compose
- [x] Managing Containers with Docker Compose
- [x] Example: FastAPI, Node.js, Redis, and PostgreSQL Backend
- [x] Writing a Docker Compose File: Common Steps
- [x] Visualizing the Docker Compose Structure
What is Docker Compose? 🤔
Docker Compose is a tool that allows you to define and manage multi-container Docker applications. It uses a simple YAML file to configure your application's services, networks, and volumes, making it easier to develop, test, and deploy applications that consist of multiple interconnected components.
How Docker Compose Manages Containers? 🔧
Docker Compose manages containers by allowing you to:
- Define Services: Specify each service (e.g., a web app, a database) and its configuration in a single
docker-compose.yml
file. - Build Images: Automatically build images from a
Dockerfile
or use existing images from a registry. - Start and Stop Containers: Easily start, stop, and manage the lifecycle of your application containers with simple commands.
Example: FastAPI, Node.js, Redis, and PostgreSQL Backend 🚀
1. Create a Project Directory
2. Directory Structure
Create the following directory structure:
my_project/
├── docker-compose.yml
├── fastapi/
│ ├── Dockerfile
│ └── main.py
├── nodejs/
│ ├── Dockerfile
│ └── index.js
└── redis/
3. FastAPI Application
fastapi/main.py
from fastapi import FastAPI
import asyncpg
app = FastAPI()
DATABASE_URL = "postgresql://user:password@postgres:5432/mydatabase"
async def get_db_connection():
conn = await asyncpg.connect(DATABASE_URL)
return conn
@app.get("/")
async def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
conn = await get_db_connection()
async with conn.transaction():
item = await conn.fetchrow("SELECT * FROM items WHERE id = $1", item_id)
return {"item": item}
fastapi/Dockerfile
# FastAPI Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./main.py /app/main.py
# Install dependencies
RUN pip install asyncpg
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
4. Node.js Application
nodejs/index.js
const express = require("express");
const app = express();
const PORT = 3000;
app.get("/", (req, res) => {
res.send("Hello from Node.js!");
});
app.listen(PORT, () => {
console.log(`Node.js server running on port ${PORT}`);
});
nodejs/Dockerfile
# Node.js Dockerfile
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
5. Docker Compose File
docker-compose.yml
version: "3.8"
services:
postgres:
image: postgres:14
environment:
POSTGRES_DB: mydatabase
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
fastapi:
build:
context: ./fastapi
ports:
- "8000:80"
depends_on:
- postgres
nodejs:
build:
context: ./nodejs
ports:
- "3000:3000"
redis:
image: "redis:alpine"
ports:
- "6379:6379"
How to Write a Docker Compose File: Common Steps 📝
-
Define the Version:
-
Specify the version of the Compose file format.
-
Define Services:
-
Each service represents a container in your application. You can specify settings like
image
,build
,ports
,volumes
, andenvironment
. -
Link Services:
-
Use
depends_on
to control the startup order of services. -
Define Networks (Optional):
-
Specify custom networks for inter-service communication.
-
Define Volumes (Optional):
- Persist data by defining volumes.
Conclusion 🎉
Docker Compose simplifies the management of multi-container applications, making it easier to define, run, and maintain your services. With its straightforward YAML configuration and the included FastAPI, Node.js, Redis, and PostgreSQL examples, you can get started quickly and scale your applications efficiently.