CMD
(및 RUN
and ENTRYPOINT
) 의 json 구문은 인수를 커널에 직접 exec syscall로 전달합니다. exec syscall에서 공백으로 따옴표, 이스케이프 제거, IO 대체, 변수 대체, 명령 사이의 파이프 연결, 여러 명령 실행 등을 통해 인수와 명령을 분리 할 수 없습니다. syscall은 실행 파일을 실행하고 해당 실행 파일에 전달할 인수 목록 만 가져 와서 실행합니다.
문자는 같은 $
변수를 확장하기 위해 ;
별도의 명령에
별도의 인수로 (공간) &&
및 ||
체인 명령에, >
출력 리디렉션, |
같은 쉘과해야 할 일의 모든 기능 명령 사이에 파이프 등이다 /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 초 지연시키고 부적절하게 죽일 수 있습니다. 쉘 exec
명령 을 사용하여 신호 처리를 완화 할 수 있습니다 .
CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
그러나 백그라운드에서 자동으로 실패한 프로세스를 처리하려면 감독자와 같은 일종의 다중 프로세스 관리자로 전환하거나 응용 프로그램을 여러 컨테이너로 분할하고 docker-compose와 같은 방식으로 배포해야합니다.
exec
선호하는 양식이므로이 양식을 계속 사용해야 합니까? 왜 선호됩니까? 아니면 더 간단한shell
형태를 사용해야 합니까?