Containerized Tooling
В своей работе мы постоянно используем различные инструменты: protoc
,
golangci-lint
, allure
и многие другие.
Чтобы избежать ситуации, в которой версия или конфигурация инструмента у одного
разработчика отличается от того, что уже установлено у другого, или от того, что
настроено в CI
, наши инструменты “запечены” в контейнеры.
Контейнеры с инструментами сами собираются на CI
и доступны как на локальных
машинах для разработки и отладки, так и с пайплайнах CI
. Это позволяет иметь
единую конфигурацию и сквозное версионирование всех инструментов во всех
окружениях.
Мы системно подошли к вопросу контейнеризации нашего тулинга:
- Создан базовый шаблон репозитория инструмента (boilerplate);
- Выделена отдельная группа проектов под названием
tooling
; - Внутри группы
tooling
на каждый инструмент создан отдельный репозиторий.
Все репозитории имеют единый общий пайплайн сборки и публикации во внутреннем реестре образов.
Группа проектов может иметь такой вид:
tree -a -C -L 2 tooling
tooling
├── golangci-lint
│ ├── .env
│ ├── .git
│ ├── Dockerfile
│ ├── Makefile
│ ├── README.md
│ ├── entrypoint.sh
│ └── golangci.yaml
├── protoc
│ ├── .env
│ ├── .git
│ ├── Dockerfile
│ ├── Makefile
│ ├── README.md
...
За конфигурацию отвечает файл .env
, обычно в нём задаётся имя образа:
IMAGE_NAME=internal-registry.dmz/dx/tooling/cowsay
В каждом репозитории присутствует шаблонный Makefile
, который может
незначительно отличаться от других, если требуются какие-либо дополнительные
действия. .env
-файл подключается в Makefile
в самой первой строке:
include .env
.DEFAULT_GOAL := build
.PHONY: build
build:
docker build --tag ${IMAGE_NAME} .
Собственно, Dockerfile
не требует какого-то отдельного описания, приведу здесь
максимально простой пример:
# syntax=docker/dockerfile:1
FROM ubuntu
RUN <<EOF
apt-get update
apt-get upgrade -y
apt-get install -y cowsay
EOF
WORKDIR /workdir
ENTRYPOINT ["/usr/games/cowsay"]
Следует обратить внимание на две вещи, которые могут быть неочевидными:
- Комментарий в первой строке
# syntax=docker/dockerfile:1
включает возможность использоватьHEREDOC
— он использован в директивеRUN
; - Вместо директивы
CMD
используетсяENTRYPOINT
— это даёт возможность передавать аргументы для этой команды при запуске контейнера.
Благодаря подходу к контейнеризации инструментов моя команда получила:
- Прозрачность и простоту “установки” и запуска инструментов в локальной среде;
- Единообразие версий инструментов в локальной среде и на
CI
; - Общую и единую конфигурацию инструментария для всех проектов.