Imagine you need to set up WordPress. This involves two main components: a database (like MySQL) and the WordPress application itself.
Docker CLI
Using only the Docker CLI, here's what you'd have to do:
- Create a network: This allows the containers to talk to each other.
docker network create wordpress-network
- Start the MySQL container:
docker run -d \
--name db \
--network wordpress-network \
-e MYSQL_ROOT_PASSWORD=example_password \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=wordpress_password \
-v db_data:/var/lib/mysql \
mysql:5.7
- Start the WordPress container:
docker run -d \
--name wordpress \
--network wordpress-network \
-p 8000:80 \
-e WORDPRESS_DB_HOST=db \
-e WORDPRESS_DB_NAME=wordpress \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress_password \
-v wordpress_data:/var/www/html \
wordpress:latest
- Stopping the containers
docker stop wordpress
docker stop db
- Removing the containers
docker rm wordpress
docker rm db
- Removing the network:
docker network rm wordpress-network
As you can see, even for a simple two-container application, the CLI commands are lengthy, repetitive, and require careful attention to dependencies (the database must start before WordPress) - commands needs to be executed in a certain order.
Docker Compose
Now, let's see how Docker Compose simplifies this process.
-
Create a
docker-compose.yml
file: This file defines the entire application stack in a simple, readable format:
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: example_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_password
volumes:
- db_data:/var/lib/mysql
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_password
volumes:
- wordpress_data:/var/www/html
volumes:
db_data:
wordpress_data:
- Start the application: With one simple command:
docker compose up -d
That's it! This single command does everything we did with multiple CLI commands:
- Creates the network.
- Starts the MySQL container with the correct settings.
- Starts the WordPress container, linking it to the database.
- Maps ports and creates volumes.
- Handles dependencies automatically.
- Stop and remove everything:
docker compose down
Key Takeaways:
- Configuration: Compose uses a single, declarative YAML file, making it much easier to manage and understand the application configuration.
- Dependencies: Compose handles dependencies automatically, ensuring containers start in the correct order.
- Commands: Compose uses simple, high-level commands, reducing the amount of typing and the risk of errors.
Docker Compose drastically simplifies managing multi-container applications, making development and deployment much more efficient. It's the recommended approach for most Docker projects involving more than one container.