Деплой и инфра
Image layers: оптимизируй реальный Dockerfile
Читать про кэш-префиксы и multi-stage build — не то же самое, что превратить четырёхминутную CI-сборку в двадцатисекундную. Возьми намеренно плохой Dockerfile, загони его во все три режима отказа — буксование кэша, раздутие образа и утёкший секрет — затем перепиши и докажи каждый фикс измерениями.
Преврати ментальную модель юнита в воспроизводимый инженерный цикл: измерь базовую сборку, переупорядочь под кэш-префикс, разбей на multi-stage для тонкой отгрузки, отфильтруй build-контекст, устрани секрет из истории слоёв и подтверди каждое изменение числами до/после.
Возьми намеренно плохой Dockerfile (своё приложение или стартовый, описанный ниже) и перепиши так, чтобы обычная правка исходника пересобиралась за секунды вместо минут, опубликованный образ упал минимум вдвое, а ни один секрет не выживал в истории слоёв — доказывая каждый шаг измерениями, а не заявлениями.
- Таблица до/после: время холодной сборки, время тёплой-пересборки-после-одной-правки, размер финального образа и размер переданного build-контекста — измеренные, а не оценённые.
- Тёплая пересборка после однострочной правки исходника больше не перезапускает установку зависимостей (видно как 'CACHED' в выводе сборки), а финальный образ минимум на 50% меньше single-stage базы.
- docker history (или извлечение слоёв) финального образа не показывает восстановимого токена и файла .env ни в одном слое.
- Короткий разбор, сопоставляющий каждое изменение с механизмом, который оно эксплуатирует: кэш-префикс, кэширование по тексту RUN, multi-stage discard, фильтрация build-контекста и безопасность секретов в неизменяемых слоях.
- Добавь CI-кэш: включи BuildKit registry или GitHub Actions cache (--cache-from / --cache-to), чтобы выигрыш тёплой пересборки пережил эфемерные CI-раннеры, и покажи попадание слоя install в кэш на свежем раннере.
- Добавь CI-гейт по размеру и секретам: вали сборку, если финальный образ растёт сверх порога, и прогоняй сканер секретов (например, trivy или dockle) по слоям образа, чтобы повторно внесённый секрет ломал пайплайн.
- Повтори упражнение multi-stage для второго языка (Go-бинарь на scratch/distroless/static и Node-приложение на distroless) и сравни, насколько маленьким может стать каждый рантайм и почему.
- Запинь базовый образ по digest и добавь правило renovate/dependabot, затем покажи, как смена digest инвалидирует ровно ожидаемый префикс слоёв и ничего раньше.
Это цикл, который ты будешь запускать на каждом реальном Dockerfile: сначала измерь, переупорядочь под кэш-префикс, чтобы дорогой install оставался хитом, слей update-and-install, перейди на multi-stage для тонкой отгрузки, отфильтруй контекст через .dockerignore и убери секреты из истории слоёв через secret mount или отбрасываемый builder stage — подтверждая каждое изменение числами до/после в одинаковых условиях. Сделав это раз на намеренно плохом Dockerfile, ты доводишь production-переписывание до мышечной памяти: порядок, тонкость, ignore и никогда не rm секрет.