Modern applications rely on multiple components, or services, such as database, back-end, front-end, web API, and file sharing. Managing these components can be a difficult task because of the update and security tasks.
Docker compose allows the coordination of multiple containers on a single host. It includes two components : the docker-compose command which helps managing the containers and the docker compose file which defines the services and resources.
Docker compose is included as part of the docker desktop. On Linux, you need to install it after installing the docker engine.
When working with docker compose, we talk about services instead of containers. Services are similar to containers, but they are scaled up and down, restarted if stopped, and can run on multiple nodes.
The process of working with docker compose can be summarized into three steps:
- Specify the images using docker files
- Define the services using the docker-compose.yml file
- Start the services using the command docker-compose up
A docker compose file describes how to run services needed by an application. The file contains all the options of the docker container run
, docker volume create
, and docker network create
commands written in YAML format. This file describes the resources for each service such as images, volumes, ports, and networks.
Docker compose file has multiple configuration options. We have chosen the important ones.
Docker compose file follows a specific format. The latest major version format is the version 3. It is important to state the format at the beginning of the file to let the interpreter correctly processes the file.
version: "3"
The services key allows the definition of services. All services should be under the services key.
version: "3.8"
services:
web:
build: ./web
db:
build: ./db
Specifies the path to the Dockerfile to build the image.
build: .
build: ./web
build:
context: ./db
dockerfile: dockerfile-database.prod
Overrides the default CMD command in the Dockerfile. It specifies the command to be executed once the service started.
command: npm run start
command: ["dotnet", "myapp.dll"]
States the services that the current service depends on. This option permits the starting and stopping of services according to the indicated dependency order.
depends_on:
- db
- cache
Overrides the entry point that is set in the dockerfile using the ENTRYPOINT instruction. In addition, the CMD instruction is also ignored.
entrypoint: /app/entrypoint.sh
Specifies environment variables for the service. It helps in configuring the services since these variables are available inside the service.
environment:
DEBUG=1
DISPLAY='true'
DB_USER=postgres
Boolean values (true, false, yes, no) should be enclosed between quotes. Otherwise, they will be processed by the YAML interpreter.
Specifies single of multiple files that contain a list of environment variables in the form VARIABLE=VALUE.
# .env file
MYVAR=MYVAL
DEBUG="1"
# docker-compose.yml file
env_file: .env
env_file:
- ./file1.env
- /app/file2.env
Exposes ports of the service to other linked services running on the same network. These ports are not exposed to the host (see ports option). Numbers should be enclosed between quotes.
expose:
- "80"
- "22"
Specifies the docker image used to start the service.
image: mysql
image: alpine:3.1
image: myuser/myimage:latest
image: myrepo.com/ubuntu
image: a234bc5
The presence of both build and image options allows the building of the image from the dockerfile specified in the build and name the image with the tag in the image option.
build: ./web
image: myweb:latest
Specifies the networks the service should join.
networks:
- backend-network
- frontend-network
Exposes and maps ports between the host and the container. The format is host-port:container-port. Put the mapping between quotes. If the host port is not specified, a random port is selected for the host.
ports:
- "8080:80"
- "5000:123"
- "6070:6672/udp" # specify the protocol
The values should be enclosed within quotes because of the colon (:) that can be interpreted by YAML.
States the restart policy for a service.
restart: no # no restart under any circumstance
restart: always # always restart
restart: on-failure # restart if their is a failure
restart: unless-stopped # restart except when stopped
Mounts a temporary filesystem in the container.
tmpfs: /tempdir
tmpfs:
- /datafs
- /tempfs
Specifies the host path or a volume to mount inside the container. Volumes are invoked under service and as a top level key.
The top level volumes key is used to define named volumes that are used under services.
services:
web:
volumes:
- /var/share # create a volume
- "mydata:/data" # named volume
- "/public/data:/shared" # absolute path
db:
volumes:
- "dbdata:/var/database" # named volume
- "./cache:/var/cache" # relative path to compose file
volumes:
mydata: # defined in web service
dbdata: # defined in db service