대다수의 OS에서 첫번째 Process ID 즉, PID 1은 초기에 실행되는 init process가 할당 받는다. init은 고아프로세스를 입양하기 때문에 모든 프로세스의 직/간접적인 부모 프로세스가 된다.
컨테이너에서느 init 프로세스가 없기 때문에 가장 먼저 실행된 일반 애플리케이션이 PID 1을 할당 받게 된다. 이 경우 크게 두 가지가 문제가 된다.
첫째로 정상적인 시그널 처리를 하지 못할 수 있다. 일반 애플리케이션은 다른 프로세스를 관리할 목적으로 실행된 것이 아니기 때문에 적절한 시그널 핸들러를 가지고 있지 않을 가능성이 크기 때문이다.
둘째로 고아프로세스를 처리할 수 없어진다. 부모 프로세스가 먼저 종료되어 종료상태를 회수할 수 없게 된 프로세스를 고아프로세스라고 하는데 이 때 고아프로세스는 PID1을 새로운 부모 프로세스로 취급하게 되며 PID1이 고아프로세스의 종료상태를 회수하며 좀비 프로세스가 되는 것을 방지한다. 하지만 이러한 역할을 하지 못하는 일반 애플리케이션의 경우 이러한 문제를 막을 수 없다.
위의 문제를 해결하는 방법은 간단하다. init프로세스의 역할 을 수행하는 프로세스에게 PID 1을 할당해 주면 된다. 이러한 프로그램으로 dumb-init과 tini가 있다.
우선 Dockerfile의 ENTRYPOINT로 dumb-init을 실행하고 궁극적으로 컨테이너에서 실행하고자 하는 명령을 dumb-init의 인자로 전달해 실행하게 하면 된다.
# 최초로 dumb-init을 실행한다.
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
# dumb-inti의 인자로 CMD의 내용이 들어오게 된다.
CMD ["sh", "/scripts/run.sh"]