
Комментарии 7
Для сборки образа в CI/CD так же можно использовать buildkit rootless, если по каким-то причинам podman/buildah не подходит.
Да, согласен. BuildKit без рут прав - хороший вариант для сборки образов в CI/CD, особенно если хочется уйти от привилегированного Docker-in-Docker, а podman/buildah по каким-то причинам не подходят.
Там есть конечно свои нюансы с раннером, кешем, правами, сторедж и сетью, но как отдельный рабочий вариант безопасной сборки образов без рут доступа, это вполне уместно.
Спасибо за комментарий, он в какой-то мере даже дополнил статью.
А как же Dockerfile syntax?
ADD можно оставить только для редкого случая, когда вам действительно нужна автоматическая распаковка локального tar-архива и вы контролируете этот архив.
Ну как так-то… ADD умеет делать это лучше, чем приведенный сниппет.
Сравниваем:
RUN set -eux; \
curl -fsSLo /tmp/tool.tar.gz "https://example.com/tool-${TOOL_VERSION}.tar.gz"; \
echo "${TOOL_SHA256} /tmp/tool.tar.gz" | sha256sum -c -; \
tar -xzf /tmp/tool.tar.gz -C /usr/local/bin; \
rm -f /tmp/tool.tar.gz
Против
ADD --unpack=true \
--checksum sha256:${TOOL_SHA256} \
https://example.com/tool-${TOOL_VERSION}.tar.gz /usr/local/bin
При этом ADD лучше работает с кэшами, не требует наличия в образе curl, tar, shasum и даже шелла. И не запускает qemu для не-нативных архитектур.
Двльше, очень нужно рассказать всем и везде, что Dockerfile поддерживает heredoc. И это очень полезно в первую очередь для RUN. Сравниваем на том же самом сниппете:
RUN set -eux; \
curl -fsSLo /tmp/tool.tar.gz "https://example.com/tool-${TOOL_VERSION}.tar.gz"; \
echo "${TOOL_SHA256} /tmp/tool.tar.gz" | sha256sum -c -; \
tar -xzf /tmp/tool.tar.gz -C /usr/local/bin; \
rm -f /tmp/tool.tar.gz
Против
RUN << EOF
set -eux
curl -fsSLo /tmp/tool.tar.gz "https://example.com/tool-${TOOL_VERSION}.tar.gz"
echo "${TOOL_SHA256} /tmp/tool.tar.gz" | sha256sum -c -
tar -xzf /tmp/tool.tar.gz -C /usr/local/bin
rm -f /tmp/tool.tar.gz
EOF
Чем сложнее операции по сборке, тем нужнее эта фича. А если уж там 5-10 опций --mount для всяких кэшей и прочего добавить, то вообще незаменимая штука.
К слову об архитектурах.
Я бы еще добавил в секцию о multi-stage рекомендацию настраивать кросс-компиляцию и исполнять билд-стадию нативно, вот так:
ARG BUILDPLATFORM
# Run build stage on host-native architecture
FROM --platform=${BUILDPLATFORM} ${BUILD_BASE} AS build
ARG TARGETARCH
ARG BUILDARCH
RUN --mount=... --mount=... --mount=... << EOF
if [[ "${BUILDARCH}" != "${TARGETARCH}" ]; then
# setup cross-compilation
fi
# compile
make -j`nproc` all
# install
make -j`nproc` install DESTDIR=/dest
EOF
# For target architecture just copy files from build stage without executing anything.
FROM ${BASE}
COPY --from=build /dest /
Если этого не делать, то при сборке мультплатформенных образов нативная для хоста архитектура будет собираться нормально, а вот все остальные будут собираться в qemu и это очень медленно.
Ну и на сладкое нужно упомянуть docker buildx bake, он пока довольно сырой, но уже позволяет гораздо более удобным способом управлять более сложными конфигурациями, когда требуется несколько вариантов образа и/или несколько вызовов докера для получения нужного результата.
Буквально пару недель назад переделывал контейнер одного сервиса. Раньше, там был alpine, gcc, и несмотря на настроенный multi-stage, нормально сборку никто не настраивал и не оптимизировал.
Я перевел с gcc на llvm/clang/lld, добавил варианты образов с сантиайзерами, внедрил кросс-компиляцию и 11 стадий сборки, за счет чего полностью избавился от сборки внутри qemu. Разобрался с кэшами и еще кучей всего. В результате, теперь сервис собирается за пять минут вместо полутора часов, при том, что сборка теперь делает в несколько раз больше полезных артефактов.
После вашего комментария специально копнул глубже, перепроверил актуальные возможности Dockerfile/BuildKit и подкорректировал статью: переписал блок про ADD, добавил пояснение про heredoc и отдельно отметил multi-platform сборки с нативной build-стадией и кросс-компиляцией. Спасибо — это как раз тот случай, когда комментарий не просто уточняет деталь, а реально усиливает материал.
Какая сокровищница! Спасибо!
Best Practices по Dockerfile: от базового образа и кеша до SBOM, Cosign и CI/CD