Короткий ответ
При ENTRYPOINT ["executable"] в exec-форме и CMD ["--default-flag"], docker run image без дополнительных аргументов выполнит executable --default-flag, а docker run image --other-flag заменит именно CMD, выполнив executable --other-flag, не трогая сам ENTRYPOINT.
Как это работает подробнее
Docker собирает финальную команду контейнера как конкатенацию массива ENTRYPOINT и массива аргументов — либо CMD из образа (если явных аргументов в docker run нет), либо аргументов, переданных после имени образа в docker run (если они есть, они целиком заменяют CMD, но не ENTRYPOINT). Это работает предсказуемо только при exec-форме (["..."]) обоих инструкций — shell-форма ломает эту механику, так как оборачивает команду в /bin/sh -c.
Пример кода
Dockerfile
ENTRYPOINT ["python", "cli.py"]
CMD ["--mode=default"]Что использовать на практике
- Практика. такой паттерн используют для образов-утилит, где
ENTRYPOINTфиксирует саму программу, аCMDзадаёт "разумные значения по умолчанию" флагов, которые пользователь образа может переопределить без необходимости переопределять весьENTRYPOINTчерез--entrypoint.
Подводные камни
- Риск. задают
ENTRYPOINTв shell-форме (ENTRYPOINT executable) и затем недоумевают, почемуCMDс аргументами не подхватывается ожидаемым образом — в shell-форме Docker игнорируетCMDкак аргументы в привычном смысле, так как вся команда уже единая строка, выполняемая через shell.