
Как проверить контекст сборки Docker и исключить лишние файлы


Если сборка Docker неожиданно тянет кэш, логи или учебный конфиг, проблема обычно не в команде COPY, а раньше: в контексте сборки. Контекст — это не только то, что попадет в итоговый образ, а весь набор файлов, к которым сборщик вообще может обратиться во время сборки. Поэтому полезно проверять две вещи отдельно: сколько данных Docker отправляет в сборку и какие файлы реально видны внутри шага COPY . ..
Ниже — учебный разбор на маленькой папке со статической страницей, Dockerfile, временным кэшем и фиктивным конфигом. Цель узкая: убедиться, что в контекст попадают только нужные файлы, а исключение из контекста не воспринимается как полная защита чувствительных данных.
Что Docker считает контекстом сборки
Когда вы запускаете docker build ., точка в конце означает: «возьми текущую папку как контекст сборки». Для локальной директории это важно буквально: Docker рекурсивно рассматривает вложенные каталоги, а инструкции COPY и ADD могут работать только с файлами из этого контекста. Если в папке лежат кэш, логи и тестовые конфиги, они сначала становятся доступны сборке, и только потом вы решаете, копировать их в образ или нет.
Отсюда возникает частая путаница. Файл может не попасть в итоговый образ, но все равно попасть в контекст и быть отправленным сборщику. Для локальной сборки это лишний шум, а для удаленного сборщика — еще и лишняя передача данных. Поэтому вопрос «что копирует мой Dockerfile» полезно дополнять вопросом «что я вообще отправляю в сборку».
Есть и обратная граница: сборка не видит файлы вне выбранного контекста. Если вы запускаете сборку из родительской папки, контекст может оказаться слишком широким; если из слишком узкой — нужный файл будет недоступен для COPY. Практический вывод простой: перед настройкой .dockerignore сначала проверьте, из какой директории вы запускаете docker build.
Учебная папка и правила для .dockerignore
Возьмем условную учебную структуру. Она маленькая, но хорошо показывает типичную ошибку: статическая страница занимает килобайты, а мусор вокруг — сотни килобайт.
site/
├── Dockerfile
├── index.html
├── styles.css
├── .cache/
│ └── render.bin
├── logs/
│ └── dev.log
└── config/
└── demo.env
Учебные исходные данные: index.html — 1 КБ, styles.css — 2 КБ, Dockerfile — 1 КБ, .cache/render.bin — 600 КБ, logs/dev.log — 300 КБ, config/demo.env — 1 КБ. Итого условный контекст без исключений — 905 КБ. Для страницы это заведомо лишнее.
Файл .dockerignore нужно положить в корень именно того контекста, который вы передаете в сборку. Если сборка идет из site, то и .dockerignore должен лежать в site. Совпавшие шаблоны будут удалены из контекста до отправки сборщику. В простом учебном случае достаточно такого набора:
.cache
logs
config/*.env
Такой файл говорит: не включать временный кэш, папку логов и любые .env-файлы в каталоге config. Если хочется оставить пометки для себя, строки с # в первом столбце считаются комментариями. Еще одна полезная деталь: если в проекте несколько Dockerfile для разных задач, рядом с конкретным Dockerfile можно использовать отдельный ignore-файл по специальному имени; он будет важнее корневого. Это удобно, когда для тестовой и боевой сборки нужны разные исключения.
Как проверить, что в контекст попали только нужные файлы
Проверка становится надежной, если сделать ее в два шага. Сначала смотрим, уменьшился ли объем передаваемого контекста. Затем проверяем, что внутри сборки действительно не видно исключенные файлы. Один из этих шагов без второго легко вводит в заблуждение: маленький контекст еще не доказывает правильный набор файлов, а список файлов без сравнения объема не показывает, не отправляете ли вы что-то лишнее параллельно.
Учебный пример. Ниже Dockerfile для локальной сборки в обычной shell-среде. В нем есть диагностический этап inspect, который копирует текущий контекст и печатает список файлов, а итоговый этап кладет только страницу и стили в образ с Nginx.
FROM alpine:3.20 AS inspect
WORKDIR /ctx
COPY . .
RUN find . -maxdepth 3 -type f | sort
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
COPY styles.css /usr/share/nginx/html/styles.css
Теперь последовательность проверки. Сначала сборка без .dockerignore:
docker build --target inspect --no-cache --progress=plain -t site-check .
В выводе обычно есть строка загрузки контекста. В нашем условном примере она будет близка к 905 КБ. Диагностический шаг при этом покажет, что внутри сборки видны и .cache/render.bin, и logs/dev.log, и config/demo.env. После добавления .dockerignore запускаем ту же команду повторно. Теперь ожидаемый условный результат — около 4 КБ контекста: 1 КБ HTML + 2 КБ CSS + 1 КБ Dockerfile. А в списке файлов больше не должно быть кэша, логов и фиктивного конфига.
Эта проверка дает измеримый результат, а не ощущение «стало чище». Если объем контекста почти не изменился, значит правило написано не там или не совпало с фактическим путем. Если объем уменьшился, но нужный файл пропал, правило оказалось слишком широким. Например, шаблон config удалит весь каталог, а config/*.env — только env-файлы в нем.
Где .dockerignore не помогает и почему это не полноценная защита секретов
.dockerignore решает конкретную задачу: не отправлять лишние файлы в текущий контекст сборки. Это полезно, но границы у решения узкие. Если файл уже лежит в другом месте, попал в репозиторий, оказался в удаленном tar-архиве или вы запустили сборку из слишком широкой директории, один только .dockerignore не превращается в универсальный барьер.
Именно поэтому в учебной папке лучше держать не настоящие секреты, а фиктивный файл вроде config/demo.env. Так вы спокойно отрабатываете механику исключений и не проверяете безопасность на реальных данных. Даже правильно настроенный .dockerignore не стоит описывать как полную систему защиты секретов: он уменьшает риск случайной отправки в конкретной сборке, но не отменяет необходимость отдельного хранения чувствительных значений.
Есть и еще одна практическая ловушка: разработчики иногда передают секреты через --build-arg, потому что это быстро. В документации Docker для секретов такой путь не рекомендуется. Для статьи достаточно запомнить правило без настоящих ключей: .dockerignore отвечает за состав контекста, а секреты требуют отдельного механизма и отдельной дисциплины хранения.
Короткий чек-лист перед сборкой
Чтобы не пересматривать правила наугад, удобно проверять проект по одному и тому же порядку.
- Из какой папки идет сборка? Именно она становится корнем контекста.
- Какие файлы реально нужны Dockerfile? Для статической страницы обычно это HTML, CSS и сам Dockerfile.
- Что точно лишнее? Кэш, логи, локальные env-файлы, временные каталоги редактора.
- Уменьшился ли передаваемый контекст? Смотрите на строку загрузки контекста в выводе сборки.
- Исчезли ли исключенные файлы из диагностического этапа? Проверяйте через отдельный target вроде
inspect.
Если этот цикл пройден, вы получаете проверяемый результат: сборка видит только то, что нужно для образа, и не тянет учебный мусор вместе со страницей. Для маленького проекта это экономит время на отладке, а для больших — помогает не раздувать контекст незаметно от коммита к коммиту.
Если хотите углубить тему после базовой практики, посмотрите сохраненное описание каталога курса «Docker для Production: от оптимизации образов до глубокого анализа сетевого трафика». В нем подтверждены темы многоэтапной сборки и оптимизации Dockerfile, а также отдельный блок по безопасности и hardening контейнеров. Официальная страница в исходных данных недоступна, поэтому ориентироваться стоит именно на сохраненное описание каталога.





















