Build Checks в Docker: как проверять конфигурацию сборки

Docker Build Checks — новая функция, представленная в Dockerfile 1.8, которая позволяет проверять и валидировать конфигурацию сборки до её выполнения. По сути, это продвинутый инструмент линтинга для Dockerfile и опций сборки.

Как это работает

В обычном процессе создания образа Docker выполняет шаги сборки, указанные в Dockerfile. При использовании проверок сборки Docker вместо выполнения шагов проверяет Dockerfile и предоставленные опции, сообщая о выявленных проблемах.

Проверки сборки полезны для:

  • Валидации Dockerfile и параметров сборки перед их запуском
  • Соответствия последним лучшим практикам
  • Выявления потенциальных проблем или анти-паттернов

Поддержка проверок сборки

Проверки сборки поддерживаются в:

  • Buildx версии 0.15.0 и выше
  • Действиях GitHub docker/build-push-action версии 6.6.0 и выше
  • Действиях GitHub docker/bake-action версии 5.6.0 и выше

Пример использования

Проверки в процессе обычной сборки

Создайте простой Dockerfile с проблемой:

FROM alpine
CMD echo "Hello, world!"

При обычной сборке проверки запускаются автоматически и отображают нарушения в выводе:

$ docker build .
[+] Building 3.5s (11/11) FINISHED
...

1 warning found (use docker --debug to expand):
- JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 2)

В этом примере сборка прошла успешно, но появилось предупреждение JSONArgsRecommended, указывающее, что инструкции CMD следует использовать синтаксис массива JSON.

Исправленный Dockerfile будет выглядеть так:

FROM alpine
CMD ["echo", "Hello, world!"]

Подробный вывод проверок

Для получения более подробной информации о проверках можно использовать флаг --debug:

$ docker --debug build .
[+] Building 3.5s (11/11) FINISHED
...

1 warning found:
- JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 2)
JSON arguments recommended for ENTRYPOINT/CMD to prevent unintended behavior related to OS signals
More info: https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
Dockerfile:2
--------------------
1 | FROM alpine
2 | >>> CMD echo "Hello, world!"
3 |
--------------------

С флагом --debug в выводе содержится ссылка на документацию и фрагмент Dockerfile, где была обнаружена проблема.

Проверка без выполнения сборки

Для запуска проверок без фактической сборки используйте команду с флагом --check:

$ docker build --check .

Пример вывода для нашего Dockerfile:

[+] Building 0.6s (3/3) FINISHED                           docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 111B 0.0s
=> [internal] load metadata for docker.io/library/alpine:latest 0.6s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
Check complete, 1 warning has been found!

WARNING: JSONArgsRecommended - https://docs.docker.com/go/dockerfile/rule/json-args-recommended/
JSON arguments recommended for CMD to prevent unintended behavior related to OS signals
Dockerfile:2
--------------------
1 | FROM alpine
2 | >>> CMD echo "Hello, world!"
3 |
--------------------

При использовании флага --check, если обнаружены нарушения, команда завершается с ненулевым кодом статуса.

Настройка проверок

Прерывание сборки при нарушениях

По умолчанию нарушения проверок выводятся как предупреждения с кодом выхода 0. Можно настроить Docker для прерывания сборки при обнаружении нарушений, используя директиву check=error=true в Dockerfile:

# check=error=true

FROM alpine
CMD echo "Hello, world!"

С этой директивой сборка завершится с ненулевым кодом выхода при обнаружении нарушений:

$ docker build .
[+] Building 1.5s (5/5) FINISHED
...

1 warning found (use docker --debug to expand):
- JSONArgsRecommended: JSON arguments recommended for CMD to prevent unintended behavior related to OS signals (line 4)
ERROR: failed to solve: lint violation found for rules: JSONArgsRecommended
$ echo $?
1

Также можно задать директиву ошибки через CLI:

$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=error=true" .

Пропуск определенных проверок

Для пропуска определенных проверок используйте директиву check=skip в Dockerfile:

# check=skip=JSONArgsRecommended

FROM alpine AS BASE_STAGE
CMD echo "Hello, world!"

В этом примере мы пропускаем проверку JSONArgsRecommended, поэтому сборка будет успешной, несмотря на нерекомендуемый формат CMD, но будет ошибка связанная с BASE_STAGE:

$ docker build .
...
1 warning found (use docker --debug to expand):
- StageNameCasing: Stage name 'BASE_STAGE' should be lowercase (line 3)

Можно также пропускать несколько проверок:

# check=skip=JSONArgsRecommended,StageNameCasing

FROM alpine AS BASE_STAGE
CMD echo "Hello, world!"

Эквивалентно через CLI:

$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended,StageNameCasing" .

Для пропуска всех проверок используйте параметр skip=all:

# check=skip=all

FROM alpine
CMD echo "Hello, world!"

Комбинирование параметров error и skip

Чтобы как пропускать определенные проверки, так и вызывать ошибку при других нарушениях, используйте оба параметра, разделяя их точкой с запятой:

# check=skip=JSONArgsRecommended;error=true

FROM alpine
WORKDIR relative/path
CMD echo "Hello, world!"

В этом примере мы пропускаем проверку JSONArgsRecommended, но если будут найдены другие проблемы (например, относительный путь в WORKDIR), сборка завершится с ошибкой.

То же самое через CLI:

$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=skip=JSONArgsRecommended;error=true" .

Экспериментальные проверки

До перехода в стабильную версию проверки могут быть доступны как экспериментальные и по умолчанию отключены.

Чтобы включить все экспериментальные проверки, используйте:

$ docker build --check --build-arg "BUILDKIT_DOCKERFILE_CHECK=experimental=all" .

Или в Dockerfile:

# check=experimental=all

FROM alpine
COPY . .
CMD echo "Hello, world!"

Для выборочного включения экспериментальных проверок передайте список идентификаторов:

# check=experimental=CopyIgnoredFile

FROM alpine
COPY . .
CMD echo "Hello, world!"

Директива experimental имеет приоритет над директивой skip. Например, при установке skip=all и включении экспериментальных проверок, последние все равно будут выполняться:

# check=skip=all;experimental=all

FROM alpine
COPY . .
CMD echo "Hello, world!"

Доступные правила проверки

Build Checks включает набор предопределенных правил для обеспечения лучших практик:

ПравилоОписание
StageNameCasingИмена этапов должны быть в нижнем регистре
FromAsCasingКлючевое слово as должно соответствовать регистру ключевого слова from
NoEmptyContinuationПустые строки продолжения станут ошибками в будущих релизах
ConsistentInstructionCasingВсе команды в Dockerfile должны использовать одинаковый регистр
DuplicateStageNameИмена этапов должны быть уникальными
ReservedStageNameЗарезервированные слова не следует использовать в качестве имен этапов
JSONArgsRecommendedРекомендуется использовать JSON-аргументы для ENTRYPOINT/CMD
MaintainerDeprecatedИнструкция MAINTAINER устарела, используйте метку для определения автора
UndefinedArgInFromКоманда FROM должна использовать объявленные ARG
WorkdirRelativePathОтносительные пути в workdir могут дать непредсказуемые результаты
UndefinedVarПеременные должны быть определены до их использования
MultipleInstructionsDisallowedНе следует использовать несколько инструкций одного типа на одном этапе
LegacyKeyValueFormatУстаревший формат ключ/значение с разделителем-пробелом не следует использовать
RedundantTargetPlatformУстановка платформы на предопределенный $TARGETPLATFORM избыточна
SecretsUsedInArgOrEnvКонфиденциальные данные не должны использоваться в командах ARG или ENV
InvalidDefaultArgInFromЗначение по умолчанию для глобального ARG приводит к пустому имени образа
FromPlatformFlagConstDisallowedФлаг FROM --platform не должен использовать константное значение

Экспериментальные правила:

  • CopyIgnoredFile: Попытка скопировать файл, исключенный .dockerignore
  • InvalidDefinitionDescription: Комментарии должны следовать определенному формату

Build Checks — мощный инструмент, который поможет разработчикам следовать лучшим практикам при создании Dockerfile и улучшить качество процесса сборки Docker-образов.