Как устранять проблемы с окружением при работе с Docker
DevOpsдокерконтейнерыокружениепроблемы
Что проверяют
Есть ли у кандидата процедура отладки, а не набор заклинаний. Интервьюер хочет услышать, как человек локализует слой, где сломалось: образ, конфигурация, сеть или сам код.
Как отвечать
Порядок диагностики:
docker compose psиdocker compose logs -f <service>: контейнер упал сразу или крутится в рестарт-петле, что в последних строках.docker compose config: печатает итоговую конфигурацию после подстановки переменных из.env. Половина случаев «переменная не подхватилась» видна прямо тут.- Зайти внутрь:
docker compose exec app shдля живого контейнера,docker compose run --rm app shесли контейнер падает на старте. docker inspectдля смонтированных томов, сетей и итогового набораEnv.
Типичные причины:
- Переменные:
ARGдоступен только во время сборки,ENVв рантайме. Значения, которые вкомпилируются в артефакт при сборке, надо передавать черезbuild.args, а не черезenvironment, иначе они просто не доедут. - Сеть: внутри контейнера
localhostэто сам контейнер. К соседнему сервису обращаются по имени сервиса из compose (db:5432), к хост-машине черезhost.docker.internal.EXPOSEничего не публикует наружу, публикуетports. - Тома: bind-mount кода поверх рабочего каталога перекрывает то, что положил
Dockerfile, включая установленные внутрьsite-packagesилиnode_modules. Отсюда классическое «при сборке всё поставилось, а в рантайме модуля нет». - Кэш слоёв: поменяли
requirements.txt, а слой установки взялся из кэша, потому что копирование файла шло после копирования кода. Правильный порядок:COPY requirements.txt, установка, затемCOPY . .. Проверка гипотезы: сборка с--no-cache. - Архитектура: образ, собранный на Apple Silicon, на amd64-сервере падает с
exec format error. Лечится--platform linux/amd64или мультиарх-сборкой через buildx. - Права: файлы, созданные root-процессом внутри контейнера, не редактируются на хосте. Решается ключом
user:в compose или непривилегированным пользователем в образе. - Готовность зависимостей:
depends_onбезcondition: service_healthyждёт только старта контейнера, а не готовности Postgres принимать соединения.
Профилактика: пин базового образа по тегу с версией или digest вместо latest, лок-файл зависимостей, .dockerignore, чтобы локальный .venv не уезжал в образ, healthcheck у сервисов, один и тот же образ в CI и на проде.
Где спотыкаются
Ограничиваются ответом «посмотрю логи и пересоберу с --no-cache». Пересборка чаще прячет причину, чем находит: реальная разница обычно в переменных сборки против рантайма или в томе, перекрывшем содержимое образа.