#!/usr/bin/env sh set -e DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock} TMP_DIR=/tmp/restart CURL_TIMEOUT=${CURL_TIMEOUT:-30} # SIGTERM-handler term_handler() { exit 143; # 128 + 15 -- SIGTERM } docker_curl() { curl --max-time "${CURL_TIMEOUT}" --no-buffer -s --unix-socket "${DOCKER_SOCK}" "$@" } trap 'kill ${!}; term_handler' SIGTERM if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then mkdir -p $TMP_DIR # https://docs.docker.com/engine/api/v1.25/ # Set container selector if [ "$AUTOHEAL_CONTAINER_LABEL" == "all" ]; then selector() { jq -r .[].Id } else selector() { jq -r '.[] | select(.Labels["'${AUTOHEAL_CONTAINER_LABEL:=autoheal}'"] == "true") | .Id' } fi echo "Monitoring containers for unhealthy status" while true; do sleep ${AUTOHEAL_INTERVAL:=5} CONTAINERS=$(docker_curl -XGET http://localhost/containers/json | selector) for CONTAINER in $CONTAINERS; do HEALTH=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .State.Health.Status) if [ "unhealthy" = "$HEALTH" ]; then DATE=$(date +%d-%m-%Y" "%H:%M:%S) CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name) echo "$DATE Container ${CONTAINER_NAME} (${CONTAINER:0:12}) found to be unhealthy" touch "$TMP_DIR/$CONTAINER" fi done for CONTAINER in `ls $TMP_DIR`; do DATE=$(date +%d-%m-%Y" "%H:%M:%S) CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name) if [ "null" = "$CONTAINER_NAME" ]; then echo "$DATE Delete container ${CONTAINER_NAME} (${CONTAINER:0:12}) from restart list because container name null implies container does not exist" rm "$TMP_DIR/$CONTAINER" else echo "$DATE Restarting container ${CONTAINER_NAME} (${CONTAINER:0:12})" docker_curl -f -XPOST http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" fi done done else exec "$@" fi