mirror of
https://github.com/willfarrell/docker-autoheal.git
synced 2024-12-06 19:16:20 +01:00
86 lines
2.6 KiB
Bash
Executable File
86 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env sh
|
|
|
|
set -e
|
|
set -o pipefail
|
|
|
|
DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock}
|
|
UNIX_SOCK=""
|
|
CURL_TIMEOUT=${CURL_TIMEOUT:-30}
|
|
|
|
# only use unix domain socket if no TCP endpoint is defined
|
|
case "${DOCKER_SOCK}" in
|
|
"tcp://"*) HTTP_ENDPOINT="$(echo ${DOCKER_SOCK} | sed 's#tcp://#https://#')"
|
|
CA="--cacert /certs/ca.pem"
|
|
CLIENT_KEY="--key /certs/client-key.pem"
|
|
CLIENT_CERT="--cert /certs/client-cert.pem"
|
|
;;
|
|
*) HTTP_ENDPOINT="http://localhost"
|
|
UNIX_SOCK="--unix-socket ${DOCKER_SOCK}"
|
|
;;
|
|
esac
|
|
|
|
# SIGTERM-handler
|
|
term_handler() {
|
|
exit 143; # 128 + 15 -- SIGTERM
|
|
}
|
|
|
|
docker_curl() {
|
|
curl --max-time "${CURL_TIMEOUT}" --no-buffer -s \
|
|
${CA} ${CLIENT_KEY} ${CLIENT_CERT} \
|
|
${UNIX_SOCK} \
|
|
"$@" || return 1
|
|
return 0
|
|
}
|
|
|
|
trap 'kill ${!}; term_handler' SIGTERM
|
|
|
|
if [ "$1" = 'healthcheck' ]; then
|
|
docker_curl --fail "${HTTP_ENDPOINT}/_ping"
|
|
exit $?
|
|
fi
|
|
|
|
if [ "$1" = 'autoheal' ]; then
|
|
if [ ! -x $UNIX_SOCK ]; then
|
|
if [ ! -e "${DOCKER_SOCK}" ]; then
|
|
echo "${DOCKER_SOCK} not found"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# https://docs.docker.com/engine/api/v1.25/
|
|
|
|
# Set container selector
|
|
if [ "$AUTOHEAL_CONTAINER_LABEL" == "all" ]; then
|
|
labelFilter=""
|
|
else
|
|
labelFilter=",\"label\":\[\"${AUTOHEAL_CONTAINER_LABEL:=autoheal}=true\"\]"
|
|
fi
|
|
|
|
AUTOHEAL_START_PERIOD=${AUTOHEAL_START_PERIOD:=0}
|
|
echo "Monitoring containers for unhealthy status in ${AUTOHEAL_START_PERIOD} second(s)"
|
|
sleep ${AUTOHEAL_START_PERIOD}
|
|
|
|
while true; do
|
|
sleep ${AUTOHEAL_INTERVAL:=5}
|
|
|
|
apiUrl="${HTTP_ENDPOINT}/containers/json?filters=\{\"health\":\[\"unhealthy\"\]${labelFilter}\}"
|
|
stopTimeout=".Labels[\"autoheal.stop.timeout\"] // ${AUTOHEAL_DEFAULT_STOP_TIMEOUT:-10}"
|
|
docker_curl "$apiUrl" | \
|
|
jq -r "foreach .[] as \$CONTAINER([];[]; \$CONTAINER | .Id, .Names[0], $stopTimeout )" | \
|
|
while read -r CONTAINER_ID && read -r CONTAINER_NAME && read -r TIMEOUT; do
|
|
CONTAINER_SHORT_ID=${CONTAINER_ID:0:12}
|
|
DATE=$(date +%d-%m-%Y" "%H:%M:%S)
|
|
if [ "null" = "$CONTAINER_NAME" ]; then
|
|
echo "$DATE Container name of ($CONTAINER_SHORT_ID) is null, which implies container does not exist - don't restart"
|
|
else
|
|
echo "$DATE Container ${CONTAINER_NAME} ($CONTAINER_SHORT_ID) found to be unhealthy - Restarting container now with ${TIMEOUT}s timeout"
|
|
docker_curl -f -XPOST "${HTTP_ENDPOINT}/containers/${CONTAINER_ID}/restart?t=${TIMEOUT}" \
|
|
|| echo "$DATE Restarting container $CONTAINER_SHORT_ID failed"
|
|
fi
|
|
done
|
|
done
|
|
|
|
else
|
|
exec "$@"
|
|
fi
|