Dockerfile¶
Dockerfile — это текстовый файл, содержащий набор инструкций для автоматической сборки образа контейнера в среде Docker. Файл определяет базовый образ, устанавливаемое программное обеспечение, настройки окружения, команды для запуска и другие параметры, необходимые для создания изолированного и воспроизводимого окружения для приложения.
Dockerfile является ключевым элементом концепции «инфраструктура как код» (Infrastructure as Code, IaC), позволяя разработчикам и системным администраторам описывать процесс развёртывания приложения в виде версионируемого, читаемого и многократно используемого файла. Каждая инструкция в Dockerfile создаёт новый слой (layer) в образе, что способствует эффективному кэшированию и ускорению повторных сборок.
¶История
Разработка Dockerfile неразрывно связана с появлением и эволюцией платформы Docker. Компания Docker, Inc. (основана в 2010 году) выпустила первую публичную версию Docker в 2013 году. С самого начала был предложен декларативный способ описания сборки образа, который впоследствии получил название Dockerfile. Первоначально формат был простым и включал всего несколько инструкций (FROM, RUN, CMD, EXPOSE). По мере роста популярности Docker и усложнения сценариев использования, набор инструкций расширялся: были добавлены ENV, COPY, ADD, ENTRYPOINT, VOLUME, WORKDIR и другие.
В 2015 году Dockerfile стал частью спецификации формата образов Open Container Initiative (OCI), что способствовало его стандартизации и совместимости с другими системами контейнеризации (например, Podman, containerd). В 2017 году Docker представил многоэтапную сборку (multi-stage builds), позволяющую создавать более компактные и безопасные образы, разделяя этапы компиляции и финальной сборки.
¶Структура и синтаксис
Dockerfile состоит из последовательности инструкций, каждая из которых обычно записывается с новой строки. Инструкции могут быть дополнены комментариями, начинающимися с символа #. Порядок инструкций важен, так как каждая последующая команда выполняется на основе состояния, созданного предыдущими.
Основные инструкции Dockerfile:
- FROM — задаёт базовый образ, на основе которого строится новый образ. Это обязательная инструкция, с которой должен начинаться любой Dockerfile. Пример:
FROM ubuntu:22.04илиFROM python:3.11-slim. - RUN — выполняет команду в текущем слое образа во время сборки. Используется для установки пакетов, создания пользователей, настройки окружения. Пример:
RUN apt-get update && apt-get install -y nginx. - CMD — задаёт команду по умолчанию, которая будет выполняться при запуске контейнера. Может быть переопределена при запуске. В Dockerfile может быть только одна инструкция
CMD. Пример:CMD ["nginx", "-g", "daemon off;"]. - ENTRYPOINT — определяет исполняемый файл, который будет запущен при старте контейнера. В отличие от
CMD, аргументы, переданные при запуске, добавляются к командеENTRYPOINT. Часто используется вместе сCMDдля передачи аргументов по умолчанию. Пример:ENTRYPOINT ["python"],CMD ["app.py"]. - COPY — копирует файлы или директории из контекста сборки (обычно из директории, где находится Dockerfile) в файловую систему образа. Пример:
COPY ./app /app. - ADD — аналогична
COPY, но дополнительно поддерживает автоматическое извлечение архивов (tar, gzip) и загрузку файлов по URL. ИспользованиеADDрекомендуется только при необходимости этих функций, в остальных случаях предпочтительнееCOPY. - ENV — устанавливает переменные окружения, которые будут доступны в контейнере во время сборки и при его запуске. Пример:
ENV NODE_ENV=production. - WORKDIR — устанавливает рабочую директорию для последующих инструкций
RUN,CMD,ENTRYPOINT,COPYиADD. Пример:WORKDIR /usr/src/app. - EXPOSE — информирует Docker о том, что контейнер будет слушать указанные сетевые порты во время выполнения. Эта инструкция носит информационный характер и не публикует порты автоматически. Пример:
EXPOSE 80. - VOLUME — создаёт точку монтирования для внешнего тома (volume) или анонимного тома. Пример:
VOLUME /data. - USER — задаёт имя пользователя или UID, от имени которого будут выполняться последующие инструкции
RUN,CMDиENTRYPOINT. Пример:USER appuser. - ARG — объявляет переменные, которые могут быть переданы в Dockerfile во время сборки с помощью флага
--build-arg. Пример:ARG VERSION=latest. - LABEL — добавляет метаданные к образу в формате ключ-значение. Используется для организации, лицензирования, версионирования. Пример:
LABEL maintainer="team@example.com". - SHELL — позволяет изменить командную оболочку, используемую для выполнения инструкций
RUN. По умолчанию для Linux используется/bin/sh -c, для Windows —cmd /S /C. - HEALTHCHECK — определяет команду для проверки состояния контейнера. Docker периодически выполняет эту команду и на основе её результата устанавливает статус контейнера (healthy, unhealthy). Пример:
HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1. - ONBUILD — добавляет триггерную инструкцию, которая выполняется при использовании данного образа в качестве базового в другом Dockerfile. Применяется для создания универсальных базовых образов.
¶Многоэтапная сборка (Multi-stage builds)
Многоэтапная сборка — это техника, позволяющая использовать несколько инструкций FROM в одном Dockerfile. Каждый FROM начинает новый этап сборки. Артефакты (файлы, бинарники) из предыдущих этапов могут быть скопированы в финальный этап с помощью инструкции COPY --from=<имя_этапа>. Это позволяет создавать образы, содержащие только необходимые для выполнения приложения файлы, без инструментов сборки, компиляторов и промежуточных файлов, что значительно уменьшает размер образа и повышает безопасность.
Пример: первый этап может использовать образ Go для компиляции бинарника, а второй этап — минимальный образ (например, alpine или scratch), в который копируется только скомпилированный бинарник.
¶Лучшие практики
При написании Dockerfile рекомендуется следовать ряду правил для обеспечения эффективности, безопасности и воспроизводимости:
- Минимизация количества слоёв. Каждая инструкция
RUN,COPY,ADDсоздаёт новый слой. Объединение команд в одной инструкцииRUN(например, с помощью&&) уменьшает число слоёв. - Использование .dockerignore. Файл
.dockerignoreпозволяет исключить из контекста сборки ненужные файлы (.git,node_modules, временные файлы), что ускоряет передачу контекста в демон Docker. - Выбор минимального базового образа. Использование образов на основе
alpineилиscratch(пустой образ) снижает размер финального образа и уменьшает поверхность атаки. - Кэширование слоёв. Инструкции, которые редко меняются (например, установка системных пакетов), следует размещать в начале Dockerfile, а часто меняющиеся (копирование исходного кода) — в конце. Это позволяет эффективно использовать кэш Docker и ускоряет сборку.
- Запуск от непривилегированного пользователя. Создание и использование пользователя с ограниченными правами (инструкция
USER) снижает риски безопасности при эксплуатации контейнера. - Явное указание версий базового образа. Использование конкретных тегов (например,
python:3.11.4-slim) вместоlatestобеспечивает воспроизводимость сборки. - Минимизация количества устанавливаемых пакетов. Установка только необходимых зависимостей уменьшает размер образа и потенциальные уязвимости.
¶Пример Dockerfile
Ниже приведён пример Dockerfile для простого веб-приложения на Python с использованием Flask:
```dockerfile
¶Используем официальный образ Python
FROM python:3.11-slim
¶Устанавливаем рабочую директорию
WORKDIR /app
¶Копируем файл с зависимостями
COPY requirements.txt .
¶Устанавливаем зависимости
RUN pip install --no-cache-dir -r requirements.txt
¶Копируем исходный код приложения
COPY . .
¶Указываем порт, который будет слушать приложение
EXPOSE 5000
¶Определяем команду для запуска приложения
CMD ["python", "app.py"] ```
¶Применение
Dockerfile является основным инструментом для создания образов контейнеров в экосистеме Docker. Он используется в различных сценариях:
- Разработка и тестирование. Разработчики создают Dockerfile для локального запуска приложений в изолированном окружении, что гарантирует идентичность сред разработки, тестирования и эксплуатации.
- Непрерывная интеграция и непрерывная доставка (CI/CD). В пайплайнах CI/CD (например, Jenkins, GitLab CI, GitHub Actions) Dockerfile используется для автоматической сборки образов, которые затем публикуются в реестре образов (Docker Hub, Amazon ECR, Google Container Registry, Яндекс Container Registry).
- Микросервисная архитектура. Каждый микросервис обычно описывается собственным Dockerfile, что позволяет независимо собирать, тестировать и развёртывать компоненты системы.
- Обучение и демонстрация. Dockerfile позволяет быстро развернуть сложные окружения для обучения или демонстрации продукта.
¶Критика и ограничения
Несмотря на широкое распространение, Dockerfile имеет определённые недостатки:
- Декларативность, но не идемпотентность. Хотя Dockerfile описывает, что должно быть в образе, выполнение одной и той же инструкции
RUNможет давать разные результаты, если внешние источники (например, репозитории пакетов) изменились. Это может нарушить воспроизводимость сборки. - Отсутствие встроенного управления зависимостями. Dockerfile не предоставляет механизмов для разрешения конфликтов версий пакетов, что может приводить к ошибкам сборки.
- Сложность отладки. При возникновении ошибки во время сборки (особенно на этапе
RUN) бывает сложно определить точную причину, так как контекст выполнения внутри слоя ограничен. - Риск создания «толстых» образов. При неопытном использовании Dockerfile легко создать образ большого размера, содержащий множество неиспользуемых файлов и уязвимых компонентов.
Для преодоления некоторых ограничений Dockerfile были разработаны альтернативные инструменты, такие как BuildKit (встроенный в Docker, улучшающий производительность и безопасность сборки), Kaniko (сборка образов без привилегий), Podman (альтернативный движок контейнеризации, совместимый с Dockerfile) и Cloud Native Buildpacks (автоматическое определение и установка зависимостей).
¶Источники
- Docker Documentation — Dockerfile reference.
- Docker Documentation — Best practices for writing Dockerfiles.
- Open Container Initiative — OCI Image Format Specification.
- Книга: «Docker: практическое руководство для разработчиков и администраторов» (авторы: Адриан Моуэт, Джеймс Тернбулл).
- Статья: «Multi-stage builds» в официальной документации Docker.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


