Не понимаю, что происходит, когда я пытаюсь выполнить две команды во время выполнения через директиву CMD в `Dockerfile. Я предположил, что это должно работать:
CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
Но это не работает. Контейнер еще не запущен. Поэтому я должен был сделать это так:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Я не понимаю Почему это? Почему первая строка не верна? Может кто-нибудь объяснить мне эти вещи "формат оболочки CMD против формата JSON и т. Д.". Простыми словами.
Сразу отмечу - то же самое было с command:
директивой docker-compose.yml
, как и ожидалось.
exec
форму, так как она является предпочтительной? Почему это предпочтительнее? Или я должен использовать более простуюshell
форму?CMD [ "sh", "-c", "echo", "$HOME"]
. Почему неCMD ["sh", "-c", "echo $HOME"]
или, если на то пошло,CMD ["sh -c echo $HOME"]
?Не мешай себе. Просто создайте bash-файл «start.sh»:
в вашем Dockerfile сделайте:
источник
Синтаксис json
CMD
(иRUN
иENTRYPOINT
) передает аргументы ядру напрямую как системный вызов exec. В системном вызове exec нет разделения команды на аргументы пробелами, экранирования кавычек, перенаправления ввода-вывода, подстановки переменных, передачи между командами, выполнения нескольких команд и т. Д. Системный вызов принимает только исполняемый файл и список аргументов для передачи этому исполняемому файлу, и он запускает его.Символы, такие как
$
расширение переменных,;
разделение команд,(пробел) для разделения аргументов
&&
и||
цепочка команд,>
для перенаправления вывода,|
передачи между командами и т. Д., Являются функциями оболочки и нуждаются в чем-то вроде/bin/sh
или/bin/bash
для их интерпретации и реализации.Если вы переключитесь на строковый синтаксис
CMD
, docker запустит вашу команду с оболочкой:В противном случае ваш второй синтаксис делает то же самое:
Обратите внимание, что я не рекомендую запускать несколько команд таким образом внутри контейнера, так как при первой ошибке команда не обрабатывается, особенно если она выполняется в фоновом режиме. Вы также оставляете оболочку, выполняющую роль pid 1 внутри контейнера, что нарушает обработку сигналов, что приводит к 10-секундной задержке и неосторожному уничтожению вашего контейнера докером. Обработка сигналов может быть уменьшена с помощью команды оболочки
exec
:Однако для обработки процессов, которые молча терпят неудачу в фоновом режиме, требуется переключиться на какой-нибудь многопроцессный менеджер, например supervisord, или, предпочтительно, разбить ваше приложение на несколько контейнеров и развернуть их с помощью чего-то вроде docker-compose.
источник
Я предполагаю, что первая команда завершается неудачно, потому что в форме DOCKER CMD выполняется только первый параметр, остальные вводятся в эту команду.
Вторая форма работает, потому что все команды разделены с ";" подаются в команду sh, которая их выполняет.
источник
Я не думаю, что вы должны ставить запятую после "начала"
вместо использования
пытаться
так как docker использует "sh -c", команда выше будет выполнена как показано ниже
источник
sh -c
в этом сценарии нет.