Синтаксис json для CMD
(и RUN
и ENTRYPOINT
) передайте аргументы ядру непосредственно как системный вызов exec. В системном вызове exec нет разделения команды от аргументов пробелами, экранирования кавычек, перенаправления ввода-вывода, замены переменных, передачи между командами, выполнения нескольких команд и т.д. Системный вызов принимает только исполняемый файл для запуска и список аргументов для передачи этому исполняемому файлу и запускает его.
Персонажи, подобные $
для расширения переменных, ;
для разделения команд,
(пробел) для разделения аргументов, &&
и ||
чтобы связать команды в цепочку, >
для перенаправления вывода, |
для передачи данных между командами и т.д. Все это функции оболочки и нужно что-то вроде /bin/sh
или /bin/bash
интерпретировать и внедрять их.
Если вы переключитесь на строковый синтаксис CMD
, docker выполнит вашу команду с помощью оболочки:
CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
В противном случае ваш второй синтаксис делает то же самое:
CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
Обратите внимание, что я не рекомендую запускать несколько команд таким образом внутри контейнера, поскольку при сбое вашей первой команды обработка ошибок не выполняется, особенно если она выполняется в фоновом режиме. Вы также оставляете оболочку, работающую как pid 1 внутри контейнера, что приведет к нарушению обработки сигналов, что приведет к 10-секундной задержке и неблагодарному уничтожению вашего контейнера docker. Обработка сигналов может быть уменьшена с помощью оболочки exec
команда:
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
Однако для обработки процессов, которые беззвучно выходят из строя в фоновом режиме, требуется переключиться на какой-нибудь менеджер нескольких процессов, такой как supervisord, или, предпочтительно, разбить ваше приложение на несколько контейнеров и развернуть их с помощью чего-то вроде docker-compose.