Dockerfile
Урок 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?