diff --git a/Dockers/docker-watcher/Dockerfile b/Dockers/docker-watcher/Dockerfile new file mode 100644 index 0000000..2132da6 --- /dev/null +++ b/Dockers/docker-watcher/Dockerfile @@ -0,0 +1,6 @@ +FROM docker:cli + +COPY watch.sh /watch.sh +RUN chmod +x /watch.sh + +ENTRYPOINT ["/watch.sh"] diff --git a/Dockers/docker-watcher/watch.sh b/Dockers/docker-watcher/watch.sh new file mode 100644 index 0000000..3a06b34 --- /dev/null +++ b/Dockers/docker-watcher/watch.sh @@ -0,0 +1,56 @@ +#!/bin/sh +set -eu + +WATCH_CONTAINER="${WATCH_CONTAINER:?set WATCH_CONTAINER to the container name or id to watch}" +RESTART_CONTAINERS="${RESTART_CONTAINERS:?set RESTART_CONTAINERS to a comma-separated list of containers to restart}" +POLL_INTERVAL="${POLL_INTERVAL:-30}" + +# Only restart when status *becomes* unhealthy (avoids restarting every poll while still unhealthy). +# Set RESTART_ON_EVERY_POLL=1 to restart on every poll while unhealthy. +RESTART_ON_EVERY_POLL="${RESTART_ON_EVERY_POLL:-0}" + +log() { + printf '%s %s\n' "$(date '+%Y-%m-%dT%H:%M:%S')" "$*" +} + +inspect_health() { + docker inspect --format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' "$1" 2>/dev/null || printf 'missing' +} + +restart_list() ( + IFS=',' + for c in $RESTART_CONTAINERS; do + c=$(echo "$c" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + [ -z "$c" ] && continue + if docker restart "$c" 2>/dev/null; then + log "restarted: $c" + else + log "restart failed: $c" + fi + done +) + +prev="" +log "watching health of: $WATCH_CONTAINER (interval ${POLL_INTERVAL}s)" +log "will restart on unhealthy: $RESTART_CONTAINERS" + +while true; do + status="$(inspect_health "$WATCH_CONTAINER")" + + case "$status" in + missing) + log "watch target not found: $WATCH_CONTAINER" + ;; + unhealthy) + if [ "$RESTART_ON_EVERY_POLL" = "1" ] || [ "$prev" != "unhealthy" ]; then + log "unhealthy — restarting configured containers" + restart_list + fi + ;; + *) + ;; + esac + + prev="$status" + sleep "$POLL_INTERVAL" +done