Dockerfile
1Dockerfile: создаём свой образ2Слои и кэш: быстрая сборка образов← вы здесь3Multi-stage builds: маленькие продакшн-образы
Урок 2~9 минут

Слои и кэш: быстрая сборка образов

Docker кэширует каждый слой. Правильный порядок инструкций — разница между 30 секундами и 3 минутами на каждой сборке.

Как работает кэш

При сборке Docker проверяет каждый слой:

  • Если инструкция и входные данные не изменилисьUsing cache
  • Если изменились → пересобирает этот слой и все последующие

Попробуй в симуляции

Проблемный порядок

dockerfile
FROM node:20-alpine
WORKDIR /app
 
COPY . .              # ← копируем ВСЁ
RUN npm install       # ← устанавливаем зависимости
 
CMD ["node", "server.js"]

Проблема: любое изменение кода (даже в одном файле) инвалидирует COPY . .RUN npm install пересобирается заново. Каждый раз — полная переустановка зависимостей.

Правильный порядок

dockerfile
FROM node:20-alpine
WORKDIR /app
 
COPY package*.json ./     # ← только манифест зависимостей
RUN npm ci                # ← кэшируется пока package.json не изменится
 
COPY . .                  # ← код приложения (меняется часто)
 
CMD ["node", "server.js"]

Теперь npm ci выполняется только когда меняется package.json. Изменение кода → только пересборка последнего слоя.

Принцип

Стабильное → изменяемое. Инструкции, которые меняются реже, должны стоять выше.

dockerfile
FROM python:3.12-slim        # 1. Базовый образ (меняется редко)
WORKDIR /app
 
COPY requirements.txt .      # 2. Зависимости (меняются изредка)
RUN pip install -r requirements.txt
 
COPY . .                     # 3. Код (меняется часто)
 
CMD ["python", "app.py"]

Каждый RUN — отдельный слой

dockerfile
# Три слоя, промежуточный мусор ОСТАЁТСЯ
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*
 
# Один слой, мусор УДАЛЁН в том же слое
RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*

Удаление файлов в отдельном RUN не уменьшает образ — слой с файлами уже сохранён.

Просмотр слоёв

bash
docker history my-app       # все слои с размером
docker inspect my-app       # JSON с метаданными слоёв

Squash и BuildKit

bash
# BuildKit — ускоренная сборка (включён по умолчанию в Docker 23+)
DOCKER_BUILDKIT=1 docker build .
 
# Параллельные стадии, лучший кэш, секреты без утечки в слои

В следующем уроке — multi-stage builds: маленькие продакшн-образы.

Docker кэширует каждый слой. Изменение слоя инвалидирует все последующие. Ставь стабильное (зависимости) перед изменяемым (код).
📦
Слои Docker образа
CMD ["node", "server.js"]
Точка входа
0 BREBUILD
COPY . .
Исходный код приложения
840 KBREBUILD
RUN npm ci
Установка зависимостей
124 MBCACHED
COPY package*.json ./
Только манифест зависимостей
1.2 KBCACHED
WORKDIR /app
Рабочая директория
0 BCACHED
FROM node:20-alpine
Базовый образ Node.js Alpine
51 MBCACHED
4
слоёв кэшировано
2
слоёв пересобрать
✅ Зависимости копируются отдельно — npm ci кэшируется пока package.json не изменится
🎯
Миссия 1 из 3
Почему COPY package.json идёт до COPY . . в хорошем Dockerfile?