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
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:
# 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:
# 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)