Обидві інструкції задають, що запускається в контейнері, але по-різному поводяться з аргументами docker run:
CMD- команда за замовчуванням. Якщо при запуску передати команду, вона повністю замінитьCMD.ENTRYPOINT- основний виконуваний файл. Аргументиdocker run(абоCMD) дописуються до нього як параметри.
ENTRYPOINT ["php", "artisan"]
CMD ["serve", "--host=0.0.0.0"]
docker run myapp # php artisan serve --host=0.0.0.0
docker run myapp queue:work # php artisan queue:work
docker run myapp migrate --force # php artisan migrate --force
Типовий сценарій - скрипт-обгортка як ENTRYPOINT, що готує середовище й передає керування команді:
#!/bin/sh
set -e
php artisan config:cache
exec "$@" # запустити CMD - і зробити його PID 1
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]
Exec-форма проти shell-форми:
CMD ["php-fpm"](JSON-масив, exec-форма) - процес запускається напряму й отримує сигнали.CMD php-fpm(shell-форма) - запускається через/bin/sh -c, і PID 1 - це оболонка. СигналSIGTERMприdocker stopотримує shell, а не застосунок, тож контейнер не завершується коректно і через 10 секунд його вбиваютьSIGKILL.
Тому в обох інструкціях - exec-форма, а в скрипті-обгортці - exec "$@".
ENTRYPOINT можна перевизначити при запуску: docker run --entrypoint sh myapp.