Docker Compose: Simplify your work with Makefile

Every few years, the software development industry experiences a paradigm shift. One of these phenomena can be recognized as the growing interest in the concept of microservices. Although microservices are not the newest technology, only recently its popularity has literally skyrocketed.

Large monolithic services are now being replaced by independent stand-alone microservices. A microservice can be thought of as an application that serves a single and very specific purpose. For example, it can be a relational DBMS, an Express application, a Solr service.

Docker Compose: Simplify your work with Makefile

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

Platform Docker, in the development and deployment of microservices, has become almost the industry standard. On the project website, you can learn 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 edge systems.

Docker Compose

Technology Docker Compose designed for configuring multi-container applications. A Docker Compose project can have as many Docker containers as the creator of that 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 multi-container Docker applications.

Docker Compose: Simplify your work with Makefile
Two containers running on a host system

GNU Make

Program make, in essence, is a tool for automating the assembly of programs and libraries from source code. In general, it can be said that make applicable to any process that involves the execution of arbitrary commands to transform some source material to some end result, to some purpose. In our case, the commands docker-compose will be converted to abstract targets (Phone targets).

To tell the program make about what we want from her, we need a file Makefile.

In our Makefile will contain the usual commands docker ΠΈ docker-composewhich are designed to solve many problems. Namely, we are talking about assembling a container, starting it, stopping it, restarting it, organizing a user entry into the container, working with container logs, and solving other similar tasks.

Typical use cases for Docker Compose

Imagine a typical web application that has the following components:

  • TimescaleDB (Postgres) database.
  • Express.js application.
  • Ping (just a container that doesn't do anything special).

This application will need 3 Docker containers and a file docker-composeA containing instructions for managing these containers. Each of the containers will have different interaction points. For example, with a container timescale it will be possible to work approximately the same as working with databases. Namely, it allows you to do the following:

  • Login to the Postgres shell.
  • Import and export of tables.
  • Creation pg_dump tables or databases.

Express.js application container, expressjs, may have the following features:

  • Issuance of fresh data from the system log.
  • Entering a shell to execute certain commands.

Interaction with containers

Now that we've set up communication between containers using Docker Compose, it's time to communicate with these containers. Within the Docker Compose system, there is a command docker-compose, supporting the option -f, which allows you to transfer the 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.

Let's take a look at what interactions with containers look like when using commands docker-compose. If we imagine that we need to enter the shell psql, then the corresponding commands might look like this:

docker-compose -f docker-compose.yml exec timescale psql -Upostgres

The same command, which is not used to execute docker-compose, docker, might look like this:

docker exec -it  edp_timescale_1 psql -Upostgres

Note that in such cases it is always preferable not to use the command docker, and the command docker-compose, as it eliminates the need to remember container names.

Both of the above commands are not that complicated. But if we used the "wrapper" in the form Makefile, which would give us an interface in the form of simple commands and would itself call such long commands, then the same results could be achieved like this:

make db-shell

It is clear that the use Makefile greatly simplifies the work with containers!

Working example

Based on the above project scheme, we will 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 it describes, let's 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 c= allows you to limit the scope of the command to a single container.

After Makefile ready, you can use it like this:

  • make help - issuing a list of all commands available for make.

Docker Compose: Simplify your work with Makefile
Help for available commands

  • make build - building an image from Dockerfile. In our example, we used existing images timescale ΠΈ ping. But the image api we want to build locally. This is exactly what will be done after executing this command.

Docker Compose: Simplify your work with Makefile
Building a Docker container

  • make start - start all containers. To run only one container, you can use a command like make start c=timescale.

Docker Compose: Simplify your work with Makefile
Running the timescale container

Docker Compose: Simplify your work with Makefile
Running a ping container

  • make login-timescale - login to the bash session of the container timescale.

Docker Compose: Simplify your work with Makefile
Running bash in a timescale container

  • make db-shell - entrance to psql in a container timescale to execute SQL queries against the database.

Docker Compose: Simplify your work with Makefile
Running psql in a timescaledb container

  • make stop - stop containers.

Docker Compose: Simplify your work with Makefile
Stopping the timescale container

  • make down - stopping and deleting containers. To remove a specific container, you can use this command, specifying the desired container. For example - make down c=timescale or make down c=api.

Docker Compose: Simplify your work with Makefile
Stop and delete all containers

Results

Even though the Docker Compose system gives us a rich set of commands for managing containers, sometimes these commands become long and hard to remember as a result.

Method of use Makefile helped us establish a quick and easy interaction with containers from a file docker-compose.yml. Namely, we are talking about the following:

  • The developer interacts only with the project containers described in docker-compose.yml, other running containers do not interfere with work.
  • In the event that a certain command is forgotten, you can execute the command make help and get help on available commands.
  • You don't have to remember long lists of arguments to perform things like getting fresh log entries or logging in. For example, a command like docker-compose -f docker-compose.yml exec timescale psql -Upostgres turns into make db-shell.
  • File Makefile You can, as the project grows, flexibly adjust to it. For example, it is easy to add a command to it to create a database backup or to perform any other action.
  • If a large development team uses the same Makefile, this streamlines collaboration and reduces errors.

PS In our marketplace there is an image Docker, which is installed in one click. You can check the containers work on VPS. All new customers are given 3 days of testing free of charge.

Dear Readers, How do you automate work with Docker Compose?

Docker Compose: Simplify your work with Makefile

Source: habr.com

Add a comment