If you try to stop the container with docker stop
while Rails (Puma) is running on Docker, you will get Exit 1 (SIGHUP).
If you are using ECS or Kubernetes, the container may not terminate properly and may cause unexpected problems.
% docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
xxx rails "bundle exec rails s…" 44 seconds ago Exited (1) 3 seconds ago api
xxx
The cause is the so-called "PID 1 problem [^ 1]". PID 1 is called the init process, which is a special process called by the kernel at system startup. The init process handles signals, spawns child processes, deletes zombie processes, and more. This time, when Rails ([^ 2]) was started, PID 1 was used, and there was a problem that the signal could not be handled correctly.
#The result of executing the top command on the container
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 2.2m 1.5m 0.0 0.1 0:00.02 S /bin/bash /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.
If you look at the process, you can see that Rails is running with PID 1.
As a child process of PID 1 by using a program such as tini or [dumb-init](https://github.com/ Yelp/dumb-init) It will be possible to start the application.
If docker-compose 3.7 or later is available, you can work around the problem by adding the init
parameter to docker-compose.yml
([^ 3]).
#Rails starts as a child process of the init process
PID USER PR NI VIRT RES %CPU %MEM TIME+ S COMMAND
1 root 20 0 1.0m 0.0m 0.0 0.0 0:00.03 S /sbin/docker-init -- /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.0
6 root 20 0 2.2m 1.5m 0.0 0.1 0:00.00 S `- /bin/bash /bin/docker-entrypoint.sh bundle exec rails s -b 0.0.0.0
Looking at the process after running docker-compose down
, the container is stopped at 143 (SIGTERM).
% docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------
api /bin/docker-entrypoint.sh ... Exit 143
Add initProcessEnabled: true
([^ 4]) to the task definition. initProcessEnabled
is equivalent to --init
in docker run
.
You can also use a lightweight init such as tini, but starting with Kubernetes 1.17 it seems that you can work around the problem by using Share Process Namespace ([^ 5]).
Recommended Posts