Какая примерная структура Dockerfile в вашем проекте
Что проверяют
Работали ли вы с Docker руками, а не только запускали готовый docker compose up, и знаете ли про кеш слоёв и безопасность образа. Следом спрашивают, почему инструкции идут именно в таком порядке и под каким пользователем работает приложение.
Как отвечать
Опишите свой реальный Dockerfile, но разложите его по шагам с причинами. Типичный каркас для Python-сервиса:
- база:
python:3.13-slimс зафиксированной минорной версией, никакихlatest. Slim меньше полного образа и обходится без сюрпризов Alpine, где из-за musl часть пакетов приходится собирать из исходников; - многоэтапная сборка: в стадии
builderставятся компиляторы и заголовки, собирается виртуальное окружение, а в финальный образ копируется только оно; - переменные:
PYTHONDONTWRITEBYTECODE=1иPYTHONUNBUFFERED=1, чтобы логи сразу уходили в stdout; - зависимости до кода: сначала
COPY requirements.txtилиpyproject.tomlс lock-файлом, затемpip install --no-cache-dir -r requirements.txtилиuv sync --frozen, и только потомCOPY . .. Тогда правка кода не пересобирает слой с зависимостями; - пользователь: создаётся непривилегированный пользователь и
USER app; - запуск:
CMDв exec-форме, например["gunicorn", "app.main:app", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:8000"], чтобы процесс получалSIGTERMи корректно завершался.
Рядом лежит .dockerignore с .git, .venv, .env и кешами. Секреты для сборки передаются через RUN --mount=type=secret, а не через ARG или ENV, которые остаются в образе. Миграции базы при сборке не выполняются, это отдельный шаг деплоя.
Если Dockerfile писали не вы, скажите об этом прямо и объясните, что в нём понимаете и что улучшили бы.
Где спотыкаются
Копируют весь проект до установки зависимостей. Каждое изменение в коде заново ставит все пакеты, и сборка идёт минутами вместо секунд.
Считают, что EXPOSE открывает порт. Это только документация, а публикует порт -p при запуске или настройка в compose.
Пишут CMD строкой в shell-форме. Тогда команду запускает /bin/sh -c, сигнал остановки может не дойти до приложения, и контейнер добивается SIGKILL по таймауту.