Docker Compose is a tool that allows you to describe (in a YAML file) and manage (in command line) several containers as a set of interconnected services.
Let´s assume we are working on a Rails application with 2 dependancies : PostgreSQL & Redis. we will for example create 3 containers:
- a PostgreSQL container
- a Redis container
- a container for our application code
We will then be able to start our set of containers with a single docker-compose up command.
Without Docker Compose, we would have had to run 3 docker run commands with a lot of arguments to achieve the same result. In addition, it would have required that we write a rather precise README so that the other members of the team obtain the same result. With Docker Compose, this configuration is done in a file that is versioned with the rest of the application code.
In the docker-compose.yml file, each container is described with a set of parameters that correspond to the options available during a docker run: the image to use, the volumes to mount, the ports to open, etc.
Here is an example of a Docker Compose configuration file:
version: "2"
services:
db:
image: postgres
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
Installation
Docker Compose is not installed with Docker. It is therefore necessary to install it before you can use it.
Here is its installation on Linux (Ubuntu)
apt install docker-compose
Some useful commands
- docker-compose up starts the services described in the docker-compose.yml and does not give the cursor (shell) back.
- docker-compose up -d starts the services described in the docker-compose.yml and returns (shell) control to us once the services are started.
- docker-compose pull refresh all the services with the latest version . (Pulls an image associated with the service defined in
docker-compose.yml
).
- docker-compose up –build rebuilds services before launching them.
- docker-compose down stops the services.
- docker-compose restart restarts all services.
- docker-compose restart <service> restarts one specified services.
- docker-compose exec <service> bash. Provides a bash console on one of the services. We can add the option -it for interactive purpose: ( docker-compose -it exec <service> bash)
- docker-compose logs returns all service logs since the last start and gives us the (shell) control back.
- docker-compose logs -f displays service logs and continues to “listen” to them without giving us (shell) controls back.
- docker-compose logs -f <service>Display the logs on one of the services/container only and continue listening to them
Difference between docker-compose and Dockerfile
The key difference between the Dockerfile and docker-compose is that the Dockerfile describes how to build Docker images, while docker-compose
is used to describe how to run Docker images as set of containers.
For example, a Dockerfile that describes how to create a custom Nginx image that hosts your HTML files might look like this:
FROM nginx:latest
COPY ./hello-world.html /usr/share/nginx/html/
When the image is assembled, this Dockerfile tells the docker build
command to start with the latest Nginx image, and then to copy your hello-world.html file into the file serving folder of Nginx.
Dockerfile image building
To create a new, custom image based on this example Dockerfile, run the docker build
command
$ docker build -t my-nginx-image:latest .
Note that the dot at the end tells the docker build
command to look for the Dockerfile in the current directory. Leave this out and you’ll get the “docker build requires exactly 1 argument” error.
After this command runs, a query of the Docker images installed on your local computer includes an image named my-nginx-image in the listing:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-nginx-image latest c58ef9bfbb57 7 days ago 144MB
a docker-compose.yaml file that describes how to run the image created with the Dockerfile above might look like this:
version: '3.9'
services:
my-nginx-service:
container_name: my-website
image: my-nginx-image:latest
cpus: 1.5
mem_limit: 2048m
ports:
- "8080:80"