Every few years, a paradigm shift occurs in the software development industry. One of these phenomena is the growing interest in the concept of microservices. Although microservices is not the latest technology, only recently has its popularity literally skyrocketed.Large monolithic services these days are replaced by independent autonomous microservices. A microservice can be considered as an application that serves a single and very specific purpose. For example, it can be a relational DBMS, Express application, Solr service. Nowadays it is difficult to imagine the development of a new software system without the use of microservices. And this situation, in turn, leads us to the Docker platform.
Docker
The Docker platform , in the development and deployment of microservices, has become an almost industry standard. On the project’s website, you can find out that Docker is the only independent containerization platform that allows organizations to effortlessly create any applications, as well as distribute and run them in any environment - from hybrid clouds to border systems.Docker compose
Docker Compose
technology is designed to configure multi-container applications. A Docker Compose project can include as many Docker containers as the creator of this project needs.When working with Docker Compose, a YAML file is used to configure application services and organize their interaction with each other. Docker Compose is thus a tool for describing and running Docker multi-container applications.Two containers running on the host systemGNU Make
A program make
is essentially a tool for automating the assembly of programs and libraries from source code. In general, we can say that it is make
applicable to any process that includes the execution of arbitrary commands for converting certain source materials to a certain resulting form, to a certain goal. In our case, the teams docker-compose
will be converted to abstract goals ( Phony targets ).In order to tell the program make
what we want from it, we need a file Makefile
.Ours Makefile
will contain the usual commands docker
anddocker-compose
that are designed to solve many problems. Namely, we are talking about assembling a container, about starting, stopping, restarting it, about organizing a user’s login to the container, about working with container logs and about solving other similar problems.Typical Uses for Docker Compose
Imagine a regular web application that has the following components:- TimescaleDB Database (Postgres).
- Express.js application.
- Ping (just a container that does nothing special).
This application will need 3 Docker containers and a file docker-compose
containing instructions for managing these containers. Each of the containers will have different points of interaction. For example, timescale
you can work with a container in much the same way that you work with databases. Namely, it allows you to perform the following actions:- Login to Postgres shell.
- Import and export tables.
- Create a
pg_dump
table or database.
The container of an Express.js application,, expressjs
may have the following features:- The output of fresh data from the system log.
- Enter the shell to execute certain commands.
Container Interaction
After we configured the connection between containers using Docker Compose, it's time to establish interaction with these containers. As part of the Docker Compose system, there is a command docker-compose
that supports an option -f
that allows you to transfer a file to the system docker-compose.yml
.Using the capabilities of this option, you can limit interaction with the system only to those containers that are mentioned in the file docker-compose.yml
.Take a look at how container interactions look when using commands docker-compose
. If we imagine that we need to enter the shell psql
, then the corresponding commands may look like this:docker-compose -f docker-compose.yml exec timescale psql -Upostgres
The same command for which not docker-compose
, but is used docker
, may look like this:docker exec -it edp_timescale_1 psql -Upostgres
Please note that in such cases it is always preferable to use not a command docker
, but a command docker-compose
, since this eliminates the need to remember the names of the containers.Both of the above commands are not so complicated. But if we used the “wrapper” in a form Makefile
that would give us an interface in the form of simple commands and call such long commands ourselves, then the same results could be achieved like this:make db-shell
It is obvious that the use Makefile
greatly simplifies the work with containers!Working example
Based on the above project diagram, create the following file docker-compose.yml
:version: '3.3'
services:
api:
build: .
image: mywebimage:0.0.1
ports:
- 8080:8080
volumes:
- /app/node_modules/
depends_on:
- timescale
command: npm run dev
networks:
- webappnetwork
timescale:
image: timescale/timescaledb-postgis:latest-pg11
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
command: ["postgres", "-c", "log_statement=all", "-c", "log_destination=stderr"]
volumes:
- ./create_schema.sql:/docker-entrypoint-initdb.d/create_schema.sql
networks:
- webappnetwork
ping:
image: willfarrell/ping
environment:
HOSTNAME: "localhost"
TIMEOUT: 300
networks:
webappnetwork:
driver: bridge
To manage the Docker Compose configuration and to interact with the containers that it describes, create the following file Makefile
:THIS_FILE := $(lastword $(MAKEFILE_LIST))
.PHONY: help build up start down destroy stop restart logs logs-api ps login-timescale login-api db-shell
help:
make -pRrq -f $(THIS_FILE) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
build:
docker-compose -f docker-compose.yml build $(c)
up:
docker-compose -f docker-compose.yml up -d $(c)
start:
docker-compose -f docker-compose.yml start $(c)
down:
docker-compose -f docker-compose.yml down $(c)
destroy:
docker-compose -f docker-compose.yml down -v $(c)
stop:
docker-compose -f docker-compose.yml stop $(c)
restart:
docker-compose -f docker-compose.yml stop $(c)
docker-compose -f docker-compose.yml up -d $(c)
logs:
docker-compose -f docker-compose.yml logs --tail=100 -f $(c)
logs-api:
docker-compose -f docker-compose.yml logs --tail=100 -f api
ps:
docker-compose -f docker-compose.yml ps
login-timescale:
docker-compose -f docker-compose.yml exec timescale /bin/bash
login-api:
docker-compose -f docker-compose.yml exec api /bin/bash
db-shell:
docker-compose -f docker-compose.yml exec timescale psql -Upostgres
Most of the commands described here apply to all containers, but using the option c=
allows you to limit the scope of the command to one container.Once Makefile
ready, you can use it like this:make help
- issuing a list of all the commands available for make
.
Available Commands Helpmake build
- assembly of the image from Dockerfile
. In our example, we used existing images timescale
and ping
. But api
we want to collect the image locally. This is exactly what will be done after executing this command.
Docker container assemblymake start
- launch of all containers. To start only one container, you can use the command of the form make start c=timescale
.
Launch timescale containerLaunch ping containermake login-timescale
- entry into the bash session of the container timescale
.
Running bash in timescale containermake db-shell
- Log in psql
to the container timescale
to execute SQL queries to the database.
Running psql in timescaledb containermake stop
- stopping containers.
Stopping the timescale containermake down
- stop and remove containers. To delete a specific container, you can use this command with the specified container. For example - make down c=timescale
or make down c=api
.
Stop and delete all containersSummary
Despite the fact that the Docker Compose system gives us an extensive set of commands designed to manage containers, sometimes these commands become long, and as a result they can be difficult to remember.The methodology of use Makefile
helped us establish quick and easy interaction with containers from the file docker-compose.yml
. Namely, we are talking about the following:- ,
docker-compose.yml
, . - , ,
make help
. - , . ,
docker-compose -f docker-compose.yml exec timescale psql -Upostgres
make db-shell
. Makefile
, , . , .Makefile
, .
PS In our marketplace there is a Docker image , which is installed in one click. You can check the operation of containers on VPS . All new customers are given 3 days free of charge for testing.Dear readers! How do you automate work with Docker Compose?