🌱 Tim's Dev Wiki

Search IconIcon to open search

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.

 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)