Перейти к содержанию

Dockerfile

Dockerfile
это текстовый документ, содержащий инструкции для создания образа Docker.

Зачем это нужно

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


Как работает

  1. Создается файл под названием Dockerfile в директории проекта (где лежит ваше написанное приложение).
  2. В этом файле указываются инструкции для создания образа Docker.
  3. Происходит создание образа Docker через команду docker build.
  4. Созданный образ Docker можно запускать с помощью команды docker run.

Инструкции Dockerfile

Примечание

Инструкции Dockerfile состоят из команд, которые используются для создания образа Docker. Каждая инструкция представлена в виде строки в Dockerfile. Каждая инструкция создает слой в образе Docker.

Особенности

Все инструкции Dockerfile должны быть написаны заглавными буквами.

Инструкция Что делает
FROM задает базовый образ на основе которого мы создаем создаем свой.
LABEL описывает метаданные образа. Это атрибут только Dockerfile и не идет в будущий образ. Обычно описывает кто создал Dockerfile и версию образа.
ARG предоставляет способ задавать переменные и их значения по умолчанию, которые доступны только во время сборки образа. Переменная не сохраняется в готовом контейнере и недоступна для запущенного контейнера
LABEL метки, позволяющие добавлять метаданные с помощью пар "ключ-значение", которые затем можно использовать для поиска и идентификации контейнеров и образов Docker
USER Задает пользователя, от которого будут выполняться все последующие команды.
ENV задает переменные командной оболочки, которые приложение может использовать для конфигурации во время работы, а также в процессе сборки. Приложение внутри контейнера может обращаться к этой переменной.
RUN выполняет команду в оболочке командного интерпретатора во время сборки образа
COPY копирует файлы из локальной файловой системы (контекста сборки) в наш образ
ADD похож на COPY, отличие в том, что ADD позволяет копировать файлы в образ через интернет
WORKDIR меняет рабочий каталог в образе для остальных инструкций сборки и процесса по умолчанию, который запускается с получившимися контейнерами
CMD определяет команду, запускающую процесс, который будет выполняться в конейнере
EXPOSE определяет порты, которые будут открыты в конейнере
ENTRYPOINT определяет команду, которая будет запускаться при запуске конейнера

Важно

Команда FROM является единственной обязательной инструкцией в Dockerfile.

Ни ARG, ни ENV не подходят для хранения паролей и токенов.

ARG — переменные этапа сборки (docker build), ENV — переменные времени выполнения контейнера (docker run).


Примеры использования инcтрукций Dockerfile

Примеры
FROM <image>[:<tag>]
FROM ubuntu:22.04
FROM python:3
FROM nginx

LABEL <key>=<value>
LABEL maintainer="John Doe" version="1.0"

COPY <src> [<src> ...] <dest>
<src> файл или директория внутри **build** контекста
<dest> целевая директория внутри контейнера
COPY start* /startup/
COPY httpd.conf magicfile /etc/httpd/conf/

ENV <key> <value>
<key> имя переменной окружения
<value> присваиваемое значение
ENV LOG_LEVEL debug
ENV DB_HOST 10.10.50.2:3389

ARG <key>[=<default value>]
<key> имя переменной окружения
<value> значение по умолчанию, опционально
ARG VERSION=latest
FROM ubuntu:${VERSION}
ARG BUILD
ENV BUILD=v1.0.0
RUN echo $BUILD

WORKDIR <path>
<path> путь внутри контейнера

USER <username>:<group>
USER <UID>:<GID>
USER www-data
USER postgres

RUN <command>
<command> которая будет выполняться при ``сборке образа``
RUN apt update && apt install python
RUN ["bash", "-c", "rm", "-rf", "/tmp/dir"]
RUN ["myscript.py", "arg1", "arg2"]

CMD <command>
<command> которая будет выполняться при ``старте контейнера``
CMD /start.sh
CMD ["echo", "Hello World"]
CMD ["python3", "manage.py", "runserver"]

ENTRYPOINT <command>
<command> которая будет выполняться при ``старте контейнера``
ENTRYPINT exec top -b
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
ENTRYPOINT ["/bin/sh", "/docker-entrypoint.sh"]

VOLUME <path> [<dest>....]
<dest> директория монтирования для тома
VOLUME /app /db /data
VOLUME ["/var/www", "/var/log/apache", "/etc/apache2"]

EXPOSE <port>[/<proto>]
<port> порт сервиса внутри конейнера
<proto> tcp/udp опционально
EXPOSE 5050
EXPOSE 8080/tcp 3389/udp

HEALTHCECK [<OPTIONS>] CMD <command>
OPTIONS - возможные параметры проверки:
--interval=DURATION (по умолчанию: 30s)
--timeout=DURATION (по умолчанию: 30s)
--start-period=DURATION (по умолчанию: 0s)
--retries=COUNT (по умолчанию: 3)
<command> команда которая будет выполнена для проверки работоспособности
HEALTHCHECK --interval=3m --timeout=3s CMD curl -f http://localhost/ || exit 1

Сборка образа

В интерфейсе командной строки Docker есть флаг build, который позволяет на основе Dockerfile собрать образ Docker.

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

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

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

Часто сборка Docker выполняется одним вызовом команды docker build, при котором создается один артефакт - образ контейнера.

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


Рекомендации

  • Избегайте установки лишних пакетов и упаковки лишних данных в образы при сборке (build context bloating)
  • Используйте связанные команды для RUN инструкций
  • Следите за последовательностью описания Dockerfile, избегаем cache miss
  • Уменьшайте кол-во слоев
  • Один контейнер - одна задача
  • Чистите за собой
  • Используйте multi-stage сборки

Путь работы с Docker

1) Создать Dockerfile

FROM nginx
COPY index.html /usr/share/nginx/html
2) Собрать образ
docker build -t my-nginx .
3) Запустить контейнер
docker run -p 80:80 my-nginx
4) Проверить работоспособность
curl http://localhost
5) Остановить контейнер
docker stop my-nginx