Консультация по продукту 1cloud

5 приемов оптимизации сборки Docker-образов

Согласитесь, хранить образ Nginx размером в 200+ Мбайт. на базе Debian 9 — довольно накладно, поэтому рассмотрим 5 приемов по уменьшению размера собираемых образов.

Прием 1 — уменьшаем количество слоев в образе

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

RUN apt-get update && apt-get install -y nginx

Об этом приеме мы не раз упоминали в статье «Введение в Docker: образы, контейнеры и докер-файлы». Если вы ещё не читали нашу статью — рекомендуем с ней ознакомиться.

Прием 2 — удаляем ненужный кэш apt-get

Пакетный менеджер apt-get, обновляя репозиторий, сохраняет кэш, который в большинстве случаев не нужен, и его можно удалить, уменьшив тем самым собираемый образ на 100+ Мбайт. Сделать это совсем несложно, достаточно в инструкции RUN последней командой указать: && rm -f /var/lib/apt/lists/*.

Соединим оба приёма в одну инструкцию:

RUN apt-get update && apt-get install -y nginx && rm -f /var/lib/apt/lists/*

Такая конструкция работает именно в одной инструкции RUN, если вы вынесете rm -f /var/lib/apt/lists/* в отдельный RUN — ничего не сработает, так как кеш будет очищаться в другом слое, а его обновление будет оставаться в предыдущем слое.

Прием 3 — копируем только нужные файлы проекта в образ с помощью .dockerignore-файла

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

Исправить ситуацию призван .dockerignore-файл, который работает так же как и .gitignore-файл. В этих файлах указываются те папки и файлы, которые «не надо трогать». Gitignore-файл располагается в корневом каталоге копируемого в образ проекта. Обратите внимание на точку в начале названия файла — «.gitignore», так и должно быть.

Рассмотрим пример работы .gitignore-файла. Например, мы работаем с GIT, и в нашем проекте есть GIT-репозиторий. В образе он нам не нужен, поэтому его можно не копировать, а ещё в образе нам не нужен Dockerfile. Укажем эти файлы в .gitignore-файле:

.GIT
Dockerfile

При сборке образа Docker прочтет .dockerignore-файл и не включит в образ указанные в нем папки и файлы.

Приём 4 — используем минималистические Linux-образа Alpine

Как правило, для сборки образов применяются дистрибутивы Debian, Ubuntu, CentOS. Но это оправдано в том случае, если ваш проект будет использовать всё обилие возможностей ядра и пакетов, которые предоставляет выбранный дистрибутив. Если же вам нужно просто создать контейнер с Nginx или иной другой программой — используйте Alpine-сборки.

Alpine-образ весит считанные мегабайты, а не сотни Мбайт как Debian или Ubuntu, при этом в нём есть всё необходимое для запуска большинства приложений. Например, так выглядит dockerfile Nginx-образа на Alpine-сборке, который занимает 7 Мбайт:

FROM alpine
RUN apk add --no-cache nginx && mkdir -p /run/nginx
EXPOSE 80
COPY custom.conf /etc/nginx/conf.d
dockerCOPY . /opt/
CMD ["nginx”,”-g”,”daemon off;”]

Еще один бесспорный плюс Alpine — скорость сборки образа. Она разительно отличается в лучшую сторону по сравнению со скоростью сборки на любом другом дистрибутиве Linux.

Прием 5 — часто изменяемые слои ставим в конец dockerfile

Слоистая структура Docker-образов имеет одно неприятное свойство — при внесении изменения в один из слоев, это слой и все последующие слои будут пересобраны. Поэтому, чтобы сэкономить время на сборке образа — старайтесь ставить инструкции копирования кода проекта и конфигов в конец dockerfile до команды CMD или ENTRYPOINT.


Если вы интересуетесь Docker и контейнеризацией в целом, вам могут быть интересны следующие материалы:


Средняя оценка: 5,0, всего оценок: 4