diff --git a/README.md b/README.md index e55beb7..df6cd2c 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ ___ ## Changelog - **v0.7.5**: - - Added new option **DaysKept**; `-k N` and `-K`: + - Added new option **BackupForDays**; `-b N` and `-B`: - Backup an image before pulling a new version for easy rollback in case of breakage. - Removes backed up images older than *N* days. - List currently backed up images with `-K`. @@ -56,6 +56,8 @@ Example: dockcheck.sh -y -x 10 -d 10 -e nextcloud,heimdall Options: -a|y Automatic updates, without interaction. +-b N Enable image backups and sets number of days to keep from pruning. +-B List currently backed up images, then exit. -c D Exports metrics as prom file for the prometheus node_exporter. Provide the collector textfile directory. -d N Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower. -e X Exclude containers, separated by comma. @@ -63,8 +65,6 @@ Options: -F Only compose up the specific container, not the whole compose stack (useful for master-compose structure). -h Print this Help. -i Inform - send a preconfigured notification. --k N DaysKept - enable backups of images prior to update and prunes backups older than N days. --K List currently backed up images, then exit. -I Prints custom releasenote urls alongside each container with updates in CLI output (requires urls.list). -l Only include containers with label set. See readme. -m Monochrome mode, no printf colour codes and hides progress bar. @@ -83,18 +83,19 @@ Options: ### Basic example: ``` $ ./dockcheck.sh -. . . +[##################################################] 5/5 + Containers on latest version: glances homer Containers with updates available: -1) adguardhome -2) syncthing -3) whoogle-search +01) adguardhome +02) syncthing +03) whoogle-search Choose what containers to update: -Enter number(s) separated by comma, [a] for all - [q] to quit: +Enter number(s) separated by comma, [a] for all - [q] to quit: 1,2 ``` Then it proceeds to run `pull` and `up -d` on every container with updates. After the updates are complete, you'll get prompted if you'd like to prune dangling images. @@ -242,21 +243,22 @@ The `urls.list` file is just an example and I'd gladly see that people contribut Pass `-x N` where N is number of subprocesses allowed, experiment in your environment to find a suitable max! Change the default value by editing the `MaxAsync=N` variable in `dockcheck.sh`. To disable the subprocess function set `MaxAsync=0`. -## Image Backups; `-k N` to backup previous images as custom (retagged) images for easy rollback -When the option `DaysKept` is set **dockcheck** will store the image being updated as a backup, retagged with a different name and removed due to age configured (*DaysKept*) in a future run. +## Image Backups; `-b N` to backup previous images as custom (retagged) images for easy rollback +When the option `BackupForDays` is set **dockcheck** will store the image being updated as a backup, retagged with a different name and removed due to age configured (*BackupForDays*) in a future run. Let's say we're updating `b4bz/homer:latest` - then before replacing the current image it will be retagged with the name `dockcheck/homer:2025-10-26_1132_latest` - `dockcheck` as repo name to not interfere with others. - `homer` is the image. - `2025-10-26_1132` is the time when running the script. - `latest` is the tag of the image. -Then if an update breaks you could temporarily roll back to the previoius working state by changing the docker compose image to `image: dockcheck/homer:2025-10-26_1132_latest` and get it up and running again, then continue troubleshooting the breaking update. +Then if an update breaks, you could restore the image by stopping the container, delete the new image, eg. `docker rmi b4bz/homer:latest`, then retag the backup as latest `docker tag dockcheck/homer:_latest b4bz/homer:latest`. +After that, start the container again (now with the backup image active) and it will be updated as usual next time you run dockcheck or other updates. -The backed up images will be removed if they're older than *DaysKept* value (passed as `-k N` or set in the `dockcheck.config` with `DaysKept=N`) and then pruned. -If configured for eg. 7 days, force earlier cleaning by just passing a lower number of days, eg. `-k 2` to clean everything older than 2 days. -Backed up images will not be removed if neither `-k` flag nor `DaysKept` config variable is set. +The backed up images will be removed if they're older than *BackupForDays* value (passed as `-b N` or set in the `dockcheck.config` with `BackupForDays=N`) and then pruned. +If configured for eg. 7 days, force earlier cleaning by just passing a lower number of days, eg. `-b 2` to clean everything older than 2 days. +Backed up images will not be removed if neither `-b` flag nor `BackupForDays` config variable is set. -Use the capital option `-K` to list currently backed up images. Or list all images with `docker images`. +Use the capital option `-B` to list currently backed up images. Or list all images with `docker images`. To manually remove any backed up images, do `docker rmi dockcheck/homer:2025-10-26_1132_latest`. ## Extra plugins and tools: diff --git a/default.config b/default.config index 2289391..90abfa5 100644 --- a/default.config +++ b/default.config @@ -28,7 +28,7 @@ #CurlRetryCount=3 # Max number of curl retries #CurlConnectTimeout=5 # Time to wait for curl to establish a connection before failing #DisplaySourcedFiles=false # Display what files are being sourced/used -#DaysKept=7 # Enable backups of images and removes backups older than N days. +#BackupForDays=7 # Enable backups of images and removes backups older than N days. ### Notify settings ## All commented values are examples only. Modify as needed. diff --git a/dockcheck.sh b/dockcheck.sh index 9a4b4be..7b98f02 100755 --- a/dockcheck.sh +++ b/dockcheck.sh @@ -34,6 +34,8 @@ Help() { echo echo "Options:" echo "-a|y Automatic updates, without interaction." + echo "-b N Enable image backups and sets number of days to keep from pruning." + echo "-B List currently backed up images, then exit." echo "-c Exports metrics as prom file for the prometheus node_exporter. Provide the collector textfile directory." echo "-d N Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower." echo "-e X Exclude containers, separated by comma." @@ -42,10 +44,7 @@ Help() { echo "-h Print this Help." echo "-i Inform - send a preconfigured notification." echo "-I Prints custom releasenote urls alongside each container with updates in CLI output (requires urls.list)." - echo "-k N Number of days to store image backups before pruning - this also enables the backup function." - echo "-K List currently backed up images, then exit." echo "-l Only include containers with label set. See readme." - echo "-k N DaysKept - enable backups of images prior to update and prunes backups older than N days." echo "-m Monochrome mode, no printf colour codes and hides progress bar." echo "-M Prints custom releasenote urls as markdown (requires template support)." echo "-n No updates; only checking availability without interaction." @@ -86,7 +85,7 @@ Stopped=${Stopped:-""} CollectorTextFileDirectory=${CollectorTextFileDirectory:-} Exclude=${Exclude:-} DaysOld=${DaysOld:-} -DaysKept=${DaysKept:-} +BackupForDays=${BackupForDays:-} OnlySpecific=${OnlySpecific:-false} SpecificContainer=${SpecificContainer:-""} SkipRecreate=${SkipRecreate:-false} @@ -111,9 +110,11 @@ c_reset="\033[0m" RunTimestamp=$(date +'%Y-%m-%d_%H%M') RunEpoch=$(date +'%s') -while getopts "ayfFhiIlmMnprsuvc:e:d:k:Kt:x:R" options; do +while getopts "ayb:BfFhiIlmMnprsuvc:e:d:t:x:R" options; do case "${options}" in a|y) AutoMode=true ;; + b) BackupForDays="${OPTARG}" ;; + B) print_backups; exit 0 ;; c) CollectorTextFileDirectory="${OPTARG}" ;; d) DaysOld=${OPTARG} ;; e) Exclude=${OPTARG} ;; @@ -121,8 +122,6 @@ while getopts "ayfFhiIlmMnprsuvc:e:d:k:Kt:x:R" options; do F) OnlySpecific=true ;; i) Notify=true ;; I) PrintReleaseURL=true ;; - k) DaysKept="${OPTARG}" ;; - K) print_backups; exit 0 ;; l) OnlyLabel=true ;; m) MonoMode=true ;; M) PrintMarkdownURL=true ;; @@ -172,9 +171,9 @@ if [[ -n "$DaysOld" ]]; then exit 2 fi fi -if [[ -n "$DaysKept" ]]; then - if ! [[ $DaysKept =~ ^[0-9]+$ ]]; then - printf "-k argument given (%s) is not a number.\n" "$DaysKept" +if [[ -n "$BackupForDays" ]]; then + if ! [[ $BackupForDays =~ ^[0-9]+$ ]]; then + printf "-b argument given (%s) is not a number.\n" "$BackupForDays" exit 2 fi fi @@ -570,7 +569,7 @@ if [[ -n "${GotUpdates:-}" ]]; then [[ "$ContPath" == "null" ]] && ContPath="" # Add new backup tag prior to pulling if option is set - if [[ -n "${DaysKept:-}" ]]; then + if [[ -n "${BackupForDays:-}" ]]; then ImageConfig=$(docker image inspect "$ImageId" --format '{{ json . }}') ContRepoDigests=$($jqbin -r '.RepoDigests[0]' <<< "$ImageConfig") [[ "$ContRepoDigests" == "null" ]] && ContRepoDigests="" @@ -595,7 +594,7 @@ if [[ -n "${GotUpdates:-}" ]]; then if docker pull "$ContImage"; then # Removal of the -tag image left behind from backup - if [[ ! -z "${ContRepoDigests:-}" ]] && [[ -n "${DaysKept:-}" ]]; then docker rmi "$ContRepoDigests"; fi + if [[ ! -z "${ContRepoDigests:-}" ]] && [[ -n "${BackupForDays:-}" ]]; then docker rmi "$ContRepoDigests"; fi else printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1 fi @@ -663,8 +662,8 @@ if [[ -n "${GotUpdates:-}" ]]; then fi printf "\n%bAll updates done!%b\n" "$c_green" "$c_reset" - # Clean up old backup image tags if -k is used - if [[ -n "${DaysKept:-}" ]]; then + # Clean up old backup image tags if -b is used + if [[ -n "${BackupForDays:-}" ]]; then IFS=$'\n' CleanupCount=0 for backup_img in $(docker images --format "{{.Repository}} {{.Tag}}" | sed -n '/^dockcheck/p'); do @@ -672,8 +671,8 @@ if [[ -n "${GotUpdates:-}" ]]; then backup_tag=${backup_img#* } backup_date=${backup_tag%%_*} # UNTAGGING HERE - if datecheck "$backup_date" "$DaysKept"; then - [[ "$CleanupCount" == 0 ]] && echo "Removing backed up images older then $DaysKept days." + if datecheck "$backup_date" "$BackupForDays"; then + [[ "$CleanupCount" == 0 ]] && echo "Removing backed up images older then $BackupForDays days." docker rmi "${repo_name}:${backup_tag}" && ((CleanupCount+=1)) fi done