Введение
Эта статья объясняет, как создаются образы в Docker, начиная с контекста сборки и кэширования, заканчивая выбором базовых образов и использованием инструкций Dockerfile. Вы узнаете, как эффективно управлять процессом сборки, минимизировать ошибки и оптимизировать образы для различных задач.
Контекст создания образов
Контекст создания образа — это набор файлов, который Docker использует при выполнении команды docker build. Обычно это текущая директория (.), содержащая Dockerfile и необходимые файлы. Docker также поддерживает контекст из git-репозиториев, если путь начинается с префиксов github.com/, git@ или git://. Однако рекомендуется вручную указывать файлы для большей гибкости и контроля.
Также можно передать Dockerfile через стандартный ввод (STDIN), используя docker build - < Dockerfile. В этом случае контекст отсутствует, и используются только инструкции из Dockerfile.
Как создаются образы
Образы в Docker состоят из уровней, каждый из которых создаётся при выполнении инструкции в Dockerfile. Каждый уровень — это статическая файловая система с метаданными. Во время сборки Docker запускает временный контейнер для выполнения инструкции, сохраняет результат как новый уровень и удаляет контейнер (если не указан --rm=false). Активные процессы, запущенные в инструкции RUN, завершаются после её выполнения, поэтому для долговременных процессов используйте ENTRYPOINT или CMD.
Чтобы просмотреть уровни образа, используйте команду docker history. Пример:
$ docker history mongo:latest
IMAGE CREATED CREATED BY
278372cb22b2 4 days ago /bin/sh -c #(nop) CMD ["mongod"]
341d04fd3d27 4 days ago /bin/sh -c #(nop) EXPOSE 27017/tcp
ebd34b5e9c37 4 days ago /bin/sh -c #(nop) ENTRYPOINT &{["/entrypoint."]
f3b2b8cf226c 4 days ago /bin/sh -c #(nop) COPY file:ef2883b33ed7ba0cc
... Если сборка завершилась с ошибкой, можно запустить последний успешный уровень для отладки. Пример Dockerfile:
респ
FROM busybox:latest
RUN echo "This should work"
RUN /bin/bash -c echo "This won't"
Команда сборки:
$ docker build -t echotest .
Step 0 : FROM busybox:latest
---> 4986bf8c1563
Step 1 : RUN echo "This should work"
---> Running in f63045cc086b
This should work
---> 85b49a851fcc
Removing intermediate container f63045cc086b
Step 2 : RUN /bin/bash -c echo "This won't"
---> Running in e4b31d0550cd
/bin/sh: /bin/bash: not found
The command '/bin/sh -c /bin/bash -c echo "This won't"' returned a non-zero code: 127
Для отладки можно запустить последний успешный образ:
$ docker run -it 85b49a851fcc
/ # /bin/bash -c "echo hmm"
/bin/sh: /bin/bash: not found
/ # /bin/sh -c "echo ahh!"
ahh!
/ # Анализ: Ошибка произошла из-за отсутствия bash в образе busybox.
Кэширование
Docker кэширует уровни для ускорения сборки. Кэш используется, если инструкция и её родительский уровень не изменились. Однако кэш может быть некорректным, если файлы или метаданные изменились (для инструкций COPY и ADD). Чтобы отключить кэширование, используйте docker build --no-cache. Пример нежелательной практики:
ENV UPDATED_ON "14:12 17 February 2015"
RUN git clone... Совет: Избегайте таких строк, так как они могут запутать пользователей из-за несоответствия дат.
Базовые образы
Выбор базового образа — важный шаг. Официальные образы, такие как mysql или nginx, предпочтительны, так как они оптимизированы для работы в контейнерах. Для собственных приложений используйте образы, соответствующие языку программирования (например, python, node). Для минимализма подойдёт alpine (5 МБ), для более широких возможностей — debian. Образ scratch подходит для минималистичных бинарных образов, но требует статической компиляции.
Образ phusion/baseimage включает сервисы, такие как init, cron и SSH, но это увеличивает размер. Используйте его только при необходимости множества процессов.
Инструкции Dockerfile
Основные инструкции Dockerfile:
- ADD: Копирует файлы или распаковывает архивы. Используйте
COPYдля простых задач илиRUNсcurl/wgetдля загрузки. - CMD: Задаёт команду для запуска контейнера. Может быть переопределена в
docker run. - COPY: Копирует файлы из контекста в образ. Поддерживает JSON-формат для путей с пробелами.
- ENTRYPOINT: Определяет выполняемую программу. Аргументы
CMDилиdocker runпередаются ей. - ENV: Устанавливает переменные среды.
- EXPOSE: Указывает порты для контейнера.
- FROM: Задаёт базовый образ. Всегда указывайте тег версии.
- MAINTAINER: Указывает автора образа.
- ONBUILD: Задаёт инструкции для дочерних образов.
- RUN: Выполняет команду и сохраняет результат.
- USER: Задаёт пользователя для инструкций.
- VOLUME: Объявляет том для данных.
- WORKDIR: Устанавливает рабочий каталог.
Заключение
Создание образов в Docker требует понимания контекста сборки, кэширования, выбора базового образа и правильного использования инструкций Dockerfile. Оптимизация этих процессов повышает эффективность и упрощает сопровождение контейнеров.
Отзывы