Comments 6
Понимаю что это перевод, но всё же: в итоговом докерфайле для билд-образа сначала копируется список зависимостей самого проекта (COPY ./requirements.txt .
), а потом устанавливаются нужные инструменты (git, pip):
FROM alpine:latest AS build
WORKDIR /app
COPY ./requirements.txt .
RUN apk add --no-cache git python3 py3-pip
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip3 install --no-cache-dir -r requirements.txt
RUN pip3 uninstall -y pip setuptools packaging
FROM alpine:latest AS release
# ...
Это значит, что при каждом изменении в файле requirements.txt не будет работать кэш для последующих слоёв. Если переставить строки местами - сначала устанавливать нужные вещи, которые не зависят непосредственно от содержимого requirements.txt, а потом уже копировать его - можно ещё ускорить билд.
сюда можно еще "колёса" прикрутить в билд, чтобы быстрее работало
RUN pip wheel --no-cache-dir --no-deps --wheel-dir ./wheels -r requirements.txt
А в релизе уже
COPY --from=build ./wheels /wheels
COPY --from=build ./requirements.txt .
RUN pip install --upgrade pip
RUN pip install --no-cache /wheels/*
Колёса (Wheel-файлы) значительно ускоряют установку, так как они уже скомпилированы
Вроде как есть привычный термин - не "разделенный образ", а multi-stage.
Ну и это известно, что каждая команда порождает слой, поэтому их надо минимизировать, упихивать в одну строку.
RUN pip3 uninstall -y pip setuptools packaging
FROM python:3.11-slim AS release
Вот этот кусок кода вообще не понял - зачем uninstall, если начинаем новый образ?
Что за дичь вы проповедуете? Соединить все RUN через && \ религия не позволяет?
RUN вообще может быть одна, со всеми install и remove, так же как и COPY.
EXPOSE, ЕNV, WORKDIR, и CMD должны быт в одном экземпляре в самом конце.
А если вам действительно нужна безопастность и маленькие образы, то distroless единственный вариант. Недаром сами K8s перешли именно на GCP distroless. Даже по сравнению с Oracle Linux или RHEL, у Alpine такое огромное кол-во CVE, что его никто в проде не использует.
Как оптимизировать размер контейнерного образа в Docker