Docker Compose
Last updated September 16, 2022.

Docker Compose is a CLI tool for running and coordinating the communication of multiple Docker containers. It’s a container orchestrator, like Kubernetes. You just have to supply a YAML config file with all the info needed for running each container, then with a single command they’ll all get created and started. You can also tear everything down instantly.
docker-compose.yml
is kept at the root of the project- It can create networks and attach containers to them and create volumes
1
2
3
4
5
6
7
8
9
10
11
| docker-compose up # Starts up all services using `docker-compose.yml`
-d # Run in the background (detached)
--build # Force-trigger a build
-f <file> # Path of the compose file. By default, `docker-compose.yml` is expected in the cwd
docker-compose down # Tear down all services
--volumes # Also remove volumes
docker-compose logs
-f # Follow the live output rather than just dumping it all out on the terminal once
# It'll interleave the output of all the running services
|
Docker Compose supports the concatenation of multiple YAML compose files to get a ‘merged’ compose file where more specialised compose files will overwrite rules in the one before it.
It’s common practice to have multiple compose files with slight variations. Eg. in addition to a ‘shared’ compose file, docker-compose.yml
, which contains all the config common to both dev and prod, you might also have docker-compose-dev.yml
and docker-compose-prod.yml
defining specific setups for development and production. In development for example, you might have a bind mount set up so that you can have hot reloading in the container. But for production, you wouldn’t want this
# Example
In the
official Docker tutorial, we’re using these 2 commands to startup our app server and database server:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Backend server container startup:
docker run -dp 3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:12-alpine \
sh -c "yarn install && yarn run dev"
# Database server container startup:
docker run -d \
--network todo-app \
--network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
|
From this, we can create the following docker-compose.yml
file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| # Docker Compose version: *https://docs.docker.com/compose/compose-file/*
version: "3.7"
# The list of containers we want to run
services:
app: # You can pick any name for the service. This will later become the network alias. See https://docs.docker.com/engine/reference/commandline/network_connect/#create-a-network-alias-for-a-container.
image: node:12-alpine # Base image
command: sh -c "yarn install && yarn dev" # Command to run on startup. Note that the `-c` tells `sh` to run the given string
ports:
- 3000:3000
working_dir: /app
volumes: # Volume mapping
- ./:/app
environment:
MYSQL_HOST: mysql # This should be the same as the **network alias** of the database server
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:5.7
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
# Named volumes *aren't automatically created* with Docker-Compose. They need to be listed:
volumes:
todo-mysql-data:
|
Note: Docker Compose does not replace your Dockerfile. See this relevant
StackOverflow post.
Now you just need to run docker-compose up -d
and both these containers will be created, along with an isolated network and the volumes you listed:

# Docker Compose vs. Kubernetes
The main difference is that Kubernetes can run and scale containers across multiple computers, but Docker Compose runs containers on a single host machine.
If you are networking containers within the same host go for docker compose. If you are networking containers across multiple hosts go for kubernetes. (
source)
(Sourced from
theserverside)