Небольшой совет по уменьшению размера ваших образов Docker

Привет всем, первый пост на dev.to, желаю быть более активным в будущем!

Сегодня я хочу рассказать о небольшом совете, который я недавно придумал для уменьшения размера образов Docker, в моем случае я смог уменьшить размер в два раза!

Предположим, что вы работаете с таким языком, как Ruby или Python, даже если эти языки не компилируются, им часто нужны некоторые системные библиотеки для правильной работы, в частности, если вы работаете с базами данных (MySQL, SQLite, Postgres), вам нужно скомпилировать gem или библиотеку для конкретной архитектуры вашей машины.

В моем случае я работаю с Ruby и пытаюсь установить гем SQLite, который, к сожалению, требует системную библиотеку build-base.

Вот проект, над которым я работаю:
Faenz Analytics

Поэтому я решил установить его, скомпилировать SQLite gem и удалить все, что мне больше не нужно, вот мой Dockerfile:

FROM ruby:3.0.4-alpine3.15
WORKDIR /faenz-analytics
RUN apk update && 
    apk add make && 
    apk add build-base &&  # this takes 200Mb of space!!
    apk add sqlite-dev

# ...some instructions

RUN bundle install  # installing Ruby gems
RUN apk del build-base

# ...some other instructions
Войти в полноэкранный режим Выход из полноэкранного режима

Все просто, верно? Мы установили build-base, скомпилировали и установили гемы и удалили build-base, чтобы уменьшить размер изображения.

Проблема в том, что это не работает! Размер изображения такой же, как если бы мы не удалили build-base. Давайте выясним, почему.

Мы написали три инструкции RUN, каждая из которых генерирует слой, и эти слои объединяются Docker для создания конечного образа:

  1. первая RUN устанавливает системные библиотеки
  2. второй RUN устанавливает gems/библиотеки Ruby или любого другого используемого вами языка
  3. третий RUN удаляет системные библиотеки

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

Это как сумма без отрицательных чисел. Размер может только увеличиваться или оставаться неизменным от слоя к слою.

Что? Не сдавайтесь, мы справимся 🚀.

Вот решение: поместите эти операции в один слой!

FROM ruby:3.0.4-alpine3.15
WORKDIR /faenz-analytics
RUN apk update && 
    apk add make && 
    apk add sqlite-dev

# ...some instructions

RUN apk add build-base && 
    bundle install && 
    apk del build-base

# ...some other instructions
Вход в полноэкранный режим Выход из полноэкранного режима

Группировка операций в одной инструкции RUN позволяет Docker не тратить место на хранение build-base в слое. Слой создается в конце инструкции, поэтому мы собираемся установить, использовать build-base и предварительно удалить его, чтобы слой не содержал его вообще.

С помощью этого маленького совета размер моего изображения уменьшился с 400 Мб до 170 Мб, менее чем в два раза!

Если вы хотите утрировать с микро оптимизацией, вы можете применить то же решение к apk update (или apt-get update для образов debian/ubuntu), удалив кэш, созданный этой командой:

RUN apk update && 
    add build-base && 
    # install other dependencies here...
    bundle install && 
    apk del build-base && 
    rm -rf /var/cache/apk && 
    rm -rf tmp/cache
Войдите в полноэкранный режим Выйти из полноэкранного режима

Я не эксперт по Docker, поэтому, если вы знаете лучшее решение или хотите поделиться похожими советами по уменьшению размера изображения, пожалуйста, оставьте комментарий, я весь внимание 🙏

Оцените статью
Procodings.ru
Добавить комментарий