在bash中捕获来自“docker stop”的信号

时间:2013-12-16 02:47:01

标签: bash docker

我在docker容器中有一个入口点脚本,如下所示:

#!/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来捕获发送的信号。以交互方式运行时,ctrl+c将按预期触发它,但docker stop命令只等待10秒超时,并退出而不进入shut_down函数

如何将b docker stop发送的信号捕获到bash中进行清理?

3 个答案:

答案 0 :(得分:12)

老问题,但这会解决问题:

#!/bin/bash

echo starting up

exec /opt/myapp

有关详细信息,请查看此处:http://www.techbar.me/stopping-docker-containers-gracefully/

答案 1 :(得分:9)

看看this,可能会鼓舞人心: - )

<强>更新

@ nick-humrich这是我的lamer副本&amp;过去(归功于原作者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"

答案 2 :(得分:2)

自Docker 1.9起,您可以使用STOPSIGNAL中的Dockerfile指令:

STOPSIGNAL signal
     

STOPSIGNAL设置将发送到容器的系统调用信号   出口。该信号可以是与a匹配的有效无符号数   在内核的系统调用表中的位置,例如9,或信号   以SIGNAME格式命名,例如SIGKILL。

来源:https://docs.docker.com/engine/reference/builder/#stopsignal