Оптимизация образов
Оптимизация пространства и времени
Сборка образа может занимать заметное время, а готовый образ может быть довольно объёмным: он потребует много места на диске и будет долго передаваться по сети. Дополнительное место на диске займёт и билд-кеш образа: хранилище слоёв создаваемого образа.
Следовательно, есть практический смысл в том, чтобы оптимизировать процесс сборки образа и сэкономить на этом пространство и время.
Оптимизация сборки образов
Каждая инструкция в Dockerfile — это отдельный образ, его называют «слой». Чем меньше промежуточных слоев в докерфайле — тем быстрее происходит сборка образа.
При сборке слои кешируются: сохраняются в так называемом build-cache. Чем меньше слоёв — тем меньше объем билд-кеша.
Объединение команд
Вот несложный докерфайл: при сборке образа обновится APT, а затем установятся сервер, БД и интерпретатор Python
Скопировать кодDOCKER
RUN apt update
RUN apt upgrade
RUN apt install nignx
RUN apt install postgres
RUN apt install python3
Но образ состоит из пяти слоев при том, что можно обойтись всего одним: эти пакеты устанавливаются однократно и не будут изменяться. Пусть они сохранятся в билд-кеш в виде одного образа, а не пяти отдельных:
Скопировать кодDOCKER
RUN apt upgrade && apt update && \
apt install nginx postgres python3
Команды в инструкции RUN объединяются двойным амперсандом: &&. Для читаемости строки в докерфайле можно переносить, обозначая перенос обратным слешом \.
Кеширование при сборке
Докер при сборке образа использует общий кеш для всех образов. При создании образа Yamdb первые инструкции в докерфайле были такие: установить базовым слоем образ python и создать пустую директорию code:
Скопировать кодDOCKER
FROM python:3.8.5
RUN mkdir /code
...
Эти два слоя (как и последующие) были сохранены в билд-кеше.
Если при создании нового образа вы укажете в докерфайле те же команды — докер не будет собирать первые два слоя, а возьмёт из кеша готовые слои, те, что были созданы при сборке образа Yamdb.
Но если порядок слоёв изменён, добавлен новый слой или изменено содержимое слоя — докер будет собирать образ без кеша: ведь изменённый слой влияет на все последующие.
Скопировать кодDOCKER
FROM python:3.8.5
ENV secret_key mysecretkey # этот и последующие слои будут создаваться без применения кеша
RUN mkdir /code
...
Продолжая описывать образ в докерфайле, придётся выбирать, в каком порядке выполнять инструкции.
Что рациональнее: сперва установить nginx и postgres, и только после этого копировать в образ код приложения, COPY . /code?
Скопировать кодDOCKER
FROM python:3.8.5
ENV secret_key mysecretkey
RUN mkdir /code
RUN apt upgrade && apt update && \
apt install nginx postgres
...
COPY . /code
CMD python hello.py
Или наоборот, сначала добавить в образ код приложения, и лишь затем установить сервер и базу данных?
Скопировать кодDOCKER
FROM python:3.8.5
ENV secret_key mysecretkey
RUN mkdir /code
COPY . /code
...
RUN apt upgrade && apt update && \
apt install nginx postgres
CMD python hello.py