Docker совет №33: Разница между форматами CMD
Aug 9, 2018 07:09 · 237 words · 2 minute read
Инструкция CMD
может быть определена в двух форматах, которые называются exec
и shell
. Оба выполняют практически идентичные вещи, но все же между ними есть существенно различие. Давайте разберемся!
Заданная в exec
-формате команда будет запущена “как есть”, вместе со всеми переданными ей аргументами. Пример команды в exec
-формате:
CMD ["gunicorn", "-c", "python:config.gunicorn", "hello.app:create_app()"]
Заданная в shell
-формате команда запускается через shell-оболочку контейнера и позволяет использовать функционал самого shell (например, конвейер или &&
). Пример такой команды:
CMD gunicorn -c "python:config.gunicorn" "hello.app:create_app()"
В теории, использование команд в shell
-формате выглядит предпочтительнее, но могут возникнуть проблемы с корректной обработкой сигналов в docker-контейнере. Немного поясню: если вы запускаете команду в exec
-формате, то выполнив внутри запущенного контейнера команду ps
вы увидите:
PID USER TIME COMMAND
1 root 0:00 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn
15 root 0:02 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn
188 root 0:00 ps
Если же вы запускаете команду в shell
-формате, то картина будет выглядеть иначе:
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c gunicorn -c python:config.gunicorn hello.app:create_app()
6 root 0:00 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn
16 root 0:00 {gunicorn} /usr/local/bin/python /usr/local/bin/gunicorn
29 root 0:00 ps
Разработчики docker советуют использовать именно exec
-формат для запуска команд, везде, где это возможно. Если же вам крайне необходимо выполнять какие-либо shell-сценарии при старте docker-контейнера, используйте для этих целей ENTRYPOINT
.
Что касается docker-compose, то есть возможность конвертации команд из shell
-формата в exec
-формат, и выглядеть это может так:
command: >
gunicorn -c "python:config.gunicorn" "hello.app:create_app()"
Или можно сразу задать команду в exec
-формате:
command: ["gunicorn", "-c", "python:config.gunicorn", "hello.app:create_app()"]