yandex
Калькулятор ценТарифыАкцииДокументацияО насКарьера в Cloud.ruНовостиЮридические документыКонтактыРешенияРеферальная программаКейсыПартнерство с Cloud.ruБезопасностьEvolutionAdvancedEvolution StackОблако VMwareML SpaceВ чем отличия платформ?БлогОбучение и сертификацияМероприятияИсследования Cloud.ruЛичный кабинетВойтиЗарегистрироватьсяEvolution ComputeEvolution Managed KubernetesEvolution Object StorageEvolution Managed PostgreSQL®Облако для мобильных и веб‑приложенийАналитика данных в облакеEvolution Bare MetalEvolution SSH KeysEvolution ImageСайт в облакеEvolution DNSEvolution VPCEvolution Load BalancerEvolution Magic RouterEvolution DiskХранение данных в облакеEvolution Container AppsEvolution Artifact RegistryEvolution Managed ArenadataDBEvolution Managed TrinoEvolution Managed SparkАналитика данных в облакеEvolution ML InferenceEvolution Distributed TrainEvolution ML FinetuningEvolution NotebooksCurator Anti-DDoSCurator Anti‑DDoS+WAFUserGate: виртуальный NGFWStormWall: Anti-DDoSEvolution TagsEvolution Task HistoryCloud MonitoringCloud LoggingАренда GPUAdvanced Object Storage ServiceAdvanced Elastic Cloud ServerAdvanced Relational Database Service for PostgreSQLРазработка и тестирование в облакеAdvanced Image Management ServiceAdvanced Auto ScalingDirect ConnectCDNCross-platform connectionAdvanced Enterprise RouterAdvanced Cloud Backup and RecoveryAdvanced Data Warehouse ServiceAdvanced Elastic Volume ServiceAdvanced Cloud Container EngineAdvanced FunctionGraphAdvanced Container Guard ServiceAdvanced Software Repository for ContainerAdvanced Document Database Service with MongoDBAdvanced Relational Database Service for MySQLAdvanced Relational Database Service for SQL ServerCloud AdvisorAdvanced Server Migration ServiceAdvanced Data Replication ServiceAdvanced API GatewayAdvanced CodeArtsAdvanced Distributed Message Service for KafkaAdvanced Distributed Message Service for RabbitMQAdvanced DataArts InsightAdvanced CloudTableAdvanced MapReduce ServiceAdvanced Cloud Trace ServiceAdvanced Application Performance ManagementAdvanced Identity and Access ManagementAdvanced Enterprise Project Management ServiceVMware: виртуальный ЦОД с GPUVMware: виртуальный ЦОДУдаленные рабочие столы (VDI)VMware: сервер Bare MetalИнфраструктура для 1С в облакеУдаленные рабочие столыМиграция IT‑инфраструктуры в облако3D-моделирование и рендерингVMware: резервное копирование виртуальных машинVMware: резервный ЦОДVMware: резервное копирование в облакоVMware: миграция виртуальных машин
Поиск
Связаться с нами

Docker build: сборка образа Dockerfile

Dockerfile — документ с инструкциями по созданию Docker-образов. Фактически это рецепт управляемых контейнеров, которые могут воспроизводиться в любой рабочей среде. Нужно уметь с ним обращаться, чтобы избежать ошибок при сборке и проблем в продакшене. Разберем структуру Dockerfile, команду docker build и практики работы с образами, которые пригодятся в реальных проектах.

Инструкции
Иллюстрация для статьи на тему «Docker build: сборка образа Dockerfile»
Продукты из этой статьи:
Иконка-Evolution Artifact Registry
Evolution Artifact Registry
Иконка-Evolution Managed Kubernetes
Evolution Managed Kubernetes

Что такое Dockerfile и зачем он нужен

Dockerfile — это текстовый файл, который содержит инструкции для автоматической сборки образа. Описываются все шаги: выбор «базы», копирование файлов, установка зависимости, команда для запуска и другие. Окружение представлено в виде кода, который можно воспроизвести в любой системе, где работает Docker. 

Преимущества Dockerfile:

  • Повторяемость — все шаги явно описаны в инструкциях, поэтому Dockerfile гарантирует, что результат сборки образа не поменяется независимо от операционной системы, «железа» и команды разработки. 

  • Версионность — текстовый файл можно хранить в любой системе контроля версий и отслеживать изменения. При необходимости легко откатиться к прежнему состоянию инструкций. 

  • Автоматизация и CI/CD — Dockerfile без проблем интегрируется в пайплайны сборки и доставки приложений. Системы могут автоматически собрать образ, тестировать и публиковать без участия человека. 

Dockerfile позволяет автоматизировать сборку образов и сделать ее предсказуемой. Не нужно каждый раз вручную по-разному настраивать контейнеры — все шаги каждый раз будут выполняться одинаково по инструкциям. 

DockerfileDockerfile
Дарим до 20 000 бонусов
Дарим до 20 000 бонусов
4 000 бонусов — физическим лицам, 20 000 бонусов — юридическим

Docker читает Dockerfile сверху вниз и послойно создает образ. Инструкции, изменяющие файловую систему (RUN, COPY, ADD), создают отдельные слои. Инструкции-метаданные (ENV, LABEL, EXPOSE, CMD, ENTRYPOINT) не создают постоянных слоев, а добавляют информацию к образу.

Базовый синтаксис и структура файла

В текстовом файле Dockerfile стандартный формат каждой строки выглядит так:

  • Инструкции — это ключевые слова Docker, например, FROM, RUN, COPY

  • Аргументы — условия, которые нужно соблюсти для выполнения инструкции. 

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

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

  • FROM — базовый образ;

  • ENV/ARG — переменные окружения и аргументы сборки;

  • RUN — установка пакетов и зависимостей;

  • COPY/ADD — добавление файлов в образ;

  • WORKDIR — рабочая директория;

  • CMD/ENTRYPOINT — запуск контейнера. 

Длинные инструкции могут делиться на несколько строк с помощью символа \. Пример такого описания:

Для пояснения шагов сборки используются комментарии, которые в Dockerfile начинаются с символа #. Пример:

Основные инструкции Dockerfile с примерами

Недостаточно просто знать инструкции — нужно уметь ими пользоваться с учетом нюансов. Примеры и советы:

Инструкция
Назначение
Пример применения
Лучшие практики
FROM
Задает родительский образ для нового Docker-образа
FROM ubuntu:22.04FROM python:3.11-slimFROM alpine:latest
Указывайте конкретные теги (например, python:3.11-slim). Alpine (~5 MB) минимален, но несовместим с некоторыми glibc-бинарными файлами. Slim-версии (~30-70 MB) — баланс для продакшен. Для Python с native-расширениями используйте многоэтапную сборку.
WORKDIR
Устанавливает рабочую директорию внутри контейнера
WORKDIR /app
Если директории нет, Docker автоматически ее создаст. Все последующие команды (RUN, COPY, CMD) будут выполняться с привязкой к этой директории
COPY
Копирует файлы и директории из контекста сборки в контейнер
COPY src/ /app/src/
Простая и предсказуемая инструкция, которая позволяет получить ожидаемый результат
ADD
Расширенная версия инструкции COPY
ADD app.tar.gz /app/
Помимо копирования, инструкция обеспечивает распаковку архивов и загрузку файлов по URL. Для простого копирования лучше применять COPY
RUN
Запускает команды внутри контейнера и создает новые слои образа
RUN apt-get update && apt-get install -y python3
Каждая инструкция RUN создает новый слой. Чтобы уменьшить размер итогового образа, объединяйте несколько команд в одну строку
CMD
Задает команду с аргументами, которая будет выполняться при запуске контейнера
CMD ["python", "app.py"]
Можно переопределить эту инструкцию при запуске контейнера
ENTRYPOINT
Задает неизменяемую команду, которая будет всегда выполняться при запуске контейнера
ENTRYPOINT ["python"]
Часто применяется вместе с CMD — инструкцией, которая передает аргументы
ENV
Задает переменные окружения внутри контейнера
ENV NODE_ENV=production
Заданные инструкцией переменные будут доступны в процессе выполнения контейнера. Это нужно для конфигурации приложения без изменения образа
ARG
Определяет переменные, которые будут передаваться в процессе сборки образа
ARG VERSION=latest
Значения передаются при сборке и недоступны во время работы контейнера

Процесс сборки: команда docker build

Для сборки Docker-образа по инструкциям из Dockerfile выполняется с помощью команды docker build. Рассказываем, как происходит процесс. 

Синтаксис и ключевые флаги команды

Базовый синтаксис выглядит так: 

Благодаря этой команде Docker начинает собирать образ с использованием инструкций из Dockerfile и контекста, который описан в текущей директории. Для пояснения процесса используются флаги: 

  • -t (tag) — позволяет в формате name:tag задать имя и тег образа. Это нужно для идентификации образа, чтобы ссылаться на него при запуске контейнеров или публикации. 

  • -f (file) — указывает путь к Dockerfile, если он имеет другое название или находится не в той директории, которая рекомендована по умолчанию. Контекст сборки нужно указать отдельно. 

  • --no-cache — отменяет использование кэша при сборке образа. Docker будет заново выполнять все инструкции, даже если раньше создавал такие же слои. Флаг применяется, когда нужна «чистая» сборка.

  • --target — позволяет на определенном этапе останавливать сборку. Применяется в многоэтапных процессах создания образов, чтобы было удобнее осуществлять отладку. 

Флаги добавляются в базовый синтаксис команды. Пример:

Здесь указывается путь к Dockerfile, задаются имя и тег образа. 

Создание контейнераСоздание контейнера

Контекст сборки — что такое точка (.)

В команде docker build (.) означает контекст сборки — директорию, содержимое которой получает Docker-демон. Учитывайте, что будет передан весь контекст, а не только файлы, явно указанные в Dockerfile.

Чтобы исключить лишнее, используйте .dockerignore. Например, можно сделать так, что не будут передаваться временные файлы, node_modules, каталоги сборки и .git. Исключения уменьшат размер контекста, снизят нагрузку на систему и ускорят сборку. 

Кэширование слоев: как ускорить повторную сборку

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

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

Оптимизация Docker-образов: уменьшаем размер, повышаем безопасность

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

Использование многоэтапной сборки (multi-stage build)

Многоэтапная сборка позволяет объединить несколько этапов в одном Dockerfile. Идея в том, чтобы разделить этапы сборки с полным SDK и запуск приложения с минимальным runtime. 

Пример для Go:

Go-приложение компилируется в статический бинарный файл, который может работать даже на scratch (пустом образе).

Пример для Java:

Для Java на этапе сборки используется JDK (Java Development Kit), на этапе запуска — JRE (Java Runtime Environment). JRE все еще необходим, но исключение инструментов компиляции уменьшает размер образа и поверхность атак.

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

Multi-stage buildMulti-stage build

Выбор минимального базового образа

Состав и размер образа будут влиять на параметры и поведение контейнера. Например, образ ubuntu — около 70 MB, alpine — около 5 MB. 

К преимуществам минимального базового образа Alpine можно отнести небольшое количество установленных пакетов, малую поверхность для потенциальных атак, быструю загрузку и распространение. Однако есть и минусы. Это возможная несовместимость с некоторыми бинарными файлами, недоступность части пакетов и инструментов «из коробки» и сложная отладка из-за минималистичного окружения. 

Минимальный базовый образ стоит выбирать, если в приоритете безопасность и быстрое распространение. 

Очистка кеша менеджеров пакетов в одном RUN

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

Объединение позволяет уменьшить размер образа, избавиться от кеш менеджера пакетов в слоях и вести сборку в соответствии с лучшими практиками Docker. 

Файл .dockerignore: исключение ненужных файлов из контекста

Мы уже упоминали файл .dockerignore, который позволяет исключать все лишнее из контекста сборки. Пример типичного .dockerignore:

Почему .dockerignore критически важен:

  • Безопасность: исключает случайную передачу секретов (.env, ключи API, сертификаты) в образ.

  • Производительность: уменьшает размер контекста сборки, ускоряет передачу Docker-демону.

  • Предсказуемость: предотвращает попадание в образ файлов, которые могут конфликтовать с процессом сборки.

  • Изоляция: гарантирует, что образ содержит только необходимые файлы, не включая артефакты разработки.

Файл .dockerignore работает на уровне клиента Docker, исключая файлы до отправки демону. Это не защита от утечки секретов в самом образе — проверяйте, что секреты не копируются через COPY/ADD.

Файл .dockerignoreФайл .dockerignore

Практические примеры: собираем образ веб-приложения

Чтобы разобраться в применении Dockerfile, можно изучить примеры файлов для Python и Node.js. Предлагаем варианты, которые полностью иллюстрирует реальную структуру продакшен-образов.

Пример Dockerfile для Python/Django приложения

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

За основу взят официальный минималистичный образ python. Отключается создание .pyc файлов и буферизация вывода. Для оптимизации кэширования сначала копируется requirements.txt и устанавливаются зависимости, после чего копируется исходный код. Команду запуска Django-сервера задает CMD. 

Пример Dockerfile для Node.js приложения

Для Node.js рекомендовано отдельно устанавливать в зависимости и применять многоэтапную воспроизводимую сборку с помощью команды npm ci. Как может выглядеть структура Dockerfile:

Используется полный базовый образ Node.js. для уменьшения размера, финальный основан на node:alpine. Установка зависимости выполняется с помощью npm ci. 

Evolution Artifact Registry
Evolution Artifact Registry
Храните и распространяйте артефакты безопасно
Узнать больше

Сборка и проверка образа, запуск контейнера

Согласно готовому Dockerfile, команды выполняются в стандартной последовательности. Сначала идет сборка образа: 

Docker создает образ с тегом, используя в качестве контекста сборки текущую директорию. Затем следует проверка: 

После выполнения команды выводится список локальных образов с именами, тегами, размерами и уникальными идентификаторами. Если все в порядке, контейнер запускается:

Docker на основе образа запускает контейнер и пробрасывает на хост-систему порт приложения. 

Готовые образы можно хранить в сервисе Evolution Artifact Registry от Cloud.ru. При загрузке они проверяются на наличие уязвимостей. Для локальной проверки образов на уязвимости используйте Docker Scout:

Продвинутые техники и лучшие практики

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

Использование HEALTHCHECK

Механизм HEALTHCHECK позволяет Docker определять работоспособность контейнера — выявлять состояния healthy или unhealthy.

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

Важные особенности:

  • Docker только маркирует контейнер как healthy/unhealthy, но не перезапускает его автоматически.

  • В Docker Swarm HEALTHCHECK используется при развертывании и обновлении сервисов: unhealthy задачи могут быть заменены новыми в процессе rollout. Для автоматического восстановления отдельных контейнеров в Swarm используйте --restart-condition any или --restart-condition on-failure при создании сервиса. HEALTHCHECK в Swarm влияет на поведение при обновлениях, но не является единственным механизмом восстановления.

  • В Kubernetes HEALTHCHECK не используется (начиная с версии 1.8 он отключен). Для Kubernetes используйте livenessProbe и readinessProbe:

Где применять:

  • standalone Docker-контейнеры с ручным управлением;

  • Docker Swarm для автоматического восстановления;

  • локальная разработка и отладка.

Где НЕ применять:

  • Kubernetes (используйте встроенные probes);

  • если нужен только мониторинг без автоматического восстановления.

Если вы используете Kubernetes, HEALTHCHECK в Dockerfile игнорируется (начиная с версии 1.8 и во всех последующих версиях, включая актуальные). Вместо этого используйте встроенные механизмы Kubernetes:

HEALTHCHECK остается актуальным для standalone контейнеров, Docker Compose (особенно с флагом --wait) и Docker Swarm. В Docker Compose HEALTHCHECK позволяет сервисам ожидать готовности зависимостей перед запуском.

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

Настройка пользователя (USER)

По умолчанию процессы в контейнере запускаются от имени пользователя root, что создает риски безопасности. Рекомендуется запускать процессы от имени непривилегированного пользователя.

Вариант 1 (рекомендуемый): создать выделенного пользователя в Dockerfile:

Вариант 2: использовать системного пользователя nobody:

Однако учтите ограничения: nobody не имеет домашней директории и может не иметь прав на запись в некоторые директории. Это подходит только для приложений, которым не требуется запись в файловую систему.

Никогда не запускайте продакшен-контейнеры от root. Использование непривилегированного пользователя — обязательная практика безопасности.

Версионирование образов и теги

Чтобы идентифицировать разные версии одного образа, Docker используют теги. Распространенные схемы тегирования:

  • myapp:latest — обозначает последнюю сборку, категорически не рекомендуется для продакшен;

  • myapp:1.2.3 — семантическое версионирование, обеспечивает детерминированные деплои;

  • myapp:sha-abc123 — тегирование по хешу коммита, позволяет точно соотнести образ с версией кода;

  • myapp:1.2.3-abc123 — комбинация версии и хеша для максимальной воспроизводимости.

Почему latest опасен для продакшен:

  • невозможно гарантировать, что на staging и production развернут один и тот же образ;

  • откат на предыдущую версию становится недетерминированным;

  • нарушается принцип воспроизводимости инфраструктуры как кода (IaC). 

Всегда используйте фиксированные теги в продакшен. latest допустим только для разработки и CI-сборок.

Многие используют первый вариант, но для продакшена он не рекомендуется. Не обязательно зацикливаться на myapp:1.2.3, но это схема предпочтительнее. 

Сборка для разных архитектур (buildx)

Современные приложения в основном разворачиваются на разных архитектурах процессоров — amd64 и arm64. Для этих случаев в Docker есть docker buildx — расширение docker build.

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

Для мультиплатформенной сборки (особенно arm64 на amd64 или наоборот) требуется предварительно зарегистрировать обработчики QEMU:

Без этого сборка для других архитектур будет недоступна или приведет к ошибкам. Также необходимо создать и использовать билдер, поддерживающий мультиплатформенность:

Пример сборки multi-arch образа:

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

При работе с образами даже у опытных пользователей возникают неполадки и ошибки. Главное — быстро определить проблему и найти решение в соответствии с рекомендациями разработчиков Docker.

Пошаговая отладка сборки

Чтобы избежать ошибок на старте, можно проанализировать весь процесс сборки образа. В этом поможет команда:

Флаг --progress=plain позволяет в текстовом формате подробно вывести процесс сборки и проверить выполнение инструкций Dockerfile без агрегирования логов. 

Чтобы поэтапно восстановить процесс сборки, можно применять временное комментирование инструкций в Dockerfile. Комментарии нужно оставлять с символом #. Можно помечать проблемные шаги или вносить уточнения по конкретным этапам работы с образом. 

Анализ размера образа

Важный этап отладки — понять, какие инструкции и слои влияют на размер образа. Можно воспользоваться командой:

Чтобы ее выполнить, укажите имя или идентификатор образа, например:

Команда выдаст все слои образа, их размеры и инструкции для создания. Можно увидеть, на каком шаге получаются «тяжелые» слои.

Для детального анализа образов и оптимизации часто применяется инструмент dive. Он позволяет посмотреть содержимое каждого слоя, оценить инструкции Dockerfile и увидеть все примененные изменения. 

Частые ошибки новичков

У начинающих пользователей в основном возникают одни и те же проблемы и ошибки. Вот самые распространенные:

  • Проблемы с путями. Если неправильно указать относительные и абсолютные пути в инструкциях COPY и ADD, в сборке будет ошибка. Во избежание укажите пути с привязкой контексту сборки, а не местоположению Dockerfile. 

  • Неправильное использование CMD. Если в одном Dockerfile несколько инструкций CMD, выполняться будет только последняя. Прописывайте только одну. 

  • Отсутствие .dockerignore. Если проигнорировать или неправильно настроить файл для исключения, в контекст сборки будут переданы лишние элементы. Пропишите исключения сразу. 

Чтобы работать без ошибок, изучите документацию Docker и используйте рекомендуемые подходы. 

Следующие шаги: что делать с собранным образом

После сборки Docker-образа начинается работа с контейнером. Подсказываем основные этапы. 

Запуск контейнера: docker run с параметрами

Для запуска контейнера на основе собранного образа применяется команда docker run. Она включает несколько параметров: 

  • назначение имени контейнера;

  • передачу переменных окружения; 

  • проброс портов; 

  • запуск приложения в фоновом режиме.  

Примеры применения команды:

  • docker run myapp:1.0 — запуск с настройками по умолчанию; 

  • docker run -p 8000:8000 myapp:1.0 — запуск с пробросом портов;

  • docker run -d -p 8000:8000 myapp:1.0 — запуск приложения в фоновом режиме;

  • docker run -d --name myapp_container -p 8000:8000 myapp:1.0 — запуск с назначением имени контейнера.

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

Публикация в реестр: Docker Hub, GitLab Registry, AWS ECR

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

Сначала нужно выполнить тегирование с помощью команды docker tag. На этом этапе образа появится имя, которое отвечает формату реестра. Для публикации применяется команда docker push

Этот способ подходит для Docker Hub, GitLab Container Registry и AWS Elastic Container Registry. 

Интеграция в CI/CD пайплайн

Один из сценариев использования контейнеров Docker — интеграция в системе непрерывной интеграции и доставки кода. Типичная схема CI/CD пайплайна выглядит так: 

  • сборка образа на основе Dockerfile;

  • тестирование приложения внутри контейнера;

  • публикация образа в реестр;

  • деплой в целевую среду (сервер, кластер, оркестратор).

С помощью такого подхода обеспечивается единое окружение для тестирования и продакшен-среды. 

Для управления контейнерными приложениями в продакшен собранные образы удобно разворачивать в управляемом Kubernetes-кластере. Evolution Managed Kubernetes предоставляет готовую инфраструктуру для оркестрации контейнеров: автоматическое масштабирование, маркетплейс плагинов для мониторинга и безопасности, а также гибкую настройку мастер- и рабочих узлов. Это позволяет сосредоточиться на разработке, а не на управлении контрольной плоскостью кластера.

Заключение

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

Продукты из этой статьи:
Иконка-Evolution Artifact Registry
Evolution Artifact Registry
Иконка-Evolution Managed Kubernetes
Evolution Managed Kubernetes
24 марта 2026

Вам может понравиться