惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
P
Privacy International News Feed
S
Securelist
Cisco Talos Blog
Cisco Talos Blog
V
Vulnerabilities – Threatpost
Know Your Adversary
Know Your Adversary
C
Check Point Blog
Simon Willison's Weblog
Simon Willison's Weblog
K
Kaspersky official blog
I
InfoQ
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
M
MIT News - Artificial intelligence
The Cloudflare Blog
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
Last Week in AI
Last Week in AI
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
博客园 - 三生石上(FineUI控件)
P
Proofpoint News Feed
博客园 - 【当耐特】
GbyAI
GbyAI
罗磊的独立博客
D
Docker
B
Blog
腾讯CDC
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
Scott Helme
Scott Helme
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
G
Google Developers Blog
T
Threatpost
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
Microsoft Security Blog
Microsoft Security Blog
T
Threat Research - Cisco Blogs
P
Privacy & Cybersecurity Law Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Мультистейдж-сборка на Docker BuildX: мифы и реальность
InfotecsTech · 2026-06-16 · via Все публикации подряд на Хабре

Привет, Хабр! С вами эксперты ИнфоТеКС. В современной ИТ-индустрии контейнеризация стала неотъемлемой частью разработки и эксплуатации систем. Docker, как один из ключевых инструментов, прочно вошёл в повседневную практику. Однако с ростом сложности проектов, особенно в микросервисной архитектуре, возникает проблема, которая может существенно замедлить процесс разработки — скорость сборки Docker-образов.

В этой статье мы рассмотрим тонкости использования Docker в нескольких подходах и возможные решения для оптимизации процесса сборки, которые позволят разработчикам повысить эффективность работы и сократить время на внесение изменений.

Содержание

  • Вкратце про подходы

  • Эволюция сборки Docker: от хаоса к оптимизации

  • Почему мы выбрали Docker Buildx?

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

  • Кеширование

  • Безопасность в Docker

  • Подводим итоги

Вкратце про подходы

Всё больше компаний и команд разработчиков переходят на использование контейнеров для создания и развёртывания новых сервисов. Это связано с тем, что контейнеры:

  • повышают гибкость и масштабируемость

  • упрощают управление зависимостями

Однако, несмотря на все преимущества, проблемой остаётся скорость сборки Docker-образов. Она является ключевым фактором в процессах CI/CD, особенно в проектах, основанных на микросервисной архитектуре. В условиях частых обновлений и необходимости быстрого внесения изменений разработчики сталкиваются с задачей оптимизации времени сборки.

На сегодняшний день существует два подхода к хранению кода:

Подход

Отдельные репозитории для каждого компонента/микросервиса, со своим набором данных и процессом сборки

Монорепозиторий, где весь код проекта хранится в одном репозитории, а все микросервисы строятся, проверяются и реализуются на одном и том же инструментарии

Плюсы

Скорость сборки.

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

Общие инструменты и зависимости, а также общая основа в виде базовых образов позволяют снизить количество проблем с совместимостью

Минусы

Всё собирается по отдельности, множество Docker-файлов и процессов. Когда количество сервисов превышает десятки, поддерживать каждый в актуальном состоянии становится проблематично

Время на сборку.

Все образы собираются одновременно, время сборки значительно увеличивается.

О решении этой проблемы мы и расскажем далее

Эволюция сборки Docker: от хаоса к оптимизации

ИнфоТеКС занимается разработкой ПО и аппаратных средств защиты информации. Проект, на примере которого мы рассмотрим работу с Docker BuildX, — управляющее ПО, комплекс приложений.

Ранее структура проекта была организована таким образом, что каждому микросервису соответствовал свой Dockerfile. Это создавало множество проблем:

  • Каждый сервис имел свой файл, что приводило к громоздкости и усложняло сопровождение.

  • Потенциально разные зависимости в проектах усложняли управление версиями и совместимостью.

  • Из-за одной ошибочной сборки в одном сервисе приходилось пересобирать приложение с нуля.

  • Добавление нового сервиса требовало значительных временных и ресурсных затрат.

Эта устаревшая структура не только замедляла процесс разработки, но и увеличивала ошибки, что в конечном итоге влияло на качество продукта.

На промежуточном этапе мы внедрили шаблон Dockerfile и скрипты для управления сборкой. Каждый сервис имел свой набор задач, которые включались в сборочный процесс. Все сервисы стали использовать общий Dockerfile, что упростило управление. В каждом сервисе сохранялся постоянный характер файла. Это позволило настраивать сборку в соответствии с конкретными потребностями.

Хотя этот подход уже был лучше, чем предыдущий, мы понимали, что можно достичь ещё большего. Среди существующих решений:

  1. Bazel. Сборка системы от Google, оптимизирована для крупных проектов со множеством зависимостей.

  2. Встроенное решение GitHub CI/CD, поддерживающее кеширование слоёв образов.

  3. Kaniko. Альтернатива для сборки образов в Kubernetes, подходящая для облачных сред с ограниченными правами.

Почему мы выбрали Docker Buildx?

Docker Buildx — это расширение системы Docker Build, которое значительно улучшает процесс сборки. Изначально мы сомневались в его применимости, так как переход на новый запрос требовал времени на изучение и доработку кода. Но после первого опыта использования стало понятно, что без него не обойтись, если нужно собрать что-то более сложное, чем один образ.

Плюсы процесса, которые значительно упростили работу:

  • количество файлов конфигураций

  • единообразие процесса для всех составляющих (минимизация ошибки человеческого фактора)

  • скорость внесения изменений

Ключевые преимущества Docker Buildx перед Docker Build:

  1. Мультиархитектурные сборки

    Даёт возможность создавать образцы для нескольких архитектур (например, x86 и ARM) в одной команде, что критично для современных микросервисов.

  2. Расширенное кеширование

    Ускоряет процессы CI/CD, умеет сохранять и использовать кеш локально, в docker-реестре и в S3-совместимых сервисах. Это особенно полезно, когда сборка может происходить на разных сборочных агентах (runners, workers) из общего пула.

  3. Инкрементальные сборки

    Уменьшает время сборки и делает процесс более эффективным, особенно при небольших, но частых изменениях кода.

  4. Сборки в распределённых средах

    Поддерживает дистрибутивную сборку, когда процесс может выполняться параллельно на нескольких узлах, что ускоряет создание больших образов или образов для нескольких архитектур. Это полезно в крупных CI/CD-пайплайнах, где сборка может быть распределена по нескольким машинам одновременно для ускорения процесса.

Эти преимущества делают Docker Buildx эффективным средством оптимизации процессов сборки и развёртывания, что в конечном итоге приводит к более быстрой и качественной разработке ПО.

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

В примере будет три файла:

  1. Dockerfile – единый файл для всех образов/микросервисов. Он выглядит так же, как если бы мы собирали single image, разве что содержит большее количество переменных.

  2. docker-bake.hcl – в нём будем описывать общие переменные (variable), функции (function) и группы.

  3. env.hcl – в нём хранятся значения переменных для конкретной конфигурации сборки. Название файла может быть любое.

docker-bake.hcl

В файле docker-bake.hcl хранятся все переменные, группы сервисов и сами сервисы (таргеты проекта).

Переменные

variable "version" {}
variable "languages" {}
variable "registry" {}
...

variable "IMAGE_SDK" {}
variable "IMAGE_RUNTIME" {}
variable "IMAGE_SIGNING" {}
variable "IMAGE_ASTRA_SMOLENSK" {}
...

Цели (Targets)

Для каждого сервиса создаётся таргет со своими параметрами: название, теги будущего образа и т.д. Также можно создать общий базовый таргет с дефолтными настройками образа. Таргеты могут выстраиваться в цепочку и наследовать параметры от родителя, при необходимости подменяя и дополняя их.

target "base" {
    args = {
        version = "${version}
        languages = "${languages}"
        registry = "${registry}"

        IMAGE_SDK = "${IMAGE_SDK}"
        IMAGE_RUNTIME = "${IMAGE_RUNTIME}"
        IMAGE_SIGNING = "${IMAGE_SIGNING}"
        IMAGE_ASTRA_SMOLENSK = "${IMAGE_ASTRA_SMOLENSK}"
    }
}

target "license-service" {
    inherits = ["base"]
    args = {
        project = "LicenseService"
        service = "license-service"
        edition = "${edition}"
    }
    tags = ["${registry}/prod-smp/smp-license:${edition}-${version}"]
}

Группы

Группы — это объединённые по каким-либо критериям таргеты. Например, в default входят все таргеты проекта. Сюда мы складываем таргеты, которые будут собираться, если иное не указано явным образом. Также можно формировать любые группы по необходимому набору критериев. Например, весь продукт (все модули); все компоненты выбранного модуля; выбранный компонент (для тестов, отладки и т.д.).

group "default" {
    targets = ["transport-service", "backup-service", "billing-service", "import-service", "licence-service", "log-service", "messaging-service", "smp-service", "storage-service", "nginx"]
}

Файлы с переменными (env.hcl)

Мы можем объявить отдельный файл с переменными, которые будут использованы при сборке. Это удобно, когда нужны разные конфигурации сборки, например, версии SDK.

variable "IMAGE_SDK" {
    default ="dep-mngmob-net/net-sdk:6.0.424-astra-smolensk1.7.5uu1-36"
}

variable "IMAGE_SIGNING" {
    default = "dep-mngmob-net/signing:2.10.1.190-debian11-26
}

variable "IMAGE_ASTRA_SMOLENSK" {
    default = "dep-mngmob-net/astra-smolenks:1.7.5.uu1-12"
}

Dockerfile

Разберём основные элементы структуры Dockerfile, которая применяется для всех наших бэкенд-микросервисов.

Это мультистейдж-процесс, где в рамках одного Dockerfile происходит цепочка действий над проектом. Мы опустили часть кода из соображений конфиденциальности, но постарались сохранить общий смысл.

Первым этапом на основе базового SDK-образа копируется исходный код и восстанавливаются все зависимости проекта. Это происходит на основе базового образа SDK. Как результат работы этапа – получаем слой restore, включающий в себя весь исходный код и все скачанные зависимости.

ARG registry = "harbor"
ARG IMAGE_SDK
ARG IMAGE_RUNTIME
ARG IMAGE_SIGNING
ARG IMAGE_CRG_TOOLS

#============================================#
#=                 SDK                      =#
#============================================#
FROM ${registry}/${IMAGE_SDK} AS sdk

#============================================#
#=                 RESTORE                  =#
#============================================#
FROM sdk AS restore

ARG edition
ARG languages

ENV EDITION=${edition}

WORKDIR /build

COPY Source/BackupService/...
COPY Source/StorageService/...
...

RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet restore --configfile nuget.config

COPY Source/ Source/

COPY ./scripts/ci/build/installer/manage-localizations.sh ./manage-localizations.sh
RUN ./manage-localizations.sh --languages "${languages}"

Вторым этапом,  запускаем процесс непосредственно сборки проекта. Принимая за основу артефакты предыдущего слоя – restore as build, мы собираем конкретный dotnet-проект. Все параметры для его сборки — название, версия и т.д. — формируются на основе bake-файла.

#============================================#
#=                 PROD BUILD               =#
#============================================#
FROM restore AS prod-build

ARG version
ARG project
ARG edition

RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet publish "Source/${project}.Host/${project}.Host.csproj" \
    -c Release -f linux-x64 --no-restore --self-contained -o /out \
    /p:Version="${version}"

Так как мы поддерживаем работу ПО на Astra Linux в режиме ЗПС (замкнутой программной среды), все компоненты приложения должны иметь соответствующую подпись. Это следующий этап, где для работы базового образа подписи используются артефакты, созданные на стадии Build.

#============================================#
#=                 PROD SIGN                =#
#============================================#

FROM ${registry}/${IMAGE_SIGNING} AS prod-build-sign

ARG ... # Аргументы, необходимые для подписи

COPY --link --from=prod-build /out /out
RUN ... # Запуск скрипта подписи

Можно также выделить этап тестирования приложения. Здесь используется результат работы restore, как и для этапа build. Это позволяет значительно сократить время сборки, выполняя операцию restore только один раз для всех задач.

#============================================#
#=                 TEST                     =#
#============================================#
FROM restore AS test

RUN --mount=type=cache,target=/root/.nuget/packages \
    dotnet build -C Release --no-restore

ENTRYPOINT ["dotnet", "test", "--logger", "console;verbosity=normal", "./**.Tests.dll"]

Запуск сборки

Для запуска процесса сборки будем использовать следующую команду.

version="${version:?}" \
edition="${edition:?}" \
languages="$languages" \
docker buildx bake \
-f "docker-bake-hcl" \
-f "env.hcl" \
"${target:-'default'}" \
"${args[@]}"

Значения, генерируемые CI/CD, передаём как переменные среды, остальные – из файла env.hcl.

Результат

В итоге получается Dockerfile и два hcl-файла:

  1. Dockerfile общий для всех образов модуля, состоит из нескольких частей. Каждую из них можно оптимизировать, чтобы ускорить сборку.

  2. Bake-файл содержит общие параметры всех образов и индивидуальные параметры каждого сервиса.

  3. env.hcl содержит параметры, необходимые для конкретной конфигурации сборки.

Из плюсов:

  1. Больше не нужно вручную менять значение переменной в нескольких местах: замена в одном файле сразу применяется ко всему проекту.

  2. Стало легче масштабировать количество сервисов в проекте: теперь для этого достаточно добавить несколько строк кода.

Кеширование

Каждый образ состоит из последовательности слоёв, которые создаются на основе шагов, описанных в Dockerfile. Например, команды COPY, RUN, ADD и другие генерируют новые слои.

Кеширование позволяет повторно использовать слои образов, что существенно сокращает время сборки. Если один из шагов изменяется, Docker пересобирает только изменённый шаг и все последующие, при этом повторно использует те слои, которые не изменились. Это особенно важно при частых повторных сборках, когда значительная часть этапов остаётся неизменной.

Может ли кеширование вызывать проблемы? У него, помимо очевидных плюсов, есть и недостатки. Одна из распространённых проблем — применение устаревших слоёв образов. Это может привести к некорректной работе приложения, особенно при изменении зависимостей. Некорректная работа кеширования может замедлить процесс разработки и усложнить отладку.

Когда кеширование в Docker Buildx следует отключить?

Есть случаи, когда кеширование Docker-образов не применяется. Чтобы гарантировать, что финальный образ будет содержать все актуальные изменения и обновления, мы соглашаемся с тем, что сборка может занять больше времени. Это предотвращает возможные проблемы, связанные с использованием устаревших данных.

Пример №1. При подготовке релизных версий важно обеспечить чистую сборку, которая не зависит от ранее сохранённых слоёв. Отсутствие кеширования гарантирует, что все изменения, включая обновления зависимостей и базовых образов, будут учтены, и финальный образ будет максимально стабильным и предсказуемым. При этом увеличенное время сборки не критично, так как релизные версии требуются редко.

Пример №2. Когда политики безопасности или нормативные требования запрещают кеширование, чтобы гарантировать отсутствие устаревших или уязвимых компонентов в финальном образе.

Безопасность в Docker

Нельзя не остановиться и на безопасности процесса сборки образов.

Согласно последним отчётам более 44% всех контейнеров, которые находятся в коммерческой эксплуатации, содержат уязвимости. Угроза не ограничивается выявленными недостатками — хакеры беспрерывно ищут новые векторы атак на системы, построенные с использованием Docker. Поэтому даже своевременное обновление не гарантирует долгосрочную защищённость систем.

Контейнеры имеют многослойную структуру, что делает их идеальной мишенью для атаки. Всевозможные библиотеки и зависимости создают множество слоёв, каждый из которых является дополнительным уровнем сложности. Если хотя бы один слой содержит уязвимость или вредоносное ПО, то весь контейнер перестаёт быть защищённым. А если контейнеры запускаются с избыточными правами, то возникает риск эксплуатационных атак и на хостовую систему тоже.

Рекомендации по безопасности для Dockerfile и Docker Compose

При создании и развёртывании контейнеров защищённость должна закладываться на этапе конфигурации. Использование безопасных практик при написании Dockerfile поможет избежать распространённых уязвимостей.

Обновляйте базовый образ

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

Удаляйте временные файлы и неиспользуемые зависимости

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

Запускайте контейнер от имени служебного пользователя

Для повышения безопасности создайте служебного пользователя с ограниченными (минимально необходимыми) правами и запускайте контейнер от его имени. Это предотвратит выполнение контейнера от имени суперпользователя (root), ограничив доступ к системным ресурсам.

Ищите и устраняйте уязвимости

Регулярно сканируйте образы на уязвимости и анализируйте безопасность. Важно не только выявлять уязвимости, но и вовремя принимать меры по их устранению для минимизации рисков. Например, у нас выстроен полноценный процесс выявления и управления общеизвестными уязвимостями. С использованием анализатора, встроенного в сборочный конвейер, выявляются такие уязвимости, после чего обязательна процедура по оценке их применимости и устранения.

Подводим итоги

Перечислим ещё раз основные шаги по оптимизации процесса мультистейдж-сборки на Docker BuildX:

  • Анализ сборки

    Определите ресурсоёмкие этапы, подходящие для кеширования, такие как установка зависимостей и базовые шаги, в том числе выделение базовых образов в отдельные компоненты.

  • Настройка Dockerfile и CI/CD

    Внедряйте кеширование постепенно, анализируйте и вносите коррективы на каждом этапе.

  • Обучение команды

    Введите стандарты эффективной работы и обучите команду их применению, чтобы повысить стабильность и скорость разработки.

  • Мониторинг и корректировка

    Анализируйте метрики времени сборки и ресурсоёмкость для корректировки стратегий кеширования.

  • Своевременно обновляйте базовые компоненты

    При использовании сторонних библиотек – следите за их актуальностью. Используйте только актуальные версии, и что важно – поддерживаемые компоненты, в которых все найденные уязвимости своевременно устраняются.

  • Внедряйте в CI/CD-конвейер сканирование образов

    Своевременное обнаружение проблем на стадии разработки/сборки проекта позволит минимизировать время реакции на замечания анализаторов, а также время их устранения.

    Чем раньше разработка узнает о потенциальных проблемах – тем ниже вероятность, что уязвимости будут обнаружены в продуктовой эксплуатации.

Это улучшит стабильность и повысит производительность пайплайнов, что положительно повлияет на качество, скорость и безопасность ваших продуктов.

На этом всё. Желаем успешного внедрения и ускорения сборки на Docker BuildX!

P.S. Чтобы не пропустить наши новые материалы, подписывайтесь на блог! И заходите в TG-канал, там мы рассказываем о технических мероприятиях и конференциях, делимся выступлениями экспертов, обсуждаем подборки на технические и ИБ темы.