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-образов.