Найти тему

Пишем Dockerfile грамотно

Оглавление

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

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

Задумайтесь что именно делает каждый шаг

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

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

Последняя команда удаляет кэш apt-get
Последняя команда удаляет кэш apt-get

Лишняя информация в докер-образе может привести к разрастанию его размера. Размер, естественно, плохо сказывается на быстром скачивании и загрузке образа в registry, что может привести к долгому запуску приложения в пайплайне деплоя.

Правильно используйте слои

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

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

Сначала - зависимости, затем - исходники
Сначала - зависимости, затем - исходники

Объединяйте однотипные шаги

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

Проверьте контекст при сборке образа

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

Лишние файлы можно исключить из сборки с помощью специального .dockerignore файла. Не пренебрегайте возможностью им воспользоваться.

Все рекомендации направлены на ускорение сборки вашего докер-образа. В некоторых случаях мне удавалось такими простыми практиками ускорить процесс сборки образа с 15 до 3 минут.
Есть еще много более сложных практик по использованию докерфайлов, возможно мы еще вернемся к данному вопросу.
Дополняйте советы в комментариях!