This commit is contained in:
Executable
+68
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
notify() {
|
||||||
|
local color="$1"
|
||||||
|
local msg="$2"
|
||||||
|
local hostname=$(hostname)
|
||||||
|
echo "$msg"
|
||||||
|
ntfy pub -T "${color}_square" -t "Docker Health on ${hostname}" docker "$msg" >/dev/null 2>&1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
declare -A compose_projects
|
||||||
|
declare -a standalone_containers
|
||||||
|
|
||||||
|
# Find unhealthy containers
|
||||||
|
while read -r container; do
|
||||||
|
health=$(docker inspect \
|
||||||
|
--format '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' \
|
||||||
|
"$container")
|
||||||
|
|
||||||
|
# Ignore missing health checks and containers still starting
|
||||||
|
if [[ "$health" != "unhealthy" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
project_dir=$(docker inspect \
|
||||||
|
--format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}' \
|
||||||
|
"$container")
|
||||||
|
|
||||||
|
if [[ -n "$project_dir" && "$project_dir" != "<no value>" ]]; then
|
||||||
|
compose_projects["$project_dir"]+="$container "
|
||||||
|
else
|
||||||
|
standalone_containers+=("$container")
|
||||||
|
fi
|
||||||
|
|
||||||
|
done < <(docker ps -q)
|
||||||
|
|
||||||
|
# Restart compose projects once each
|
||||||
|
for project_dir in "${!compose_projects[@]}"; do
|
||||||
|
containers="${compose_projects[$project_dir]}"
|
||||||
|
|
||||||
|
notify "orange" "Unhealthy containers in $(basename "$project_dir"): $containers"
|
||||||
|
|
||||||
|
if [[ -f "$project_dir/compose.yaml" ]]; then
|
||||||
|
if docker compose \
|
||||||
|
--project-directory "$project_dir" \
|
||||||
|
up -d --force-recreate; then
|
||||||
|
|
||||||
|
notify "green" "Recovery succeeded: $(basename "$project_dir")"
|
||||||
|
else
|
||||||
|
notify "red" "Recovery FAILED: $(basename "$project_dir")"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
notify "black" "Missing compose.yaml in $project_dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Restart standalone containers
|
||||||
|
for container in "${standalone_containers[@]}"; do
|
||||||
|
notify "orange" "Unhealthy standalone container $container"
|
||||||
|
|
||||||
|
if docker restart "$container" >/dev/null; then
|
||||||
|
notify "green" "Recovery succeeded: $container"
|
||||||
|
else
|
||||||
|
notify "red" "Recovery FAILED: $container"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
Executable
+73
@@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# perform a "docker compose pull" on each location specified (recursively), or current location if none specified.
|
||||||
|
#
|
||||||
|
# will only search symbolic links when passed "-l" option, must be before any locations
|
||||||
|
# will only search hidden directories when passed "-h" option, must be before any locations
|
||||||
|
# pull-all.sh [-l][-h] # current location implied
|
||||||
|
# pull-all.sh [-l][-h] ~/my-projects /var/group-projects
|
||||||
|
|
||||||
|
# check for "-l" and "-h" in command prompt
|
||||||
|
followLinks="-H"
|
||||||
|
checkHidden="*/.*/*compose.yaml"
|
||||||
|
while getopts "lh" option; do
|
||||||
|
case $option in
|
||||||
|
l)
|
||||||
|
followLinks="-L"
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
checkHidden=""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift "$((OPTIND-1))"
|
||||||
|
|
||||||
|
if [[ "-H" == "$followLinks" ]]; then
|
||||||
|
echo "use -l to follow symbolic links"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$checkHidden" ]]; then
|
||||||
|
echo "use -h to check hidden directories"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# function to process each location
|
||||||
|
function process_docker_pull () {
|
||||||
|
startedIn=`pwd`
|
||||||
|
location=$(realpath $(dirname "$@"))
|
||||||
|
line="--- --- --- --- --- --- --- --- ---"
|
||||||
|
# use "--" to tell printf there are no more commands, only strings to print
|
||||||
|
printf -- "--- docker compose pull %s %s ---\n" "$location" "${line:${#location}}"
|
||||||
|
cd "$location"
|
||||||
|
|
||||||
|
# populate $runningServices[]
|
||||||
|
mapfile -t runningServices < <(
|
||||||
|
docker compose ps --services --status running
|
||||||
|
)
|
||||||
|
|
||||||
|
quietDocker=$(docker compose pull --ignore-buildable --ignore-pull-failures)
|
||||||
|
|
||||||
|
if docker compose up -d --dry-run | grep -q "Recreate"; then
|
||||||
|
# Only restart services that were already running
|
||||||
|
if ((${#runningServices[@]} > 0)); then
|
||||||
|
echo "restarting the following services: ${runningServices[@]}"
|
||||||
|
quietDocker=$(docker compose up -d "${runningServices[@]}")
|
||||||
|
else
|
||||||
|
echo "updates downloaded, no services were running"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
messageSuffix=""
|
||||||
|
if ((${#runningServices[@]} > 0)); then
|
||||||
|
messageSuffix=", services already current: ${runningServices[@]}"
|
||||||
|
fi
|
||||||
|
echo "no changes detected$messageSuffix"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "$startedIn"
|
||||||
|
}
|
||||||
|
|
||||||
|
# find all folders named ".git" under given locations,
|
||||||
|
# and call process_git_pull on each location that was found.
|
||||||
|
# we then work on the folder that contained the ".git" folder.
|
||||||
|
|
||||||
|
find "$followLinks" "$@" -type f \( -name 'compose.yaml' -o -name 'docker-compose.yaml' \) -not -path "$checkHidden" | sort | while read -r file; do process_docker_pull "$file"; done
|
||||||
|
|
||||||
@@ -66,6 +66,12 @@ Plug 'airblade/vim-gitgutter'
|
|||||||
Plug 'vim-airline/vim-airline'
|
Plug 'vim-airline/vim-airline'
|
||||||
Plug 'vim-airline/vim-airline-themes'
|
Plug 'vim-airline/vim-airline-themes'
|
||||||
|
|
||||||
|
" twig support (php templating)
|
||||||
|
Plug 'lumiliet/vim-twig'
|
||||||
|
|
||||||
|
" AnsiEsc to make editing colorful files better
|
||||||
|
Plug 'powerman/vim-plugin-AnsiEsc'
|
||||||
|
|
||||||
call plug#end()
|
call plug#end()
|
||||||
|
|
||||||
" config git-gutter
|
" config git-gutter
|
||||||
|
|||||||
Reference in New Issue
Block a user