Большие монолитные сервисы в наши дни заменяют независимыми автономными микросервисами. Микросервис можно рассматривать как приложение, которое служит единственной и очень специфической цели. Например — это может быть реляционная СУБД, Express-приложение, Solr-сервис.
В наши дни сложно представить себе разработку новой программной системы без применения микросервисов. А эта ситуация, в свою очередь, ведёт нас к платформе Docker.
Docker
Платформа Docker, в деле разработки и развёртывания микросервисов, стала практически индустриальным стандартом. На сайте проекта можно узнать о том, что Docker — это единственная независимая платформа контейнеризации, которая позволяет организациям без особых усилий создавать любые приложения, а также распространять и запускать их в любых средах — от гибридных облаков, до пограничных систем.
Docker Compose
Технология Docker Compose предназначена для конфигурирования многоконтейнерных приложений. В Docker Compose-проект может входить столько контейнеров Docker, сколько нужно создателю этого проекта.
При работе с Docker Compose для настройки сервисов приложения и организации их взаимодействия друг с другом используется YAML-файл. Docker Compose, таким образом, это инструмент для описания и запуска многоконтейнерных приложений Docker.

Два контейнера, работающие на хост-системе
GNU Make
Программа make, по существу, представляет собой инструмент для автоматизации сборки программ и библиотек из исходного кода. В целом, можно говорить о том, что make применима к любому процессу, который включает в себя выполнение произвольных команд для преобразования неких исходных материалов к некоему результирующему виду, к некоей цели. В нашем случае команды docker-compose будут преобразовываться в абстрактные цели (Phony targets).
Для того чтобы сообщить программе make о том, чего мы от неё хотим, нам понадобится файл Makefile.
В нашем Makefile будут содержаться обычные команды docker и docker-compose, которые предназначены для решения множества задач. А именно, речь идёт о сборке контейнера, о его запуске, остановке, перезапуске, об организации входа пользователя в контейнер, о работе с логами контейнера и о решении других подобных задач.
Типичные варианты использования Docker Compose
Представим себе обычное веб-приложение, в котором имеются следующие компоненты:
- База данных TimescaleDB (Postgres).
- Express.js-приложение.
- Ping (просто контейнер, ничего особенного не делающий).
Этому приложению понадобится 3 контейнера Docker и файл docker-compose, содержащий инструкции по управлению этими контейнерами. Каждый из контейнеров будет обладать разными точками взаимодействия. Например, с контейнером timescale можно будет работать примерно так, как работают с базами данных. А именно, он позволяет выполнять следующие действия:
- Вход в оболочку Postgres.
- Импорт и экспорт таблиц.
- Создание
pg_dumpтаблицы или базы данных.
Контейнер Express.js-приложения, expressjs, может обладать следующими возможностями:
- Выдача свежих данных из системного журнала.
- Вход в оболочку для выполнения неких команд.
Взаимодействие с контейнерами
После того, как мы настроили связь между контейнерами с использованием Docker Compose, пришло время налаживания взаимодействия с этими контейнерами. В рамках системы Docker Compose имеется команда docker-compose, поддерживающая опцию -f, которая позволяет передавать системе файл docker-compose.yml.
Используя возможности этой опции, можно ограничить взаимодействие с системой только теми контейнерами, которые упомянуты в файле docker-compose.yml.
Взглянем на то, как выглядят взаимодействия с контейнерами при использовании команд docker-compose. Если представить, что нам нужно войти в оболочку psql, то соответствующие команды могут выглядеть так:
docker-compose -f docker-compose.yml exec timescale psql -Upostgres
Та же команда, для выполнения которой используется не docker-compose, а docker, может выглядеть так:
docker exec -it edp_timescale_1 psql -Upostgres
Обратите внимание на то, что в подобных случаях всегда предпочтительнее использовать не команду docker, а команду docker-compose, так как это позволяет избавиться от необходимости помнить имена контейнеров.
Обе приведённых выше команды не так уж и сложны. Но если бы мы воспользовались «обёрткой» в виде Makefile, которая давала бы нам интерфейс в виде простых команд и сама бы вызывала подобные длинные команды, то тех же результатов можно было бы добиться так:
make db-shell
Совершенно очевидно то, что использование Makefile значительно упрощает работу с контейнерами!
Рабочий пример
На основе вышерассмотренной схемы проекта создадим следующий файл 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
Для управления конфигурацией Docker Compose и для взаимодействия с контейнерами, которые она описывает, создадим следующий файл 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
Большинство описанных здесь команд применяются ко всем контейнерам, но использование опции c= позволяет ограничить область действия команды до одного контейнера.
После того, как Makefile готов, пользоваться им можно так:
make help— выдача перечня всех команд, доступных дляmake.

Справка по доступным командам
make build— сборка образа изDockerfile. В нашем примере мы использовали существующие образыtimescaleиping. Но образapiмы хотим собрать локально. Именно это и будет сделано после выполнения данной команды.

Сборка контейнера Docker
make start— запуск всех контейнеров. Для запуска лишь одного контейнера можно воспользоваться командой видаmake start c=timescale.

Запуск контейнера timescale

Запуск контейнера ping
make login-timescale— вход в bash-сессию контейнераtimescale.

Запуск bash в контейнере timescale
make db-shell— вход вpsqlв контейнереtimescaleдля выполнения SQL-запросов к базе данных.

Запуск psql в контейнере timescaledb
make stop— остановка контейнеров.

Остановка контейнера timescale
make down— остановка и удаление контейнеров. Для удаления конкретного контейнера можно использовать эту команду с указанием нужного контейнера. Например —make down c=timescaleилиmake down c=api.

Остановка и удаление всех контейнеров
Итоги
Несмотря на то, что система Docker Compose даёт в наше распоряжение обширный набор команд, предназначенных для управления контейнерами, иногда эти команды становятся длинными, в результате их бывает сложно запомнить.
Методика использования Makefile помогла нам наладить быстрое и простое взаимодействие с контейнерами из файла docker-compose.yml. А именно, речь идёт о следующем:
- Разработчик взаимодействует только с контейнерами проекта, описанными в
docker-compose.yml, работе не мешают другие запущенные контейнеры. - В том случае, если некая команда забыта, можно выполнить команду
make helpи получить справку по доступным командам. - Не нужно запоминать длинных списков аргументов для выполнения таких действий, как получение свежих записей журнала или вход в систему. Например, команда вида
docker-compose -f docker-compose.yml exec timescale psql -Upostgresпревращается вmake db-shell. - Файл
Makefileможно, по мере роста проекта, гибко под него подстраивать. Например, в него несложно добавить команду для создания резервной копии базы данных или для выполнения любого другого действия. - Если большая команда разработчиков пользуется одним и тем же
Makefile, это упорядочивает совместную работу и снижает количество ошибок.
P.S. В нашем маркетплейсе имеется образ Docker, который устанавливается в один клик. Вы можете проверить работу контейнеров на VPS. Всем новым клиентам бесплатно предоставляются 3 дня для тестирования.
Уважаемые читатели! Как вы автоматизируете работу с Docker Compose?
ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/486682/


Добавить комментарий