π Intro to Docker Compose
So far weβve been running containers one at a time with docker run. That works fine for a single app β but real-world apps are rarely just one container.
Think about a typical Node.js app:
- π’ Node.js API β your backend server
- π¬ MySQL or PostgreSQL β your database
- π΄ Redis β for caching or sessions
Youβd need to start each container separately, set up networking between them, manage environment variables for eachβ¦ it gets messy fast.
Docker Compose solves this.
π What is Docker Compose?
Docker Compose is a tool that lets you define and run multiple containers as a single application using one configuration file β docker-compose.yml.
Instead of running three separate docker run commands with long flags, you write everything once in a YAML file and then run:
docker compose upThatβs it. All your containers start together, talk to each other, and behave like one cohesive app.
ποΈ The docker-compose.yml File
Everything is defined in a file called docker-compose.yml at the root of your project.
Hereβs a simple example with a Node.js API and a PostgreSQL database:
version: '3.8'
services: api: build: . ports: - "4000:4000" environment: - DATABASE_URL=postgres://postgres:secret@db:5432/mydb depends_on: - db
db: image: postgres:16-alpine environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: secret POSTGRES_DB: mydbWhatβs happening here:
servicesβ defines each container (called a service)apiβ builds from your localDockerfileand maps port 4000dbβ pulls the official PostgreSQL image from Docker Hubdepends_onβ ensures thedbcontainer starts beforeapi- Both services are on the same network by default, so
apican reachdbby using the hostnamedb
π Key Commands
| Command | What it does |
|---|---|
docker compose up | Start all services |
docker compose up -d | Start in detached (background) mode |
docker compose down | Stop and remove containers |
docker compose logs | View logs from all services |
docker compose ps | List running services |
docker compose build | Rebuild images |
π How Containers Talk to Each Other
When you run docker compose up, Docker automatically creates a shared network for all your services.
Each service can reach the other using its service name as the hostname.
So if your Node.js app needs to connect to Postgres, the connection string is:
postgres://user:password@db:5432/mydbNotice db β thatβs the service name from docker-compose.yml, not localhost. Docker handles the DNS resolution internally.
β Why Use Docker Compose?
- One command to start your entire app stack
- No manual networking β services talk to each other by name
- Consistent environments β same setup on every machine
- Easy to share β just share the
docker-compose.ymland anyone can run your app
π§ Mental Model
Think of docker-compose.yml as the blueprint for your entire app β it describes every piece (API, database, cache) and how they connect. Docker Compose reads that blueprint and brings the whole thing to life with a single command.