ENTRYPOINT задаёт основную команду контейнера (часто неизменяемую). CMD задаёт аргументы по умолчанию к этой команде; их можно переопределить при docker run.
# Dockerfile:
ENTRYPOINT ["./app"]
CMD ["--port", "80"]
# Запуск:
docker run myimage
# Выполнится: ./app --port 80
docker run myimage --port 3000
# Выполнится: ./app --port 3000 (CMD полностью заменён)
Форма с JSON-массивом (["cmd", "arg1"]) предпочтительна: аргументы не проходят через shell и не интерпретируются.