Add a script to update docker images with docker compose
This commit is contained in:
1 parent
fb747989d0
commit
1f6a602555
1 file changed
+108
Executable
+108
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
# Usage: ./update_docker_images.sh [--prune] [--build] [compose-directory]
|
||||
# By default, pull images and update services without pruning or building.
|
||||
# WARNING: Pruning removes stopped containers, unused images, build cache,
|
||||
# and unused anonymous volumes.
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
printf 'Usage: %s [--prune] [--build] [compose-directory]\n' "$0"
|
||||
printf '%s\n' \
|
||||
' --prune Remove unused Docker resources before updating (including volumes).' \
|
||||
' --build Build images with --pull before updating services.' \
|
||||
' -h, --help Show this help.' \
|
||||
'Default: pull images and update services; do not prune or build.'
|
||||
}
|
||||
|
||||
prune=false
|
||||
build=false
|
||||
positional=()
|
||||
while (( $# )); do
|
||||
case "$1" in
|
||||
--prune) prune=true ;;
|
||||
--build) build=true ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
--) shift; positional+=("$@"); break ;;
|
||||
-*) printf 'Unknown option: %s\n' "$1" >&2; usage >&2; exit 2 ;;
|
||||
*) positional+=("$1") ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
if (( ${#positional[@]} > 1 )); then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
compose_root=${positional[0]:-/etc/docker/compose}
|
||||
if [[ ! -d "$compose_root" ]]; then
|
||||
printf 'Compose directory not found: %s\n' "$compose_root" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
created_builder=
|
||||
cleanup() {
|
||||
local status=$?
|
||||
trap - EXIT
|
||||
if [[ -n "$created_builder" ]]; then
|
||||
if ! docker buildx rm "$created_builder"; then
|
||||
printf 'Could not remove builder: %s\n' "$created_builder" >&2
|
||||
if (( status == 0 )); then
|
||||
status=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
exit "$status"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
trap 'exit 130' INT
|
||||
trap 'exit 143' TERM
|
||||
|
||||
if "$prune"; then
|
||||
docker system df
|
||||
docker system prune -a --volumes -f
|
||||
docker system df
|
||||
fi
|
||||
|
||||
if "$build"; then
|
||||
# Select an existing container builder, not merely check whether one exists.
|
||||
# Capture the list separately so a failed Docker command stops the script.
|
||||
builders=$(docker buildx ls --format '{{.Name}} {{.Driver}}')
|
||||
builder=
|
||||
while read -r name driver; do
|
||||
if [[ "$driver" == docker-container ]]; then
|
||||
builder=$name
|
||||
break
|
||||
fi
|
||||
done <<< "$builders"
|
||||
if [[ -z "$builder" ]]; then
|
||||
# Bootstrap separately so cleanup can run if startup fails.
|
||||
created_builder=$(docker buildx create \
|
||||
--buildkitd-config /etc/docker/buildx/buildkit.toml \
|
||||
--driver docker-container \
|
||||
--driver-opt 'network=treehouse')
|
||||
builder=$created_builder
|
||||
fi
|
||||
|
||||
# Select the builder for this script without changing the user's default.
|
||||
export BUILDX_BUILDER="$builder"
|
||||
docker buildx inspect "$builder" --bootstrap
|
||||
fi
|
||||
|
||||
for directory in "$compose_root"/*; do
|
||||
[[ -d "$directory" ]] || continue
|
||||
[[ -f "$directory/docker-compose.yml" ]] || continue
|
||||
# Manually update Minecraft, so we're not always on the cutting edge
|
||||
[[ "$directory" == *minecraft* ]] && continue
|
||||
|
||||
printf '\nUpdating %s\n' "$directory"
|
||||
# A subshell restores the working directory even when a command fails.
|
||||
(
|
||||
cd -- "$directory"
|
||||
docker compose pull
|
||||
if "$build"; then
|
||||
docker compose build --pull
|
||||
fi
|
||||
# Do not let Compose implicitly build images when starting services.
|
||||
docker compose up -d --no-build
|
||||
)
|
||||
done
|
||||
Reference in new issue
Block a user