Docker is great for running single containers. But real‑world applications often need multiple services – a web server, a database, a cache, and maybe a queue worker. Managing them individually with docker run commands gets messy quickly.
Docker Compose solves this. You define all your services in a single YAML file, then start everything with one command. This guide covers installation and common use cases.
What Is Docker Compose?
Docker Compose is a tool for defining and running multi‑container Docker applications. You write a docker‑compose.yml file that describes your services, networks, and volumes. Then you run docker compose up to start everything.
Compose is useful for:
- Local development environments
- Staging and testing setups
- Small production applications
- CI/CD pipelines
Step 1: Install Docker
Docker Compose requires Docker. If you don't have Docker installed:
sudo apt update
sudo apt install docker.io -y
sudo systemctl start docker
sudo systemctl enable docker
Add your user to the docker group to run commands without sudo:
sudo usermod -aG docker $USER
Log out and log back in for the changes to take effect.
Step 2: Install Docker Compose
On Ubuntu 24.04, Docker Compose is available in the official repositories:
sudo apt install docker-compose -y
Verify the installation:
docker-compose --version
If you're using a newer system, the plugin version might be installed as docker compose (without the hyphen). Both work.
Step 3: Your First docker‑compose.yml
Create a new directory and a docker‑compose.yml file:
mkdir myapp
cd myapp
nano docker-compose.yml
Add this example that runs a simple web application with Redis:
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
redis:
image: redis:alpine
networks:
- app-network
networks:
app-network:
driver: bridge
This defines two services: an Nginx web server and a Redis cache. They communicate via the app-network network.
Step 4: Start the Application
Start all services:
docker-compose up -d
The -d flag runs containers in the background (detached mode).
Check the status:
docker-compose ps
You should see both services running. Visit http://your_server_ip:8080 to see the Nginx welcome page.
To stop everything:
docker-compose down
Step 5: Add a Database Service
Here's a more realistic example with MySQL:
version: '3.8'
services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
MYSQL_ROOT_PASSWORD: rootpassword
volumes:
- db_data:/var/lib/mysql
volumes:
wordpress_data:
db_data:
This launches a full WordPress stack with MySQL. Visit http://your_server_ip:8080 to run the WordPress installer.
Step 6: Common Docker Compose Commands
Start services:
docker-compose up -d
Stop services:
docker-compose stop
Stop and remove containers:
docker-compose down
View logs:
docker-compose logs -f
Run a command in a service:
docker-compose exec web bash
Rebuild services after code changes:
docker-compose up -d --build
Step 7: Use Docker Compose with a Custom Dockerfile
Instead of using pre‑built images, you can build your own:
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_PASSWORD: secret
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
Place a Dockerfile in the same directory, and Compose will build it automatically.
Troubleshooting
Port already in use – Change the host port in the ports section (e.g., "8081:80").
Permission denied – Add your user to the docker group and log out/back in.
Container crashes – Check logs with docker-compose logs SERVICE_NAME.
Volume permission issues – Some containers run as root. Use user: "1000:1000" in the service definition.
Next Steps
Docker Compose simplifies local development and small‑scale deployments. Start with simple stacks, then add services like Redis, Elasticsearch, or queue workers as your needs grow.
For production, consider using Docker Swarm or Kubernetes for orchestration.
Need a VPS to practice on? Check our recommended VPS providers.