Сигнал захвата от "остановки докера" в bash

У меня есть точка входа script в контейнере докера, которая выглядит примерно так:

#!/bin/bash

echo starting up

function shut_down() {
    echo shutting down

    pid=$(ps -e | grep myapp | awk '{print $1}')
    kill -SIGTERM $pid  
    exit
}

trap "shut_down" SIGKILL SIGTERM SIGHUP SIGINT EXIT

/opt/myapp

Я не могу понять, как захватить сигнал, отправленный при запуске docker stop в контейнере. При запуске в интерактивном режиме a ctrl+c будет запускать его, как ожидалось, но команда docker stop просто ждет 10-секундного тайм-аута и выходит, никогда не войдя в функцию shut_down

Как я могу захватить сигнал, отправленный docker stop в bash, чтобы выполнить некоторую очистку?

Ответы

Ответ 1

Посмотрите этот, может быть вдохновляющим: -)

UPDATE:

@nick-humrich здесь это моя копия ламера и прошлое (кредит принадлежит оригинальному автору https://github.com/lgierth)

#!/bin/bash

function ensure_started_container {
  exists=`docker ps -q | grep $1`
  if [ "$?" = "0" ] ; then
    echo "[docker-exec] skipping docker start, already started"
  else
    output=`docker start "$1"`
    echo "[docker start] $output"
  fi
  running=1
}

function setup_signals {
  cid="$1"; shift
  handler="$1"; shift
  for sig; do
    trap "$handler '$cid' '$sig'" "$sig"
  done
}

function handle_signal {
  echo "[docker-exec] received $2"
  case "$2" in
    SIGINT)
      output=`docker stop -t 5 "$1"`
      echo "[docker stop] $output"
      running=0
      ;;
    SIGTERM)
      output=`docker stop -t 5 "$1"`
      echo "[docker stop] $output"
      running=0
      ;;
    SIGHUP)
      output=`docker restart -t 5 "$1"`
      echo "[docker restart] $output"

      # restart logging
      docker attach "$1" &
      kill "$logger_pid" 2> /dev/null
      logger_pid="$!"
      ;;
  esac
}

running=0

setup_signals "$1" "handle_signal" SIGINT SIGTERM SIGHUP

ensure_started_container "$1"

docker attach "$1" &
logger_pid="$!"

while true; do
  if [ "$running" = "1" ]; then
    sleep 1
  else
    break
  fi
done

exit_code=`docker wait "$1"`
exit "$exit_code"

Ответ 3

Начиная с Docker 1.9, вы можете использовать инструкцию STOPSIGNAL в своем Dockerfile:

STOPSIGNAL signal

STOPSIGNAL устанавливает сигнал системного вызова, который будет отправлен в контейнер, чтобы Выход. Этот сигнал может быть допустимым числом без знака, которое соответствует положение в таблице syscall ядер, например 9, или сигнал имя в формате SIGNAME, например SIGKILL.

Источник: https://docs.docker.com/engine/reference/builder/#stopsignal