Каждая инструкция в Dockerfile создаёт слой — промежуточный образ. Docker кэширует слои и переиспользует их при повторной сборке, если инструкция и её входные данные не изменились.
Как работает кэш
При сборке Docker проверяет каждую инструкцию:
- Если инструкция и её входные данные не изменились — берёт из кэша (мгновенно)
- Если что-то изменилось — пересобирает этот и все последующие слои
Порядок инструкций важен
Плохой порядок — при любом изменении кода пересобираются зависимости:
FROM python:3.11-slim
WORKDIR /app
COPY . . # ← копируем всё сразу
RUN pip install -r requirements.txt # ← пересобирается при каждом изменении кода!
CMD ["python", "app.py"]
Правильный порядок — зависимости собираются только при изменении requirements.txt:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt . # ← сначала только requirements.txt
RUN pip install -r requirements.txt # ← кэшируется если requirements не изменился
COPY . . # ← код копируем после зависимостей
CMD ["python", "app.py"]
Правило: располагай инструкции от самых редко меняющихся к самым часто.
Просмотр слоёв
# Показать слои образа
docker history myapp:v1
# Подробная информация о слоях
docker inspect myapp:v1
Инвалидация кэша
# Собрать без кэша
docker build --no-cache -t myapp:v1 .
# Пересобрать с конкретного шага — измени инструкцию или добавь ARG:
ARG CACHEBUST=1
RUN apt-get update
Multi-stage builds — уменьшаем финальный образ
Сборочный образ содержит компиляторы и инструменты. Финальный — только результат.
# Стадия сборки
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Финальный образ
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
CMD ["python", "app.py"]
Финальный образ не содержит pip, компиляторов и промежуточных файлов — только то что нужно для запуска.
Размер образа: советы
- Используй
slimилиalpineбазовые образы - Объединяй несколько
RUN apt-get installв одну инструкцию - Удаляй кэш пакетного менеджера:
&& rm -rf /var/lib/apt/lists/* - Используй
.dockerignore - Используй multi-stage builds для компилируемых языков
💬 Комментарии (0)
Комментариев пока нет
Станьте первым, кто поделится мнением об этой статье!