Until now, we have been looking at containers as individual units. We fixed their plumbing, gave them memory, and put them on a diet. But in the real world, an application is rarely just one container.
A modern web app usually looks like this:
- A Frontend (React or Vue)
- A Backend API (Node.js, Laravel, or Python)
- A Database (PostgreSQL or MySQL)
- A Cache (Redis)
Starting these one by one with docker run is tedious and error prone. This is where Docker Compose steps in as your conductor.
What is Docker Compose?
Docker Compose is a tool that allows you to define and run multi-container applications. Instead of typing long commands in your terminal, you define your entire infrastructure in a single file called docker-compose.yml.
With one command, you can start every service your app needs, pre-configured to talk to each other.
Breaking Down the YAML File
The docker-compose.yml file is organized into three main sections:
- Services: This is where you define your containers (the frontend, the backend, etc.).
- Networks: This automatically sets up the "plumbing" we discussed in post one so your services can communicate.
- Volumes: This handles the "memory" from post two so your database stays persistent.
A Full-Stack Example
Here is a simplified look at how a typical stack is defined:
version: "3.8"
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
networks:
- app-network
backend:
build: ./backend
environment:
- DB_HOST=database
networks:
- app-network
database:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
Essential Compose Commands
Once your file is ready, these are the commands you will use every day:
- Start everything:
docker-compose up -d(The-druns it in the background). - Stop and remove everything:
docker-compose down. - View running services:
docker-compose ps. - View live logs:
docker-compose logs -f. - Run a command inside a service:
docker-compose exec backend npm run migrate.
Why This is a Game Changer
Using Compose means your entire environment is documented in your code. If a new developer joins your team, or if you want to move your app to a new server in your home lab, they don't need to ask you for the setup instructions. They just run docker-compose up and everything works.
In tools like Portainer, these files are often referred to as "Stacks." It is the most efficient way to manage complex applications without losing track of your configuration.
Wrapping Up
Docker Compose takes the manual labor out of container management. It ensures that your frontend, backend, and database always start in the right order with the right settings.
In our final post of this series, we will look at The Guard. We will cover the essential checklist for moving these containers out of development and into a secure production environment.
Happy Dockerizing!