Docker Compose is a tool that lets you define and manage multi-container Docker applications using a single configuration file. Instead of manually running multiple docker run
commands, you use a docker-compose.yml
file to configure your application's services, networks, and volumes all in one place.
In this tutorial, you'll learn what Docker Compose is, how it works, how to write the docker-compose.yml
file, and how to build a practical setup using Nginx, PHP, and MySQL, all connected through Docker Compose.
What is Docker Compose?
Docker Compose is a command-line tool that helps you define and run multi-container Docker applications. It uses a docker-compose.yml
file to describe the setup:
- Services – containers like web servers, PHP processors, and databases
- Networks – how containers communicate with each other
- Volumes – persistent data outside the containers
Once configured, you can launch your entire stack using:
docker compose up
You can also stop and remove everything with:
docker compose down
Why Use Docker Compose?
Docker Compose simplifies development with multiple containers. Benefits include:
- Quick setup of complex stacks
- Consistent development environments
- Isolated services per project
- Code-based infrastructure
- One command to manage everything
How to Install Docker Compose
Docker Compose comes with Docker Desktop for Windows and macOS.
For Linux:
sudo apt update
sudo apt install docker-compose-plugin
Verify installation:
docker compose version
Understanding the docker-compose.yml
File
The docker-compose.yml
file describes how containers run together. Here's a general format:
version: "3.9" # Compose file format
services:
app:
image: your-image
build: ./app
ports:
- "8000:80"
volumes:
- ./app:/app
environment:
- ENV_VAR=value
depends_on:
- db
networks:
- backend
volumes:
your_volume:
networks:
backend:
Key Sections Explained
Section | Description |
---|---|
version
| Compose file format version |
services
| Defines containers to run |
image
| Docker image to use |
build
| Path to a Dockerfile to build a custom image |
ports
| Maps host:container ports |
volumes
| Mounts local folders or named volumes |
environment
| Sets environment variables |
depends_on
| Sets startup order for containers |
command
| Overrides the default container command (optional) |
networks
| Assigns the container to custom networks |
How to Use Docker Compose
Let's set up a real web stack with:
- Nginx as the web server
- PHP-FPM for processing PHP
- MySQL as the backend database
- Local project files outside the containers
- Persistent MySQL data using volumes
Project Setup
Your project directory should look like this:
www/
├── project/
│ └── index.php
├── nginx.conf
└── docker-compose.yml
Step 1: Write a PHP File
Create the file at www/project/index.php
:
<?php
$host = 'db';
$db = 'appdb';
$user = 'webuser';
$pass = 'webpass';
// Attempt MySQL connection
$conn = new mysqli($host, $user, $pass, $db);
// Check the connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "<h1>Connected to MySQL successfully!</h1>";
$conn->close();
?>
Step 2: Nginx Configuration
Create the file www/nginx.conf
:
server {
listen 80;
server_name localhost;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
}
}
Step 3: Define the Compose File
Create www/docker-compose.yml
:
version: "3.9"
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./project:/var/www/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
networks:
- backend
php:
image: php:8.1-fpm
volumes:
- ./project:/var/www/html
networks:
- backend
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: appdb
MYSQL_USER: webuser
MYSQL_PASSWORD: webpass
volumes:
- db_data:/var/lib/mysql
networks:
- backend
volumes:
db_data:
networks:
backend:
Step 4: Start the Application
Navigate to the www/
folder and run:
docker compose up -d
This will:
- Start all containers
- Map port
8080
to your Nginx container - Serve PHP files
- Connect to MySQL using the defined environment
Visit: http://localhost:8080
You should see: Connected to MySQL successfully!
Step 5: Stop and Remove Everything
To stop and remove containers, networks, and volumes:
docker compose down
MySQL data remains in the named volume db_data
.
Essential Docker Compose Commands
Command | Description |
---|---|
docker compose up
| Start all services |
docker compose up -d
| Start in background (detached mode) |
docker compose down
| Stop and remove services and networks |
docker compose ps
| List running containers |
docker compose logs
| Show logs for all services |
docker compose logs web
| Show logs for a specific service |
docker compose exec web bash
| Access a container's shell |
docker compose stop
| Stop services without removing them |
docker compose restart
| Restart services |
docker compose build
| Rebuild service images |
docker compose up --force-recreate
| Recreate containers even if unchanged |
docker compose down --volumes
| Remove volumes with services |
Conclusion
In this tutorial, you learned how to:
- Install and verify Docker Compose
- Understand the structure of a
docker-compose.yml
file - Use Docker Compose to orchestrate multiple services
- Set up a full Nginx + PHP + MySQL environment
- Serve local files and persist database data
- Use essential Compose commands for control and maintenance