В чем разница между ENTRYPOINT и CMD в Docker
Что проверяют
Понимаете ли вы, как формируется итоговая команда контейнера. Вопрос короткий, но за ним обычно идёт разбор реального Dockerfile.
Как отвечать
Обе инструкции задают, что запускается при старте контейнера, но роли у них разные. ENTRYPOINT это сама программа, CMD это аргументы по умолчанию к ней.
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]Запуск docker run image даст python app.py --port 8080. Запуск docker run image --port 9090 заменит только CMD, то есть аргументы. Чтобы заменить саму программу, нужен явный --entrypoint.
Если ENTRYPOINT не задан, CMD становится командой целиком, и её можно переопределить прямо в docker run.
Форма записи важнее, чем кажется. Exec-форма (массив) запускает процесс напрямую, он получает PID 1 и сигналы, поэтому docker stop корректно его останавливает. Shell-форма (строка) оборачивает команду в /bin/sh -c, PID 1 достаётся оболочке, SIGTERM до приложения не доходит, и контейнер убивается по таймауту через SIGKILL.
Типичный рабочий приём: ENTRYPOINT на скрипт инициализации, который готовит окружение и заканчивается exec "$@", а CMD на команду приложения по умолчанию.
Где спотыкаются
Считают их взаимозаменяемыми и не могут объяснить, что произойдёт при docker run image bash.
Пишут shell-форму и не понимают, почему контейнер останавливается ровно десять секунд.
Забывают exec в entrypoint-скрипте, из-за чего приложение остаётся дочерним процессом и не получает сигналы.
Не знают, что в docker-compose command переопределяет CMD, а entrypoint соответственно ENTRYPOINT.