4

Let's consider following script:

#!/bin/bash
while true ; do: ; done

After running the script, the bash goes into loop, but can be interrupted (by pressing Ctrl-C or issuing kill -2 command) or terminated (by issuing kill command). All works perfectly well. But now let's consider another script:

#!/bin/bash
sleep 60

After running this script, bash process no longer reacts to SIGINT or SIGTERM signals. Of course it reacts to pressing Ctrl-C or to killing sleep process, but what I am interested in, is making bash process itself react to these signals. I need this because I am building Docker image with bash script as an entrypoint and Docker sends signals to PID 1 in the containter, which in my case will be bash process. I am struggling with making the container shut down gracefully. Bash process does not react to signals, so Docker kills it in order to shut down the containter.

Any help will be appreciated.

Krzysztof
  • 73
  • 1
  • 4
  • 2
    I suggest you to read https://hynek.me/articles/docker-signals/ which explains why signal processing can be an issue and how to make it work. tl;dr: you might need to use `exec` in combination with `--init`. – gesellix Jul 13 '18 at 07:27

2 Answers2

3

Consider this Docker file:

from centos:7

COPY entrypoint.sh /usr/bin/entrypoint.sh
RUN chmod 760 /usr/bin/entrypoint.sh

ENTRYPOINT ["/usr/bin/entrypoint.sh"]

with the corresponding entrypoint.sh script

#!/usr/bin/env bash

function finish {
    # stop holding process here
    echo "exciting gracefully . . ."
    kill -TERM "$child" 2>/dev/null
    exit 0
}

trap finish SIGHUP SIGINT SIGQUIT SIGTERM

# your process which holds the container, eg
sleep 60 &
child=$!
wait "$child

Build the image:

docker build --no-cache -t overflow .

Run the image:

docker run overflow:latest

if you CTRL+C within 60 seconds you'll see the output:

exciting gracefully . . .

Showing the signal has first killed your script and then the container.

A good resource on signals and containers can be found here

slowko
  • 829
  • 1
  • 7
  • 12
0

if your docker API 1.25+ you can run container

docker run --init -it

--init - Run an init inside the container that forwards signals and reaps processes description from docker guide https://docs.docker.com/engine/reference/commandline/run/

Artyom
  • 1
  • 1
  • 1
  • 1
    Can you expand on what `--init` does, by way of a question edit? I think your answer is right, but it may benefit from a bit more explanation. – halfer Apr 18 '20 at 20:55