Сборка незаметно ходит в сеть: проверяем RUN --network=none
Dockerfile сначала скачивает зависимости, а затем компилирует приложение. Кажется, что второй шаг полностью локальный. Но однажды сборка начинает зависеть от внешнего сервиса: build-скрипт скачивает дополнительный файл или инструмент автоматически проверяет обновление. Изменение видно только при сбое сети. Явное отключение сети у конкретного RUN помогает обнаружить такую скрытую зависимость.
Речь идёт о сети процесса сборки, а не будущего контейнера. Настройки networks в Compose описывают runtime-сервисы и сами по себе не делают сборочный шаг автономным. Если файлы уже должны находиться в контексте или предыдущем слое, можно проверить это требование непосредственно там, где они используются.
Разделить получение и использование
Сначала загружаем wheels с внешнего индекса. Затем отдельный шаг установки использует только подготовленный каталог. Пример требует BuildKit и современного frontend Dockerfile:
# syntax=docker/dockerfile:1
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip download --dest /wheels -r requirements.txt
RUN --network=none pip install --no-index --find-links=/wheels -r requirements.txt
Для действительно автономной установки набор загруженных файлов должен покрывать все зависимости выбранной платформы. Если попался исходный пакет, сборке могут понадобиться дополнительные build-зависимости. Лучше заранее проверить состав wheels и не считать удачный запуск на одной архитектуре гарантией для другой.
Флаг --no-index описывает намерение pip, а --network=none ограничивает сеть самого шага. Это два разных уровня. Первый делает ошибку понятнее, второй помогает обнаружить обращение к сети у вложенного инструмента. Наличие /wheels в предыдущем слое делает вход видимым, но само по себе не фиксирует версии: для этого отдельно нужны ограничения зависимостей и при необходимости проверка хешей.
Не принять cache за проверку
Если шаг взят из кэша, его команда в этом запуске не исполнялась. При проверке автономности посмотрите журнал сборки и заставьте нужный этап действительно выполниться на учебном проекте. Иначе зелёная строка CACHED подтверждает только наличие прежнего результата, а не возможность выполнить установку без сети сейчас.
Полезно провести отрицательный опыт: убрать из подготовленного каталога одну требуемую зависимость в отдельном тестовом Dockerfile. Установка должна завершиться понятной ошибкой, а не скачать недостающее незаметно. Затем верните полный набор и повторите сборку. Так проверяется граница между этапом получения материалов и их использованием.
После этого внешний сетевой сбой влияет на предсказуемый шаг загрузки, а локальная установка не зависит от доступности индекса. Такая структура упрощает расследование медленной сборки и перенос на изолированный builder. Но автономность одного RUN не означает автономность всего Dockerfile: FROM и другие сетевые этапы по-прежнему нужно учитывать отдельно.
Продолжить практику
Эту настройку проще понимать в составе приложения, у которого есть сеть, данные и понятная процедура обновления. На курсе «Docker и Docker Compose: контейнеризация приложений» вы упакуете HTTP-сервис с PostgreSQL, разберёте конфигурацию, хранение данных и диагностику сбоев. В программе есть локальные лабораторные, работа с registry и версиями образов; итоговый проект включает передачу окружения другому разработчику и проверку восстановления базы.
Источник: официальная документация.
Другие задачи по теме: Процессы, сеть, тома и сборка контейнера.
Продолжить на практике
- Docker и Docker Compose: контейнеризация приложений ↗
Упакуйте приложение в Docker и запустите его с PostgreSQL через Compose. Образы, сети, тома, диагностика поломок, обновление версий и восстановление данных — с практикой и итоговым проектом.
