Короткий ответ
CMD задаёт аргументы/команду по умолчанию, которые легко целиком переопределить аргументами docker run; ENTRYPOINT задаёт основную исполняемую команду, которая по умолчанию не заменяется — аргументы docker run добавляются к ней или заменяют CMD.
Как это работает подробнее
если задан только CMD, то любые аргументы после имени образа в docker run полностью заменяют CMD. Если задан ENTRYPOINT в exec-форме (["executable"]), а CMD задаёт аргументы по умолчанию, то аргументы из docker run заменяют именно CMD, а не ENTRYPOINT — то есть исполняемый файл остаётся фиксированным, меняются только его флаги.
Пример кода
Dockerfile
ENTRYPOINT ["nginx"]
CMD ["-g", "daemon off;"]Что использовать на практике
- Практика.
ENTRYPOINTудобен, когда образ должен вести себя как "обёртка" над конкретной программой (например, CLI-утилита), аCMDиспользуют для образов общего назначения, где запуск произвольной команды — ожидаемый сценарий (например, базовые образыubuntu/alpine).
Подводные камни
- Риск. задают
ENTRYPOINTв shell-форме (ENTRYPOINT command) вместо exec-формы — тогда сигналы (например,SIGTERMприdocker stop) доставляются обёртывающему/bin/sh -c, а не самому процессу, и контейнер может не завершаться штатно по таймаутуdocker stop, уходя вSIGKILL.