BuildKit меняет правила игры для создания образов Docker, использующих частные реестры NPM.

Несмотря на то, что я написал модуль NPM специально для упрощения публикации образов Docker, зависящих от частных реестров NPM, я должен сказать, что мне никогда не нравилось, как это делалось в прошлом. Но с использованием BuildKit процесс становится проще, быстрее и безопаснее. Это меняет правила игры, и я хотел написать объяснение, почему.

Итак, давайте рассмотрим старый способ создания контейнеров Docker, использующих частные репозитории. Нам не нужно смотреть дальше текущей (на момент написания) документации для NPM. Честно говоря, немного шокирует то, что BuildKit вышел в июле 2018 года, а люди до сих пор не используют его. Но я забегаю вперед.

Таким образом, «старый» способ создания этих контейнеров состоит в том, чтобы скопировать файл шаблона .npmrc в ваш контейнер Docker и предоставить --build-arg параметр командной строки, позволяющий вам вводить во время сборки токен NPM, необходимый для доступа к частный репозиторий. Этот процесс требует сложного Dockerfile, дополнительных аргументов командной строки для docker build, специального файла шаблона .npmrc, и мне всегда нужно искать тонкости безопасной обработки токена. Он также добавляет к образу Docker пару простых слоев.

Введите флаг --secret для docker build. Если вы хоть немного похожи на меня, вы даже не знали, что для docker build есть --secret флаг. И в некотором смысле вы были бы правы, потому что вам нужно установить специальный флаг среды, чтобы использовать BuildKit, который обеспечивает лучшую обработку секретов.

Так почему это полезно? Что ж, то, что мы раньше писали как (из документации NPM):

FROM risingstack/alpine:3.3-v4.3.1–3.0.1
ARG NPM_TOKEN
COPY .npmrc .npmrc
COPY package.json package.json
RUN npm install
RUN rm -f .npmrc

Теперь мы можем написать так:

# syntax = docker/dockerfile:1.0-experimental
FROM risingstack/alpine:3.3-v4.3.1–3.0.1
COPY package.json package.json
RUN --mount=type=secret,id=npmrc,dst=/root/.npmrc npm install

--mount в команде RUN - это расширение BuildKit, которое позволяет смонтировать секрет с именем npmrc в /root/.npmrc (NB: где его нужно смонтировать, зависит от вашего FROM оператора). Этот секрет не копируется в образ сборки и монтируется только при запуске npm install. Нет больше ARG, нет больше файлов шаблонов .npmrc, больше нет — build-arg аргументов командной строки, больше не нужно убирать за собой. Просто смонтируйте секреты (используя ваш существующий и уже авторизованный .npmrc файл), выполняя команды, которые требуют их, а затем размонтируйте их.

И последнее замечание: чтобы это сработало, вы должны как включить комментарий # syntax в свой Dockerfile, так и включить функциональность BuildKit, что означает, что ваша команда docker build должна выглядеть так:

DOCKER_BUILDKIT=1 docker build --secret id=npmrc,src=$HOME/.npmrc .

Прошло почти два года с тех пор, как BuildKit был интегрирован в docker build. Ясно, что это хорошо хранится в секрете (каламбур), поскольку за эти два года он ускользнул от моего взгляда и, по-видимому, от взгляда людей, которые поддерживают документацию NPM по этой теме. Более того, это все еще очевидно «экспериментальное», о чем свидетельствует заголовок # syntax в Dockerfile и необходимость в переменной среды DOCKER_BUILDKIT. Надеюсь, что в какой-то момент в не столь отдаленном будущем это больше не будет считаться экспериментальной функциональностью, так что обе эти вещи будут удалены, и единственное, что потребуется, - это параметр --mount в директиве RUN.

Дело в том, что этот функционал есть, и он работает. Таким образом, вы обязательно должны использовать его, поскольку он обеспечивает чистый и простой способ обработки секретов. Кроме того, BuildKit включает в себя множество других улучшений.