From cc4ff72e03b0fc8130754e0c59475a8646927553 Mon Sep 17 00:00:00 2001 From: Hasnat Date: Thu, 19 Apr 2018 19:38:50 +0100 Subject: [PATCH 01/20] Adds container name in log --- docker-entrypoint | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index 497a823..d786fd0 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -37,13 +37,15 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then HEALTH=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .State.Health.Status) if [ "unhealthy" = "$HEALTH" ]; then DATE=$(date +%d-%m-%Y" "%H:%M:%S) - echo "$DATE Container ${CONTAINER:0:12} found to be unhealthy" + CONTAINER_NAME=$(docker inspect --format="{{.Name}}" $CONTAINER) + 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) - echo "$DATE Restarting container ${CONTAINER:0:12}" + CONTAINER_NAME=$(docker inspect --format="{{.Name}}" $CONTAINER) + echo "$DATE Restarting container $CONTAINER_NAME (${CONTAINER:0:12})" curl -f --no-buffer -s -XPOST --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" done done From 3e9a92ddc6c8eb16e0c637684c208d87026bc9ea Mon Sep 17 00:00:00 2001 From: will Farrell Date: Fri, 20 Apr 2018 10:12:30 -0600 Subject: [PATCH 02/20] Revert "Adds container name in log" --- docker-entrypoint | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index d786fd0..497a823 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -37,15 +37,13 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then HEALTH=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} 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 inspect --format="{{.Name}}" $CONTAINER) - echo "$DATE Container $CONTAINER_NAME (${CONTAINER:0:12}) found to be unhealthy" + echo "$DATE Container ${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 inspect --format="{{.Name}}" $CONTAINER) - echo "$DATE Restarting container $CONTAINER_NAME (${CONTAINER:0:12})" + echo "$DATE Restarting container ${CONTAINER:0:12}" curl -f --no-buffer -s -XPOST --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" done done From 20791b1cab3492de9edd62fa6b682d26ab7376a6 Mon Sep 17 00:00:00 2001 From: Hasnat Date: Fri, 20 Apr 2018 17:46:32 +0100 Subject: [PATCH 03/20] show container name in log (not us docker binary this time) related to #9 --- docker-entrypoint | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index 497a823..3516d02 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -37,13 +37,15 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then HEALTH=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .State.Health.Status) if [ "unhealthy" = "$HEALTH" ]; then DATE=$(date +%d-%m-%Y" "%H:%M:%S) - echo "$DATE Container ${CONTAINER:0:12} found to be unhealthy" + CONTAINER_NAME=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} 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) - echo "$DATE Restarting container ${CONTAINER:0:12}" + CONTAINER_NAME=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .Name) + echo "$DATE Restarting container ${CONTAINER_NAME} (${CONTAINER:0:12})" curl -f --no-buffer -s -XPOST --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" done done From 31e8dfccd15d2d2ffea01b4e3451c8fee882d455 Mon Sep 17 00:00:00 2001 From: Hans Schulz Date: Thu, 17 May 2018 16:28:18 +0200 Subject: [PATCH 04/20] add curl timeout --- docker-entrypoint | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index 3516d02..aee86f8 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -3,12 +3,17 @@ 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 @@ -32,21 +37,21 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then while true; do sleep ${AUTOHEAL_INTERVAL:=5} - CONTAINERS=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/json | selector) + CONTAINERS=$(docker_curl -XGET http://localhost/containers/json | selector) for CONTAINER in $CONTAINERS; do - HEALTH=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .State.Health.Status) + 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=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .Name) + 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=$(curl --no-buffer -s -XGET --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/json | jq -r .Name) + CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name) echo "$DATE Restarting container ${CONTAINER_NAME} (${CONTAINER:0:12})" - curl -f --no-buffer -s -XPOST --unix-socket ${DOCKER_SOCK} http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" + docker_curl -XPOST http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" done done From 6a65ad6e98f562c36ba1d87e5c527f7a7d474d54 Mon Sep 17 00:00:00 2001 From: Hans Schulz Date: Fri, 18 May 2018 10:14:56 +0200 Subject: [PATCH 05/20] Update docker-entrypoint --- docker-entrypoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-entrypoint b/docker-entrypoint index aee86f8..15a917f 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -51,7 +51,7 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then DATE=$(date +%d-%m-%Y" "%H:%M:%S) CONTAINER_NAME=$(docker_curl -XGET http://localhost/containers/${CONTAINER}/json | jq -r .Name) echo "$DATE Restarting container ${CONTAINER_NAME} (${CONTAINER:0:12})" - docker_curl -XPOST http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" + docker_curl -f -XPOST http://localhost/containers/${CONTAINER}/restart && rm "$TMP_DIR/$CONTAINER" || echo "$DATE Restarting container ${CONTAINER:0:12} failed" done done From 5d80dcb64343103ef3262483a2a19ee930d89875 Mon Sep 17 00:00:00 2001 From: jon Date: Fri, 15 Jun 2018 12:05:21 +0800 Subject: [PATCH 06/20] Delete container from restart list when container name is null --- docker-entrypoint | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index 15a917f..b9eb35e 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -50,8 +50,13 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then 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) - 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" + if [ "null" = "$CONTAINER_NAME" ]; then + echo "$DATE Delete container ${CONTAINER_NAME} (${CONTAINER:0:12}) from restart list because container name null implies container is not exists" + 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 From caf3817b30befd98bf8425e681626a0ea8b62189 Mon Sep 17 00:00:00 2001 From: shidenggui Date: Fri, 15 Jun 2018 16:38:12 +0800 Subject: [PATCH 07/20] Fix grammer error --- docker-entrypoint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-entrypoint b/docker-entrypoint index b9eb35e..b0921af 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -51,7 +51,7 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then 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 is not exists" + 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})" From 8697de51a3e032eb63ccc2d778f1360630d2d330 Mon Sep 17 00:00:00 2001 From: eddyhub Date: Sun, 19 Aug 2018 08:43:30 +0200 Subject: [PATCH 08/20] Added multiarch build, because I need this image for mi Raspberry PI --- .travis.yml | 24 ++++++++++++++++++++++++ Dockerfile | 5 +++-- build.sh | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 .travis.yml create mode 100644 build.sh diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cb0aa02 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +sudo: required +services: + - docker +language: bash + +env: + global: + - TRAVIS_SECURE_ENV_VARS=true + +before_install: + - sudo apt-get remove docker docker-engine docker.io + - curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + - sudo apt-get update + - sudo apt-get -y install docker-ce + - echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json + - sudo service docker restart + - mkdir ~/.docker + - echo '{"experimental":"enabled"}' | tee ~/.docker/config.json + - ls -al ~/.docker/config.json + - cat ~/.docker/config.json + +script: + - bash build.sh $TRAVIS_REPO_SLUG $DOCKER_USERNAME $DOCKER_PASSWORD diff --git a/Dockerfile b/Dockerfile index 209ee3c..7fe3d40 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM alpine:3.5 +ARG arch=amd64 +FROM multiarch/alpine:${arch}-latest-stable RUN apk add --no-cache curl jq @@ -7,4 +8,4 @@ ENTRYPOINT ["/docker-entrypoint"] HEALTHCHECK --interval=5s CMD exit 0 -CMD ["autoheal"] \ No newline at end of file +CMD ["autoheal"] diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..0d2af1f --- /dev/null +++ b/build.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +REPO=${1} +DOCKER_USERNAME=${2} +DOCKER_PASSWORD=${3} +declare -A ARCH_MAP +ARCH_MAP[amd64]=amd64 +ARCH_MAP[armhf]=arm +ARCH_MAP[arm64]=arm64 + +docker run --rm --privileged multiarch/qemu-user-static:register --reset +echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin + +echo "Building docker images" +for i in "${!ARCH_MAP[@]}"; do + echo "################################################################################" + echo "Building and pushing: ${REPO}-${ARCH_MAP[$i]}:latest " + echo "################################################################################" + docker build --build-arg arch=${i} -t ${REPO}-${ARCH_MAP[$i]}:latest .; + docker push ${REPO}-${ARCH_MAP[$i]}:latest; +done; + +MANIFESTS="" +for arch in "${ARCH_MAP[@]}"; do MANIFESTS="${MANIFESTS} ${REPO}-${arch}:latest"; done + +echo "################################################################################" +echo "Building and pushing: ${REPO}-${ARCH_MAP[$i]}:latest " +echo "################################################################################" +docker manifest create ${REPO}:latest ${MANIFESTS}; + +for arch in "${ARCH_MAP[@]}"; do + docker manifest annotate --os linux --arch ${arch} ${REPO}:latest ${REPO}-${arch}:latest; +done; + +docker manifest push ${REPO}:latest From 825dbbc84db0879388095eccfcb325465f968691 Mon Sep 17 00:00:00 2001 From: eddyhub Date: Sun, 19 Aug 2018 11:30:28 +0200 Subject: [PATCH 09/20] Added gitlab-ci.yml to be able to build the containers in gitlab. --- .gitlab-ci.yml | 15 +++++++++++++++ .travis.yml | 2 +- build.sh | 3 ++- 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..283b24d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,15 @@ +image: docker:latest + +services: + - docker:dind +stages: + - build_and_deploy +job: + stage: build_and_deploy + script: + - mkdir ~/.docker + - echo '{"experimental":"enabled"}' | tee ~/.docker/config.json + - apk add --no-cache bash + - ls -al ~/.docker/config.json + - cat ~/.docker/config.json + - bash build.sh $DOCKER_ENV_CI_PROJECT_PATH $CI_REGISTRY_USER $CI_REGISTRY_PASSWORD $CI_REGISTRY diff --git a/.travis.yml b/.travis.yml index cb0aa02..b6d5c6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,4 @@ before_install: - cat ~/.docker/config.json script: - - bash build.sh $TRAVIS_REPO_SLUG $DOCKER_USERNAME $DOCKER_PASSWORD + - bash build.sh $TRAVIS_REPO_SLUG $DOCKER_USERNAME $DOCKER_PASSWORD index.docker.io diff --git a/build.sh b/build.sh index 0d2af1f..b2b59df 100644 --- a/build.sh +++ b/build.sh @@ -1,8 +1,9 @@ -#!/bin/bash +#!/bin/sh REPO=${1} DOCKER_USERNAME=${2} DOCKER_PASSWORD=${3} +DOCKER_REGESTRY=${4} declare -A ARCH_MAP ARCH_MAP[amd64]=amd64 ARCH_MAP[armhf]=arm From 5e816f9ff5c2a097851728eca796d7a34bbafd83 Mon Sep 17 00:00:00 2001 From: eddyhub Date: Tue, 21 Aug 2018 23:32:11 +0200 Subject: [PATCH 10/20] Use a specific version of alpine to get a reproducible build and set default arch to x86_64. --- Dockerfile | 4 ++-- build.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7fe3d40..ae825de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -ARG arch=amd64 -FROM multiarch/alpine:${arch}-latest-stable +ARG arch=x86_64 +FROM multiarch/alpine:${arch}-v3.8 RUN apk add --no-cache curl jq diff --git a/build.sh b/build.sh index b2b59df..ea15696 100644 --- a/build.sh +++ b/build.sh @@ -5,7 +5,7 @@ DOCKER_USERNAME=${2} DOCKER_PASSWORD=${3} DOCKER_REGESTRY=${4} declare -A ARCH_MAP -ARCH_MAP[amd64]=amd64 +ARCH_MAP[x86_64]=x86_64 ARCH_MAP[armhf]=arm ARCH_MAP[arm64]=arm64 From 05b09f84eeef229d7dad30de0f4916b1f4dddd27 Mon Sep 17 00:00:00 2001 From: Magi1053 Date: Wed, 22 Aug 2018 11:00:39 -0500 Subject: [PATCH 11/20] Add example for how to create the container --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 7041491..930187a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,14 @@ This container is a stand-in till there is native support for `--exit-on-unhealt [![](https://images.microbadger.com/badges/version/willfarrell/autoheal.svg)](http://microbadger.com/images/willfarrell/autoheal "Get your own version badge on microbadger.com") [![](https://images.microbadger.com/badges/image/willfarrell/autoheal.svg)](http://microbadger.com/images/willfarrell/autoheal "Get your own image badge on microbadger.com") ## How to use +```bash +docker run -d \ + --name autoheal \ + --restart=always \ + -e AUTOHEAL_CONTAINER_LABEL=all \ + -v /var/run/docker.sock:/var/run/docker.sock \ + willfarrell/autoheal +``` a) Apply the label `autoheal=true` to your container to have it watched. b) Set ENV `AUTOHEAL_CONTAINER_LABEL=all` to watch all running containers. From 11daf622171938ad7b0ec11ecf46de44922511fa Mon Sep 17 00:00:00 2001 From: will Farrell Date: Tue, 2 Oct 2018 09:00:53 -0600 Subject: [PATCH 12/20] feat: add licence --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0043319 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 will Farrell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 8830a6b4540c7d3620c2e64b31012d52b9a2ee7f Mon Sep 17 00:00:00 2001 From: Harald Heigl Date: Mon, 29 Oct 2018 09:08:32 +0100 Subject: [PATCH 13/20] Changed system to only one docker-api request, api-request now only gets unhealthy containers --- docker-entrypoint | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/docker-entrypoint b/docker-entrypoint index b0921af..18b8f1a 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -18,44 +18,29 @@ 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 - } + labelFilter="" else - selector() { - jq -r '.[] | select(.Labels["'${AUTOHEAL_CONTAINER_LABEL:=autoheal}'"] == "true") | .Id' - } + labelFilter=",\"label\":\[\"${AUTOHEAL_CONTAINER_LABEL:=autoheal}=true\"\]" 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 + + apiUrl="http://localhost/containers/json?filters=\{\"health\":\[\"unhealthy\"\]${labelFilter}\}" + docker_curl "$apiUrl" | jq -r 'foreach .[] as $CONTAINER([];[]; $CONTAINER | .Id, .Names[0])' | \ + while read -r CONTAINER_ID && read -r CONTAINER_NAME; do + CONTAINER_SHORT_ID=${CONTAINER_ID:0:12} 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" + echo "$DATE Container name of ($CONTAINER_SHORT_ID) is null, which implies container does not exist - don't restart" 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" + echo "$DATE Container ${CONTAINER_NAME} ($CONTAINER_SHORT_ID) found to be unhealthy - Restarting container now" + docker_curl -f -XPOST http://localhost/containers/${CONTAINER_ID}/restart || echo "$DATE Restarting container $CONTAINER_SHORT_ID failed" fi done done From b1fe537daacfbf086d377c29c1923bc0430eb57f Mon Sep 17 00:00:00 2001 From: Harald Heigl Date: Mon, 29 Oct 2018 09:42:26 +0100 Subject: [PATCH 14/20] Removed tmp_dir (not needed anymore) --- docker-entrypoint | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-entrypoint b/docker-entrypoint index 18b8f1a..788ef3e 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -2,7 +2,6 @@ set -e DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock} -TMP_DIR=/tmp/restart CURL_TIMEOUT=${CURL_TIMEOUT:-30} # SIGTERM-handler From 17ec6c4344360dcf1f3c2023ae30df7a52702625 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Fri, 30 Nov 2018 19:00:44 -0500 Subject: [PATCH 15/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 930187a..e2ada63 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Note: You must apply `HEALTHCHECK` to your docker images first. See https://docs ## ENV Defaults ``` AUTOHEAL_CONTAINER_LABEL=autoheal -AUTOHEAL_INTERVAL=5 +AUTOHEAL_INTERVAL=5 # check every 5 seconds DOCKER_SOCK=/var/run/docker.sock ``` From b0d602ded1a8155454ce134ec36f86f7dbc805ff Mon Sep 17 00:00:00 2001 From: Johann BERNEZ Date: Sat, 8 Dec 2018 11:03:39 +0100 Subject: [PATCH 16/20] Added AUTOHEAL_START_PERIOD to delay the first health check --- README.md | 3 ++- docker-entrypoint | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2ada63..6aba5dd 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,13 @@ b) Set ENV `AUTOHEAL_CONTAINER_LABEL=all` to watch all running containers. c) Set ENV `AUTOHEAL_CONTAINER_LABEL` to existing label name that has the value `true`. -Note: You must apply `HEALTHCHECK` to your docker images first. See https://docs.docker.com/engine/reference/builder/#/healthcheck for details. +Note: You must apply `HEALTHCHECK` to your docker images first. See https://docs.docker.com/engine/reference/builder/#healthcheck for details. ## ENV Defaults ``` AUTOHEAL_CONTAINER_LABEL=autoheal AUTOHEAL_INTERVAL=5 # check every 5 seconds +AUTOHEAL_START_PERIOD=0 # wait 0 second before first health check DOCKER_SOCK=/var/run/docker.sock ``` diff --git a/docker-entrypoint b/docker-entrypoint index b0921af..bb0b134 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -33,7 +33,9 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then } fi - echo "Monitoring containers for unhealthy status" + echo "Monitoring containers for unhealthy status in ${AUTOHEAL_START_PERIOD} second(s)" + sleep ${AUTOHEAL_START_PERIOD:=0} + while true; do sleep ${AUTOHEAL_INTERVAL:=5} From 2d895e859a51a8b7d6e0214f746d38745829aeb5 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Mon, 21 Jan 2019 11:58:19 +0100 Subject: [PATCH 17/20] Update docker-entrypoint When using the default start period, autoheal always prints `Monitoring containers for unhealthy status in second(s)` --- docker-entrypoint | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-entrypoint b/docker-entrypoint index 91498d0..b310fef 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -26,8 +26,9 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then 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:=0} + sleep ${AUTOHEAL_START_PERIOD} while true; do sleep ${AUTOHEAL_INTERVAL:=5} From d1a2e17253afae04c6e21ff2bc639ec4020d652c Mon Sep 17 00:00:00 2001 From: Rishi Date: Wed, 23 Jan 2019 22:46:05 +0530 Subject: [PATCH 18/20] Exit if right most command fails in pipe --- docker-entrypoint | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-entrypoint b/docker-entrypoint index 91498d0..9f587c9 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -1,5 +1,7 @@ #!/usr/bin/env sh + set -e +set -o pipefail DOCKER_SOCK=${DOCKER_SOCK:-/var/run/docker.sock} CURL_TIMEOUT=${CURL_TIMEOUT:-30} From c1e3ad07117b4a1d736cfaa49e67f1f541966c0e Mon Sep 17 00:00:00 2001 From: Johnny Marnell Date: Mon, 25 Feb 2019 18:52:58 -0500 Subject: [PATCH 19/20] Add global and per container stop timeouts ; minor doc fixes --- README.md | 13 ++++++++++--- docker-entrypoint | 13 ++++++++----- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6aba5dd..ffaab78 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # docker-autoheal Monitor and restart unhealthy docker containers. -This functionality was propose to be included with the addition of `HEALTHCHECK`, however didn't make the cut. +This functionality was proposed to be included with the addition of `HEALTHCHECK`, however didn't make the cut. This container is a stand-in till there is native support for `--exit-on-unhealthy` https://github.com/docker/docker/pull/22719. ## Supported tags and Dockerfile links @@ -30,8 +30,15 @@ Note: You must apply `HEALTHCHECK` to your docker images first. See https://docs ``` AUTOHEAL_CONTAINER_LABEL=autoheal AUTOHEAL_INTERVAL=5 # check every 5 seconds -AUTOHEAL_START_PERIOD=0 # wait 0 second before first health check -DOCKER_SOCK=/var/run/docker.sock +AUTOHEAL_START_PERIOD=0 # wait 0 seconds before first health check +AUTOHEAL_DEFAULT_STOP_TIMEOUT=10 # Docker waits max 10 seconds (the Docker default) for a container to stop before killing during restarts (container overridable via label, see below) +DOCKER_SOCK=/var/run/docker.sock # Unix socket for curl requests to Docker API +CURL_TIMEOUT=30 # --max-time seconds for curl requests to Docker API +``` + +### Optional Container Labels +``` +autoheal.stop.timeout=20 # Per containers override for stop timeout seconds during restart ``` ## Testing diff --git a/docker-entrypoint b/docker-entrypoint index 91498d0..2d5165a 100755 --- a/docker-entrypoint +++ b/docker-entrypoint @@ -26,22 +26,25 @@ if [ "$1" = 'autoheal' ] && [ -e ${DOCKER_SOCK} ]; then labelFilter=",\"label\":\[\"${AUTOHEAL_CONTAINER_LABEL:=autoheal}=true\"\]" fi - echo "Monitoring containers for unhealthy status in ${AUTOHEAL_START_PERIOD} second(s)" + echo "Monitoring containers for unhealthy status in ${AUTOHEAL_START_PERIOD:=0} second(s)" sleep ${AUTOHEAL_START_PERIOD:=0} while true; do sleep ${AUTOHEAL_INTERVAL:=5} apiUrl="http://localhost/containers/json?filters=\{\"health\":\[\"unhealthy\"\]${labelFilter}\}" - docker_curl "$apiUrl" | jq -r 'foreach .[] as $CONTAINER([];[]; $CONTAINER | .Id, .Names[0])' | \ - while read -r CONTAINER_ID && read -r CONTAINER_NAME; do + 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" - docker_curl -f -XPOST http://localhost/containers/${CONTAINER_ID}/restart || echo "$DATE Restarting container $CONTAINER_SHORT_ID failed" + echo "$DATE Container ${CONTAINER_NAME} ($CONTAINER_SHORT_ID) found to be unhealthy - Restarting container now with ${TIMEOUT}s timeout" + docker_curl -f -XPOST "http://localhost/containers/${CONTAINER_ID}/restart?t=${TIMEOUT}" \ + || echo "$DATE Restarting container $CONTAINER_SHORT_ID failed" fi done done From 62f7279522f910311c99abf233cb2bd132f0fd52 Mon Sep 17 00:00:00 2001 From: will Farrell Date: Tue, 26 Feb 2019 01:25:43 -0700 Subject: [PATCH 20/20] fix: add in gitignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6560709 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + + +# IDE +.idea +*.iml