Compare commits

...

421 commits
v0.1.5 ... main

Author SHA1 Message Date
singularity0821
7785e869d3
Add additional URLs to urls.list (#263)
* Sanitize message for Matrix notifications

* Use variable for jq and increment version of Matrix script

* Add additional URLs to urls.list

---------

Co-authored-by: martin <martin@meissnitzer.dev>
2026-02-06 18:07:58 +01:00
mag37
fc0b1a2505 Versionbump, changenotes 2026-01-29 13:06:07 +01:00
mag37
6c969c9169 mend 2026-01-29 09:59:45 +01:00
mag37
6e3b7ee419 Added Bark to README and minor cleanups 2026-01-29 09:42:33 +01:00
mag37
f801471288 Merge branch 'smoochy-fix_readme_and_default.config' 2026-01-29 09:20:56 +01:00
mag37
1ac92c916e Merge branch 'fix_readme_and_default.config' of github.com:smoochy/dockcheck into smoochy-fix_readme_and_default.config 2026-01-29 09:19:21 +01:00
smoochy
1584f23d33 - Adjusted description of "-r" parameter
- Adjusted order of parameters between dockcheck.sh and readme
- Added missing parameter values from readme into dockcheck.sh
2026-01-28 21:39:51 +01:00
solitudechn
9755c32f8c
add-bark-notify (#259) 2026-01-28 10:19:34 +01:00
mag37
9c780b8b35
Consistent sub-headers 2026-01-27 09:31:19 +01:00
smoochy
c9a4150b67 Adjusted default.config & readme 2026-01-26 20:14:47 +01:00
smoochy
fc5c5db72b
[Issue 255] Fix Notifiy also checking for /etc/HOSTNAME (#256)
* - Adjusted **FromHost** variable to have fallback options when `cat /etc/hostname` or `hostname` command fails.
* - Bumped Version to 0.7
2026-01-25 10:47:48 +01:00
singularity0821
4e0b705b8b
Sanitize message for Matrix notifications (#243)
* Sanitize message for Matrix notifications

* Use variable for jq and increment version of Matrix script

---------

Co-authored-by: martin <martin@meissnitzer.dev>
2025-12-14 11:49:56 +01:00
mag37
8ee5575081
Added option -b to enable image backups pre pull. (#242)
* added new variables, options and setup

* datecheck function rewrite

* moved the cleanup and prune logic to always run. Changed some wording on messages.

* added function to print currently backed up images

* Patched bugfix to not recreate stopped containers

* changed the RepoDigests grab and logic

* Moved the backup - cleanup to always trigger if -b option is used. Added -p&-b warning.

* version bump and readme fixes
2025-12-12 11:12:57 +01:00
Andrei Mateescu
f1cc8190f9
Add the Pangolin stack to urls.list (#241)
Adds a few items from the Pangolin stack (https://github.com/fosrl/) and others that are usually used together.
2025-12-12 11:00:42 +01:00
Oleh Astappiev
c33c9f4387
Fix version check condition (#239) 2025-11-13 06:17:25 +01:00
mag37
c34d52bde0
the missing ) 2025-11-01 09:25:11 +01:00
mag37
7ea97d06ce
New option -R and bugfix + cleanup (#236)
* Cleaned up legacy structure
* Add -R flag to skip container recreation after pulling images (#235)
* Added new -R option: Skip Container recreation
---------

Co-authored-by: mag37 <robin.ivehult@gmail.com>
Co-authored-by: NapalmZ <willy.baessato@gmail.com>
2025-11-01 09:14:49 +01:00
mag37
8970ee3f20
added to the sponsorlist 2025-10-21 20:47:10 +02:00
mag37
12a51d8e83
added new sponsors 2025-10-08 19:00:29 +02:00
mag37
24cae63b61
bugfix - unquoted var in list
Versionbump.
2025-10-07 08:25:44 +02:00
mag37
05e5b23e7b
bugfix - unquoted var in list
Versionbump.
2025-10-07 08:24:31 +02:00
mag37
be58805824 hot-patch unquoted variable in updates list 2025-10-06 10:18:38 +02:00
mag37
af0d0d3f6e
label and update list rework (#229)
* Reformatting the updates available list

* rewritten list padding to be dynamic

* Label rework + clearer messages (#228)

- Moved up label check and logic to earlier in the process, to iterate the whole run the same way if `-l` option is passed.
- Added messaging to make it clearer.
- Clarified Readme and --help message.
- Clarified prune message (to mean ALL dangling, not just currently updated).
2025-10-03 09:22:17 +02:00
mag37
7d1e1637f9
formatting + sponsors + removed emojis
Removed emojis - don't want it to look like just about any AI-slop.
Added more sponsors.
Changed some formatting.
2025-09-15 11:49:09 +02:00
vorezal
31a45f1d84
Add file notification channel (#222)
* Add file notification channel

* Bypass file channel notifications for dockcheck.sh script

* Implement notification channel template reuse and advanced configuration variables.

* Fix text insertion formatting for dockcheck script and container updates.

* Fix dockcheck.sh notification csv and text output.

* Fix ntfy variable references and replace tr for uppercase conversion.

* Fix ALLOWEMPTY logic, undefined snippet case, and README formatting.

* Refactor notification send/skip logic. Adjust missing variable return codes.

* Adjust notifications README section for clarity and readability.

---------

Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
2025-09-15 11:25:23 +02:00
mag37
37f33d7a06 Snooze bugfix, added auth support to ntfy.sh and sendmail support to SMTP 2025-08-11 21:36:51 +02:00
vorezal
732a5e69cd
Reword disable notification comment for clarity and use update_snooze for dockcheck notifications. (#221)
Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
2025-08-11 21:17:01 +02:00
op4lat
9156cc44e1
Ntfy.sh and authentication (#220)
* default.config: add NtfyAuth=

* notify_templates/notify_ntfy.sh: implement NtfyAuth

---------

Co-authored-by: Lat <lat@mail.com>
Co-authored-by: mag37 <robin.ivehult@gmail.com>
2025-08-11 21:16:38 +02:00
xmirakulix
fbc9a252f5
update SMTP template, added suport for sendmail (#219)
* update smtp template, add suport for sendmail

* add sendmail to DSM and bump version

* correct errormsg and version number
2025-08-02 08:04:43 +02:00
mag37
1f374b5003
clarifying ntfy.sh
"domain" is a bit misleading, so clarifying that https:// is needed. Might change to "NTFY_URL" in the future.
2025-07-27 15:06:35 +02:00
mag37
563dbb8b42
Label bugfix, search filtering fix (#216)
* search filtering fix
* skip recreation if no label when -l option used + clarification
* changed readme + help to correctly show help example
2025-07-25 10:35:49 +02:00
mag37
31bb2008b9
new logo 2025-07-19 00:41:43 +02:00
mag37
cfa74adc3d
added new logo 2025-07-19 00:40:50 +02:00
Rasmus Lundsgaard
e2dbd69c5e
first version of notification to Home Assistant (#213)
* first working version of notification to Home Assistant

* add documentation links

* update readme for notify_HA
2025-07-14 13:59:07 +02:00
mag37
98e996caa3
added paypay sponsor 2025-07-07 10:49:32 +02:00
mag37
a1e7446753 version bump + readme 2025-07-01 22:27:54 +02:00
op4lat
69c06de1bd
Add DisplaySourcedFiles variable (#207)
* Add DisplaySourcedFiles variable to be used in source_if_exists and source_if_exists_or_fail functions
* Added return 0 as to not throw wrong exit code.
* Delete source_if_exists. source_if_exists_or_fail returns success or failure. Failure doesn't stop the script

---------

Co-authored-by: Elephant Quater <eq@cont.MSHOME>
Co-authored-by: mag37 <robin.ivehult@gmail.com>
2025-07-01 22:19:15 +02:00
mag37
d37e1a1024
Bugfixes for unbound variable, potential collision and config variable mismatch
Version bump to alert users of the latest bugfixes for unbound variable, potential collision and config variable mismatch.
2025-06-27 09:22:10 +02:00
vorezal
77f024bb81
Fix unbound variable, potential collision, and config variable. (#209)
* Fix unbound variable, potential collision, and config variable.

* Return 0 when notification functions finish successfully

---------

Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
2025-06-27 09:10:31 +02:00
vorezal
a0e11de383
Snooze feature, curl, and consolidation (#200)
* Snooze feature, curl, and consolidation

* Added snooze feature to delay notifications

* Added configurable default curl arguments

* Consolidated and standardized notify template update notifications

* Added curl error handling

* Snooze comment fix

* Grep, curl args, and variable init adjustments

* Modified grep commands to make use of word boundaries in order to avoid matching on substrings

* Set CurlRetryDelay, CurlRetryCount, and CurlConnectTimeout as individual variables

* Used :- for variable initialization where assignment is redundant

* Update dockcheck.sh change notes and fix variable collision

* Remove unnecessary cat and clarify readme

* reformatting

---------

Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
Co-authored-by: mag37 <robin.ivehult@gmail.com>
2025-06-24 15:16:48 +02:00
mag37
272615166e
ntfy rename
Corrected all mentions of the ntfy template with its new name.
Also clarified the help message of the -r option.
2025-05-31 22:05:35 +02:00
mag37
4a16d2f1ea
-r clarification
Clarified the help message for the -r option.
2025-05-31 22:02:52 +02:00
Christopher Berg
67648efbe8
ntfy notification bug fixes (#197) 2025-05-31 21:55:21 +02:00
mag37
68c057e62d v0.6.6 bump and info 2025-05-29 23:03:46 +02:00
vorezal
57650f1673
Notify_v2.sh bug fixes (#188)
* Notify_v2.sh bug fixes

* Clarify notify_v2.sh usage in README.md

* Fix JSON newline handling in Discord and Telegram channels

* Additional error messages when notification templates fail to be sourced

* Additional variable for self-hosted ntfy.sh domain

* Notify_v2.sh additional fixes

* Clarify usage in README.md and notify template comments

* Support sourcing template files from project root

* Add days old message to notification title

* Handle JSON with jq in Discord and Telegram templates

* Tweak notify_v2.sh usage docs and comments

* Remove extra newline from notification body

* replaced jq with jqbin, reodered setting of jqbin, changed source for hostname var

* moved the setting of jqbin a bit further up after further testing

---------

Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
Co-authored-by: mag37 <robin.ivehult@gmail.com>
2025-05-29 22:43:34 +02:00
mag37
22871442db
hotfix suppress noise
Suppressed noise about not being able to source notification (new function) when on legacy notification template.
2025-05-26 07:27:51 +02:00
mag37
ec09612274
version bump
Version bump after minor tweaks.
Should probably learn to squash properly.. soon!
2025-05-25 18:44:20 +02:00
mag37
5e7d4f0b8a minor tweaks; curl/wget retries, missing variable fix in root-check 2025-05-25 18:39:34 +02:00
mag37
57f7580477
Update dockcheck.sh
lowering version until a few more tweaks are done.
2025-05-25 18:27:12 +02:00
vorezal
c63e2441fa
Refactor notifications and add helper functions (#182)
* Refactor notifications and add helper functions

* Add helper functions to simplify sourcing files and executing functions if they exist

* Create notify_v2.sh wrapper script

* Simplify and consolidate notification logic within notify_v2.sh

* Support notification management via environment variables

* Move secrets to dockcheck.config

* Fix NOTIFY_CHANNELS default value when not set

* Feedback changes

* Remove leading spaces from MessageBody

* Check for valid notify v2 variables

* Warn on missing configuration and bypass notifications

* Update readme

* Additional feedback fixes

* More comments in default.config with different # depth for comments and settings

* Rename NOTIFY_TOPIC_NAME variable to NTFY_TOPIC_NAME for consistency

* Add TELEGRAM_TOPIC_ID

* Fix AppriseURL variable

* Add an ending newline to all MessageBody statements for consistency

* Remove troubleshooting echo statement

* Prevent attempting to trigger notifications for notification templates if versions are the same

---------

Co-authored-by: Matthew Oleksowicz <matt@everyoneneeds.it>
2025-05-25 18:26:13 +02:00
mag37
e4b93d113c fixed variable errors 2025-05-15 15:49:49 +02:00
mag37
b2d80d036a
info about -r option 2025-05-14 20:55:09 +02:00
mag37
d80fba750f quickfix printfs 2025-05-12 15:54:34 +02:00
mag37
7ce523c37d
added sponsor 2025-05-12 07:28:49 +02:00
mag37
8e444a688f
Update rework (#178)
* first iteration rewriting the update logic

* formatting fixes

* Added an option to have compose up only target the specific container.
Used with either -F flag, config variable or label.

* Skipping update check on non-compose containers unless option is set

* Versionbump
Added new info and upped the version number.
2025-05-11 20:50:09 +02:00
mag37
ba107a424f
version bump 2025-05-07 11:31:34 +02:00
op4lat
e4b5aaeb9d
Enable markdown (#172) 2025-05-07 11:29:21 +02:00
mag37
f4e51121fe
versionbump
info: Permission checks, now compose up on whole stack, -M markdown option added.
2025-05-03 10:20:32 +02:00
mag37
7a0eda659b
Update README.md 2025-05-03 10:16:07 +02:00
mag37
77c0a4974d
Update urls.list
added more
2025-05-03 09:56:21 +02:00
mag37
9d0eddbdcb
rolled back
syntax error with unescaped dashes?
2025-05-03 00:20:39 +02:00
mag37
eb57b63a10
permission checks, dsm readme, markdown (#171)
* added check for docker socket permissions

* added sudo-check to pkg-manager

* corrected variable typo and some printf colors

* and newline..

* DSM extra readme added

* final tweaks, DSM readme

* added markdown to readme

* added markdown support to telegram template

* removed container specification from compose up -d
This will ensure any dependant containers in the same stack will
restart, others will be untouched.

* Rearranged where the url enrichment happens
2025-05-02 21:40:24 +02:00
Tobias Diekel
e393a781cf
Add option to format releasenotes as markdown (#170)
* feat: allow markdown formatting for gotify
* feat: add option to cli args
* fix: use markdown for missing urls
* fix: do not print curl
* fix: add empty line
* bump template version

---------

Co-authored-by: Tobias Diekel <td@diekel.eu>
2025-05-02 20:08:04 +02:00
jaaviercr
af202c9d6a
Update dockcheck.sh (#169)
The script did not stop when  there is an error recreating the container (in this case, docker-compose.yml was moved to other folder):
```
Now updating (1/1): nginx
latest: Pulling from library/nginx
Digest: sha256:c15da6c91de8d2f436196f3a768483ad32c258ed4e1beb3d367a27ed67253e66
Status: Image is up to date for nginx:latest
docker.io/library/nginx:latest
open /home/foo/bar/docker-compose.yml: no such file or directory

All done!
```
Added an exit for for that case.
2025-05-01 17:49:41 +02:00
Ulices
dc1673a752
fix: move new line from read to printf (#164) 2025-04-21 18:37:24 +02:00
firmlyundecided
a9e57d0737
Update urls.list (#162)
added urls for

homarr
tautulli
cleanuperr
slskd
bookstack
lubelogger
mealie
2025-04-12 11:14:07 +02:00
mag37
fff0c37fa4
Style and additions (#160)
* correcting colors

* hides progress bar in monochrome mode, added monochrome mode to config

* Added config/option to auto self-update, use with caution!

* use notification release notes url function for cli options as well

* added the flag, reordered flags

* change output order + add alpine pkgmngr

* changed logic of default.config

* added an extras section

* modifying urls list, adding option flag

* prometheus hotfix + minor tweaks

* quick pkginstaller fix

---------

Co-authored-by: Joachim Schuster <dev@joachimschuster.de>
2025-04-10 12:03:03 +02:00
mag37
0ea33366e4
prometheus hotfix 2025-04-09 18:21:07 +02:00
mag37
3a8571c625 fixes for odd unbound variables 2025-03-31 11:23:21 +02:00
mag37
710cbc118f fix: Excludes unbound 2025-03-31 07:22:22 +02:00
mag37
68ec749c39 hotfixes 2025-03-30 22:58:47 +02:00
mag37
778df1de3c PkgInstaller bug, reformatted 2025-03-30 22:17:15 +02:00
mag37
8dd1bba75b
Clean&refactor (#148)
* cleaning spaces and consistent formatting
* removed more subshells
* progress bar cleanup
* moved uservars to a .config file
* rewritten options from yes/no to true/false
* initialized default variables
* added bash options: -euo pipefail, shopt -s nullglob and failglob
* quoting variables, cleaning syntax, logic and order
* unquoted some variables due to breakage
* added exit on pull-fail
* added new sponsor
* added Slack template
2025-03-30 13:31:34 +02:00
mag37
b5c03a2caa
Merge pull request #139 from devzwf/main
Update README.md
2025-03-18 05:38:59 +01:00
ZwF
9c4c79b885
Update README.md
Add the -x option to the readme...
2025-03-17 22:20:06 -04:00
mag37
d9fe113225 updated gif 2025-03-17 08:39:09 +01:00
mag37
0a9d60f4df
Merge pull request #137 from mag37/notify_versioning
notify-template versioning
2025-03-16 20:56:11 +01:00
mag37
c57923f152 versionbump 2025-03-16 20:54:34 +01:00
mag37
fd1769c30f added versions + version checks to all templates 2025-03-16 20:47:46 +01:00
mag37
965f2dd825 first change to DSM 2025-03-14 20:36:07 +01:00
mag37
48057dfc66
notify and xargs info added
Added info about notifying on new dockcheck updates and a info block about async/xargs.
2025-03-09 10:19:22 +01:00
mag37
98e80854be
Merge pull request #135 from mag37/dockcheck_upd_notify
rewrite of notify-templates
2025-03-09 10:00:57 +01:00
mag37
dcbdb5becd minor fixes 2025-03-09 09:57:45 +01:00
mag37
8fc4f41c49 version bump and change notes 2025-03-07 21:11:01 +01:00
mag37
9b0b6137a3 fixed typos 2025-03-07 21:05:58 +01:00
mag37
7ed4286fe7 merged updates from main 2025-03-07 20:47:43 +01:00
mag37
bf1e78d2ff
hotfix changelog 2025-02-26 22:04:05 +01:00
mag37
9fa398e553
Merge pull request #132 from mag37/xargs_hotfix
Made MaxAsync=1 the default - edit to change.
Added -x option to pass a MaxAsync value on runtime.
Made it possible to disable xargs -P-flag by setting MaxAsync=0 or passing -x 0 option.
2025-02-26 21:42:58 +01:00
mag37
9ef2ea7135 versionbump + changenotes 2025-02-26 21:39:33 +01:00
mag37
8c3b899332 async hotfix, defaults to 1 subprocess, added -x option to set custom async value 2025-02-26 21:23:15 +01:00
mag37
8110cd8892
Update README.md 2025-02-25 21:30:41 +01:00
mag37
502a167919
Update README.md 2025-02-25 21:30:20 +01:00
mag37
61f90893ef
async version bump 2025-02-24 22:12:11 +01:00
mag37
229cde0efb
Updated README.md
Added changelog.
Added info about Docker Hub pull limit.
2025-02-24 22:03:20 +01:00
mag37
0c6674ac8e
Merge pull request #128 from Thaurin/parallel_check
Add async checking for updates for improved performance
2025-02-24 21:59:30 +01:00
mag37
3e079e2ec5
Update dockcheck.sh
Added MaxAsync variable.
Added POSIX xargs check.
Rewrote Excludes.
2025-02-24 21:49:19 +01:00
Thaurin
b2d67c9f52 Removed experimental -z flag and old version check code 2025-02-21 17:57:09 +01:00
Thaurin
3aeee837f9 Print entire line on error 2025-02-21 17:54:19 +01:00
Thaurin
408a8b14dd Fix -d parameter not working anymore 2025-02-20 18:48:55 +01:00
Thaurin
a2868ea505 Add error message; increase number of subprocesses 2025-02-20 18:48:55 +01:00
Thaurin
62a3d10b4f Add async checking for updates for improved performance 2025-02-20 18:48:55 +01:00
mag37
210c076968
Merge pull request #130 from mag37/osx_support
Some osx / bsd compatibility changes.
Rewritten the dependency (jq + regctl) install method.
Many thanks to @pshannon-git for testing!
2025-02-19 20:36:42 +01:00
mag37
65e875e860 fixed typo 2025-02-19 20:26:54 +01:00
mag37
3655f5ae8a version bump 2025-02-19 13:36:30 +01:00
mag37
78a7e1137f OSX appname return 2025-02-18 10:07:21 +01:00
mag37
76e6a5c38b
Update dockcheck.sh
typo
2025-02-18 08:15:52 +01:00
mag37
41029f628d
Update dockcheck.sh
indentation error.
2025-02-18 07:59:11 +01:00
mag37
b918844336 reformatting 2025-02-17 22:38:14 +01:00
mag37
27896c18ba squashed multiple dependency downloaders to one function 2025-02-17 22:23:10 +01:00
mag37
06ea7fff6d newline and rephrasing 2025-02-15 13:35:47 +01:00
mag37
e68adb34d0 added info about macos osx 2025-02-15 13:23:42 +01:00
mag37
6bc896b193 typo 2025-02-14 13:01:23 +01:00
mag37
6cba140522 too tired.. forgot fi's 2025-02-13 22:21:53 +01:00
mag37
73050abf10 rewrote regctl download 2025-02-13 22:18:08 +01:00
mag37
d4d89c305c osx/bsd compatibility changes 2025-02-13 21:39:29 +01:00
mag37
c436def448 typo 2025-02-13 21:34:03 +01:00
mag37
96ebe079a4 removed 'not source' message as its optional 2025-02-13 21:28:21 +01:00
mag37
111cb955b1 finalizing new notification structure 2025-02-10 19:46:23 +01:00
mag37
71967277aa new notification structure 2025-02-09 22:01:08 +01:00
mag37
1548b03a9e added else with inclusion of new function, rewrote 2 templates for testing 2025-02-07 20:47:01 +01:00
mag37
bc6a3529c7
Update README.md 2025-02-07 19:34:24 +01:00
mag37
01b9b33751
Merge pull request #124 from mag37/prometheus_addon
Prometheus addon
2025-02-07 19:28:43 +01:00
mag37
9ed2a0bad0 finalized prometheus addon 2025-02-07 19:27:14 +01:00
mag37
43307350ca formatting of header 2025-01-31 23:58:05 +01:00
mag37
b3600f26ac restructure, moved to addon-subdir and split code to sourced snippet 2025-01-31 23:52:10 +01:00
mag37
79def47754
Merge pull request #121 from tdralle/main
Added an export for node_exporter's text file collector to provide metrics to Prometheus
2025-01-31 23:37:24 +01:00
mag37
e6ff634394
versionbump 2025-01-28 21:55:35 +01:00
mag37
6444e18a4f
Merge pull request #122 from mag37/5.3_fixes
local image check changed, Gotify-template fixed
2025-01-28 21:53:50 +01:00
mag37
14872b0471 local image check changed, Gotify-template fixed, version bump 2025-01-28 21:50:02 +01:00
mag37
07ad241e9f removed whale icon and changed redirection to still show errors 2025-01-28 21:08:20 +01:00
Thorsten Dralle
58d53d3aaf Added a node collector to export statistics to prometheus 2025-01-27 20:57:19 +01:00
mag37
15ce226a0a changed local image check to reference ID instead of image-name 2025-01-22 16:07:50 +01:00
mag37
cce5438aca
Update notify_DSM.sh
Ensures DSM GUI refreshes its update-check.
TY @yoyoma2 for the fix.
2024-12-01 20:51:51 +01:00
mag37
be6f5edf52
Update README.md 2024-11-25 15:23:54 +01:00
mag37
99befd6938
hotfix to changenotes.
More important that it shows for older versions than being pretty.
2024-11-24 08:46:04 +01:00
mag37
8a63fd360c hotfix 2024-11-23 14:58:15 +01:00
mag37
d3786d6f75 hotfix 2024-11-23 14:57:39 +01:00
mag37
487cfb2822 typofix jq binary 2024-11-23 14:56:15 +01:00
mag37
b4943df46c
Merge pull request #111 from mag37/dependency_download_rewrite
Dependency download rewrite + jq installer
2024-11-23 12:46:38 +01:00
mag37
8603c8d4b6
Merge branch 'main' into dependency_download_rewrite 2024-11-23 12:46:15 +01:00
mag37
ae66a6f0fd ChangeNote + finalizing fixes 2024-11-23 12:40:58 +01:00
mag37
3ac0521a9b
Changenotes hotfix 2024-11-22 22:52:21 +01:00
mag37
00ae250511 versionbump + jq info 2024-11-22 15:11:49 +01:00
mag37
704387a7fe versionbump + jq info 2024-11-22 15:09:16 +01:00
mag37
1a6826e2ac versionbump + jq info 2024-11-22 15:08:44 +01:00
mag37
a28b9e555f Colorized error messages 2024-11-22 14:32:30 +01:00
mag37
8309b80dc2 cleaned old jq check + fixed some naming 2024-11-22 13:45:45 +01:00
mag37
bbe26a0ac2 changes to jq install logic
Will fall back to static binary if pkgmanager install fails
or no distribution matches.
2024-11-22 13:08:24 +01:00
mag37
d98d052af7 rewrote regctl-download to use new functions 2024-11-22 11:05:16 +01:00
mag37
fbba77dc1f jq downloading functions
Added distribution checker for packagemanager installs.
Added generic static binary downloader.
2024-11-22 11:00:45 +01:00
mag37
09c9faa008
Merge pull request #109 from mag37/feedback_podcheck
jq rewrite and formatting fixes
2024-11-20 08:39:30 +01:00
mag37
17ed46d157
Merge branch 'main' into feedback_podcheck 2024-11-20 08:38:49 +01:00
mag37
d744d51473 jq version bump 2024-11-18 21:13:44 +01:00
mag37
3821c22660 generalized variable name 2024-11-18 21:04:02 +01:00
mag37
5dd42b7336 changed to jq metadata check 2024-11-18 21:01:13 +01:00
mag37
8da2cbe611 Converted to jq metadata check.
Added jq binary check, fixed consistent command -v syntax.
2024-11-18 20:04:08 +01:00
mag37
9937d6bc3f minor readme updates 2024-11-17 20:43:22 +01:00
mag37
5517abb090 formatting to match improvements in podcheck fork 2024-11-17 14:54:28 +01:00
mag37
cb8c23e62d
Update README.md
Added urls to podman fork
2024-11-16 20:39:51 +01:00
mag37
0009adc2cf
Update urls.list
added vaultwarden-backup
2024-11-06 08:49:59 +01:00
mag37
8d39e1b66b new example-file 2024-10-21 20:51:23 +02:00
mag37
ec068dd19a
Fixed typo. 2024-10-14 06:28:35 +02:00
mag37
119932aa19
Update README.md
added Discord to the notifications list.
2024-10-13 22:28:39 +02:00
mag37
a9f2433fab
Merge pull request #104 from mag37/notify-rewrite
Complete rewrite of notify function, all templates adjusted + more.
2024-10-13 17:36:41 +02:00
mag37
18e467274e edited changenotes 2024-10-13 17:11:10 +02:00
mag37
6db92be627 getting ready for merge 2024-10-12 13:13:11 +02:00
mag37
fc47b1313b finalizing formatting and edits 2024-10-10 10:22:17 +02:00
mag37
76d2921719 fixed MSMTP-typo 2024-10-10 09:48:41 +02:00
mag37
2844e54fbd
Merge pull request #102 from thomas-mc-work/patch-1
fix upgly typo which prevents email notifications
2024-10-08 22:05:53 +02:00
Thomas McWork
e0d66cc773
fix upgly typo which prevents email notifications 2024-10-08 21:57:23 +02:00
mag37
071fa4b245 changed regctl verbosity 2024-10-08 09:41:32 +02:00
mag37
cb73025a61 added discord template 2024-10-07 21:31:33 +02:00
mag37
87f1886d28 releasenotes rewritten to array 2024-10-07 21:29:49 +02:00
mag37
ac10a96cc8 all template rewritten, some guesswork 2024-10-07 21:28:31 +02:00
mag37
e5a7a715c6
Merge pull request #99 from lpukatch/release-note-urls
add release note urls
2024-10-05 21:26:31 +02:00
mag37
8a6a1fbec2
Update urls.list 2024-10-05 21:26:07 +02:00
lpukatch
04b0c46366 add release note urls for popular services 2024-10-05 09:36:06 -04:00
mag37
319b43bc1b Added releasenotes-logic to all templates, fix to DSM+smtp 2024-10-05 08:03:33 +02:00
mag37
8b40dce2cd
Merge pull request #97 from mag37/releasenotes
Releasenotes addon
2024-10-04 23:24:15 +02:00
mag37
62b52796f2 removed empty lines 2024-10-04 23:19:41 +02:00
mag37
85ee721cd1 typo 2024-10-04 23:09:45 +02:00
mag37
6de00a2b90 removed releasenotes test script 2024-10-04 23:07:58 +02:00
mag37
a550994659 tweaks + version info 2024-10-04 23:07:01 +02:00
mag37
0e3210b561
added urls.list
Added urls.list to be ignored.
2024-10-04 14:55:43 +02:00
mag37
db4431d40a
Update dockcheck.sh
changed missing url-message.
2024-10-04 14:48:05 +02:00
mag37
9f8c62ed96 first tweaks for a release-notes addition 2024-10-04 14:39:51 +02:00
mag37
827bb7e14a
Update releasenotes.sh
added $ScriptWorkDir prefix to urls.list
2024-10-04 08:05:42 +02:00
mag37
91ff4aaaa7 Added notification release notes url function 2024-10-02 20:44:32 +02:00
mag37
999694985a
Added sponsorlist - section. 2024-09-28 14:24:34 +02:00
mag37
640046668c
added project url to --help 2024-09-28 14:22:09 +02:00
mag37
a79de24bcc Cleanups + info to readme 2024-09-18 16:44:32 +02:00
mag37
f31a886424
Merge pull request #94 from sudo-kraken/patch-1
Create notify_pushover.sh
2024-09-10 06:32:26 +02:00
Joe Harrison
5b31e68f73
Create notify_pushover.sh 2024-09-09 22:57:11 +01:00
mag37
923736c413 version bump+info 2024-08-17 23:00:41 +02:00
mag37
7d825f36c9 Rewrote prune prompt logic, wont prompt if none-interactive flags are used 2024-08-17 22:56:04 +02:00
mag37
29dffbb9b3
Merge pull request #92 from bocan/pre-commit-fixes
style: Add pre-commit checks and code cleanup
2024-08-17 20:39:07 +02:00
Chris Funderburg
588c22afc9
style: Add pre-commit checks and code cleanup
This change adds an optional pre-commit configuration that can be used
to keep the code style clean.  I've also run it across all files and
fixed numerous whitespaces issues.

To use it, if wanted, just clone / pull the repo as normal, go into the
folder and run:

```
pre-commit install
```

From that point on, when running `git commit`, it will run the checks
on any changed files.

Feel free to ignore this PR if you're not interested.
2024-08-17 08:50:39 -04:00
mag37
39c69b7648
Update README.md 2024-07-26 07:54:46 +02:00
mag37
35e33b3997
Release info + notification edits. 2024-07-24 20:49:23 +02:00
mag37
a615d759ad
Version bump. 2024-07-24 20:46:23 +02:00
mag37
df310c8f50
Merge pull request #90 from mag37/smtp
smtp-changes, deprecate ssmtp, suggest msmtp
2024-07-24 20:41:25 +02:00
mag37
b1448fbb95 smtp-changes, deprecate ssmtp, suggest msmtp 2024-07-24 12:18:23 +02:00
mag37
de67cab998
Merge pull request #88 from yoyoma2/main
zero configuration DSM notification emails
2024-07-02 18:29:53 +02:00
yoyoma2
608c218281 zero configuration DSM notification emails 2024-07-02 11:56:51 -04:00
mag37
3d122f2b86
Update README.md
Notifications updates
2024-06-21 06:25:06 +02:00
mag37
8e280145b9
Merge pull request #87 from cerealconyogurt/home
Create Gotify Template.
2024-06-21 06:16:22 +02:00
cerealconyogurt
da389a04e7 Create notify_gotify.sh
adding Gotify template
2024-06-20 22:05:10 -04:00
mag37
25563d16b6
typo 2024-06-16 23:02:57 +02:00
mag37
4917c97076
Merge pull request #84 from mag37/busyfix
Compat fixes for busyboxs timeout.
2024-06-16 19:39:22 +02:00
mag37
33fc647cb1 compat.changes due to busybox 2024-06-16 19:37:18 +02:00
mag37
abec27c38a potential busybox fix 2024-06-16 07:51:32 +02:00
mag37
082b0f4c7c
Merge pull request #82 from mag37/tfix
compat-fixes for timeout and array sorting.
2024-06-12 20:54:30 +02:00
mag37
8521280070 compat-fixes to arrays 2024-06-12 20:50:10 +02:00
mag37
0aac94f27c bugfix non coreutils 2024-06-10 21:09:04 +02:00
mag37
730dba5c3d
version bump - bugfix 2024-06-08 19:44:14 +02:00
mag37
f8455d3787
bugfix for non amd64/arm64 arch.
added --foreground to timeout.
2024-06-08 19:43:12 +02:00
mag37
bbe9164554
versionbump 2024-06-03 22:53:10 +02:00
mag37
5d86c79710
Update dockcheck.sh
versionbump for fix
2024-06-03 22:50:07 +02:00
mag37
b0f8431dbf
Update dockcheck.sh
timeout default fix
2024-06-03 22:49:14 +02:00
mag37
331d2cc5a7
Merge pull request #79 from mag37/timeout
Timeout @ registry check
2024-06-03 22:24:57 +02:00
mag37
35f460ed61 timeout info 2024-06-03 22:19:07 +02:00
mag37
aab63901d0 Added registry check timeout 2024-06-03 22:15:08 +02:00
mag37
5e53fabbf6
Merge pull request #76 from silverbios/HTTP-Method-Synapse
Update HTTP method in notify_matrix.sh
2024-04-29 13:18:28 +02:00
Alireza
8b3926fd5d
Update notify_matrix.sh
Change the HTTP method from PUT to POST because in recent versions, only POST allowed from synapse server.
2024-04-29 13:32:30 +03:30
mag37
049413cf5a
quickfix
Omitting error during git dir check.
2024-04-29 11:18:21 +02:00
mag37
b1b7f048a3
Update README.md 2024-04-24 19:46:49 +02:00
mag37
361e98c378
versionbump 2024-04-24 19:45:14 +02:00
mag37
d1ad0c68f6
Merge pull request #74 from mag37/cleanwork
cleanups, bugfixes
2024-04-24 19:42:27 +02:00
mag37
76697bc281 Re-formatted compose and env file checks.
Clearing bug for multi-env-container which would break.
Accounted for rare compose-path formatting which would break.
2024-04-22 21:12:00 +02:00
mag37
86649fb0fe re-written sorting of arrays 2024-04-22 21:08:02 +02:00
mag37
80f7dd9b82 removed unused var, cleaned prints 2024-04-22 21:02:13 +02:00
mag37
959f636152
Update README.md 2024-03-31 20:41:38 +02:00
mag37
d1bf9256fa
added topic
Added topic variable, set to 0 if not used.
2024-03-27 21:52:02 +01:00
mag37
5513e13109
Update README.md 2024-03-27 21:49:23 +01:00
mag37
f0b2f7eab7
added matrix. 2024-02-11 16:13:23 +01:00
mag37
44a90d5e62
Merge pull request #69 from silverbios/main
Added Matrix-Synapse notification Template
2024-02-10 18:36:23 +01:00
Alireza
c63643dde8
Update Example URL 2024-02-10 21:01:42 +03:30
Alireza
b2767864ab
update comments 2024-02-10 20:55:32 +03:30
Alireza
c09e813aad
Update notify_matrix.sh
Fix Msgbody variable syntax
2024-02-10 20:47:36 +03:30
Alireza
0b52dd50b6
Create notify_matrix.sh
add notification template for matrix-synapse
2024-02-10 03:03:07 +03:30
mag37
b86df76fb6
tidying some
Rephrased and reordered readme.

Removed "coded by human" - I cant know what contributors use :)
2024-02-04 21:15:21 +01:00
mag37
b8450aa774
added telegram 2024-02-02 21:39:00 +01:00
mag37
aa9421adda
Merge pull request #68 from mag37/selfup_cleanup
selfupdate rework, -v option, syntax cleanup
2024-02-02 21:27:43 +01:00
mag37
f853bfd318
typos 2024-02-02 21:21:56 +01:00
mag37
292b3e1a32 Version bump + readme 2024-02-02 21:18:19 +01:00
mag37
4c26768374 Added -v option, prints version 2024-02-02 20:52:01 +01:00
mag37
b7f8b67232
Merge pull request #65 from Nionor/main
Added Telegram template.
2024-02-02 20:47:42 +01:00
Nionor
a63a509bd2
Add files via upload
Added Telegram template.
2024-02-02 16:00:04 +01:00
mag37
5ed3b90ca4 syntax cleanup 2024-02-01 20:19:04 +01:00
mag37
78d11d1b37 Self update rework
Now just y/n and checking if it's the right git directory, else
curl/wget.
2024-01-31 21:33:14 +01:00
mag37
dfe6cf3e08
arithmetic formatting 2024-01-28 20:08:17 +01:00
mag37
3bc7352b54 Bugfix zerodivision -s option 2024-01-28 15:43:33 +01:00
mag37
1470055329
Merge pull request #62 from mag37/env-rework
Reworked --env-file logic.
2024-01-27 09:41:41 +01:00
mag37
904cd508d1 --env-file version bump 2024-01-27 09:39:37 +01:00
mag37
8ee1366505 typo 2024-01-26 21:53:15 +01:00
mag37
c063b09003 reworked --env-file logic 2024-01-26 20:45:32 +01:00
mag37
ea096b5dbc
Merge pull request #58 from thomas-mc-work/patch-1
modified update notification
2024-01-24 22:17:37 +01:00
Thomas McWork
038a30b628
add colors to version update notice 2024-01-24 21:28:53 +01:00
Thomas McWork
24d82d74b3
modified update notification
Slightly changed the notation of the local/latest version to simplify the visual impression. But it's a matter of taste.
2024-01-24 21:22:49 +01:00
mag37
8ecc354663
Update README.md
link formatting
2024-01-24 19:49:41 +01:00
mag37
4a2daa9899
Merge pull request #57 from mag37/new_labels-force
Labels support and -f force option.
2024-01-24 19:44:57 +01:00
mag37
ae8a232a1a
Merge branch 'main' into new_labels-force 2024-01-24 19:44:29 +01:00
mag37
abbb924867 labels and -f option 2024-01-24 19:37:15 +01:00
mag37
05d21a707a added readme about labels 2024-01-21 20:30:05 +01:00
mag37
4817d75d94 pushbullet template version bump. 2024-01-21 20:30:05 +01:00
mag37
32f6d428d3 pushbullet info 2024-01-21 20:30:05 +01:00
mag37
4a8afde790 Added pushbullet template.
Suggested and contributed by [@arpanghosh8453](https://github.com/arpanghosh8453)
2024-01-21 20:30:05 +01:00
mag37
ae53fe2cc7
pushbullet template version bump. 2024-01-20 10:38:11 +01:00
mag37
722fb90ce2
pushbullet info 2024-01-20 10:36:41 +01:00
mag37
18947a462d Added pushbullet template.
Suggested and contributed by [@arpanghosh8453](https://github.com/arpanghosh8453)
2024-01-20 10:33:32 +01:00
mag37
0887025412 Added functionality for labels and force restarts. 2024-01-18 20:59:55 +01:00
mag37
e331dda080 Added a simple progress bar 2024-01-17 20:26:18 +01:00
mag37
5b87072b11 version bump, ntfy.sh and errors on registry fail 2024-01-15 20:53:51 +01:00
mag37
6b2af36841 Added ntfy.sh template 2024-01-15 20:47:51 +01:00
mag37
bad7bfdf86 Added ntfy.sh template 2024-01-15 20:47:04 +01:00
mag37
2a604ff8bd Added error messages on registry fail. 2024-01-15 20:27:45 +01:00
mag37
e1b26fb772
cleanup.md 2024-01-14 20:32:46 +01:00
mag37
9e4b445c50
Added url 2024-01-13 20:34:34 +01:00
mag37
55323b7562 added apprise quickstart 2024-01-13 19:53:50 +01:00
mag37
51c8a7a05d added apprise quickstart + images 2024-01-13 19:45:03 +01:00
mag37
6a3c78d907 cleanup 2024-01-07 14:26:35 +01:00
mag37
4b6173683b
Merge pull request #55 from freekngdom/main
ignore the auto-installed regctl
2024-01-07 08:28:06 +01:00
Eric
fb4e9fd521 ignore the auto-installed regctl 2024-01-06 16:17:37 -08:00
mag37
e00bfb1d21
typo 2024-01-06 20:52:03 +01:00
mag37
77d7340e5b
Apprise & New option -i
Added new option -i, inform - to send notifications.
2024-01-06 20:45:34 +01:00
mag37
82f6442933 modified apprise-notify 2024-01-06 20:33:21 +01:00
mag37
6c37e255fb formatting 2024-01-06 17:30:00 +01:00
mag37
61e247f0ea formatting 2024-01-06 17:29:35 +01:00
mag37
b540ffa119 fixed link 2024-01-06 08:44:07 +01:00
mag37
edf6d5bd72 added architecture workaround 2024-01-06 08:40:26 +01:00
mag37
92ba4a184e edits 2024-01-06 07:47:41 +01:00
mag37
47ebb75691 Added option -i 2024-01-06 00:11:33 +01:00
mag37
3053304356 fixes 2024-01-05 21:51:43 +01:00
mag37
63b35ab2c3 formatting 2024-01-05 21:49:36 +01:00
mag37
45dbe65c28 typos 2024-01-05 21:47:14 +01:00
mag37
ae5cd4d86e Updated README 2024-01-05 21:45:13 +01:00
mag37
58bb55c79a added .gitignore to safeguard users custom notify.sh 2024-01-05 21:17:30 +01:00
mag37
fe31aed33c Edited generic template 2024-01-05 20:55:08 +01:00
mag37
5485a3b2cf Added apprise notify template. 2024-01-05 20:42:53 +01:00
mag37
94fd34478b Added ssmtp notify template. 2024-01-05 20:42:25 +01:00
mag37
8e92a3a4cb New updates to readme 2024-01-03 21:56:07 +01:00
mag37
9ead0feb9f
Merge pull request #51 from yoyoma2/main
add a generic sample notification and a DSM notification addon
2024-01-03 21:42:57 +01:00
yoyoma2
2e620cd2c0 final tweaks to notification addons 2024-01-03 12:41:18 -05:00
mag37
fc7b2888f1
Update notify_generic.sh
Added disclaimer.
2024-01-03 11:07:08 +01:00
mag37
e15a8e9dbf
Update notify_DSM.sh
Added disclaimer + some more info
2024-01-03 11:06:37 +01:00
mag37
342ff271ca
Update notify_DSM.sh
Added the passed array to a variable.
Created printable string with newlines.
2024-01-03 11:01:41 +01:00
mag37
3f56af0c8a
Update notify_generic.sh
Set the passed in array to a variable.
Made a printable string with newlines.
Edited formatting some.
2024-01-03 10:57:00 +01:00
yoyoma2
ab3aaf1140 add a sample a DSM notification addon 2024-01-01 13:46:09 -05:00
mag37
80a81f59d6
Merge pull request #50 from mag37/printf_rework
Added option -m, monochrome mode + cleaning.
2023-12-23 20:54:45 +01:00
mag37
ba3f436ac9 Added -m option, monochrome mode. 2023-12-23 20:52:04 +01:00
mag37
24438124eb cleaned up some variable names and help-section 2023-12-23 20:47:23 +01:00
mag37
e39ea0748f
Update dockcheck.sh
Added -m, Monochrome Mode.
2023-12-19 22:52:11 +01:00
mag37
ab30f22343 rework of the printf's color escape codes 2023-12-19 20:24:34 +01:00
mag37
d39badea36
Upd README.md 2023-12-14 20:55:55 +01:00
mag37
9a1f2aa7c7
Upd README.md 2023-12-14 20:44:53 +01:00
mag37
15d3a96b2c
Merge pull request #47 from mag37/agecheck
datecheck merge.
2023-12-14 13:28:39 +01:00
mag37
fbd27d6e37 Changed datecheck logic.
Printing how old in days a skipped "too new" image is.
2023-12-14 09:06:19 +01:00
mag37
7bd5f87ed1
Upd README 2023-12-13 20:16:20 +01:00
mag37
e24cba0078 upd readme 3.0 2023-12-13 19:59:58 +01:00
mag37
886379dc7d v3.0 big commit, added date-check function 2023-12-13 19:50:58 +01:00
mag37
488669b99a
Update README.md
added recent change info.
2023-12-09 10:59:27 +01:00
mag37
e20fdd9e85 regctl logic changes, check and download will match the scripts workdir. 2023-12-09 10:56:22 +01:00
mag37
3d1c424d23
Update dockcheck.sh
added a regctl-check for when regctl is within the pwd.
(as suggested by @yoyoma2 )
2023-11-19 20:20:05 +01:00
mag37
132fda3388
Update README.md 2023-08-29 20:42:00 +02:00
mag37
cc9b3b0828
Update README.md 2023-08-28 21:31:18 +02:00
mag37
29c2c5e961
Merge pull request #41 from elchanly/elchanly-patch-1
Update dockcheck.sh to include stopped containers
2023-08-28 21:26:12 +02:00
mag37
5dc9af9874
Update dockcheck.sh
Did some changes to the logic, cleaned some whitespace.
2023-08-28 21:24:23 +02:00
elchanly
f91ca08d54
Update dockcheck.sh to include stopped containers
as suggested in reddit, this is proposed to include stopped containers
take into account im not skilled in this programming language but i wanted to contribute.
2023-08-21 23:56:03 +02:00
mag37
9a246b52c4
Merge pull request #39 from mag37/fixing
Fixes `dc_brief.sh` to only exclude exact matches.
2023-07-11 23:33:02 +02:00
mag37
0c33f581f7 Removed old exclude-logic 2023-07-11 23:30:46 +02:00
mag37
b492aacf0f minor edits 2023-07-11 23:11:14 +02:00
mag37
f498138d4b Added recent "exclude containers"-bugfix to the dc_brief.sh 2023-07-11 23:05:34 +02:00
mag37
6a3198eb08
Update dockcheck.sh
patched the self_update logic to respect (and skip interaction) if `-y|a` flag is passed.
2023-06-28 18:03:56 +02:00
mag37
48bfea9fbf
Merge pull request #36 from mag37/dev1
Fixes the Exclude-option to only exclude exact matches. 
Formatting: Added counter and info message on current update.
2023-06-27 20:45:12 +02:00
mag37
f2fc5a4d34 Updated: 2.4 info 2023-06-27 19:45:21 +02:00
mag37
f0940e81ec Fixes to the Exclude-option to only exclude exact matches, instead of
wildcarding and excluding by mistake.

Added a counter + message about which container updating.
2023-06-27 19:34:20 +02:00
mag37
a25e648557 Changes to the Exclude-option to only exclude exact matches. 2023-06-21 20:09:31 +02:00
mag37
0e2bdc94ad
Update README.md 2023-03-08 12:48:36 +01:00
mag37
19eb57077f selfupd-edit
Changed to if git fails, it'll return to ask for curl/manual.
2023-03-05 21:59:08 +01:00
mag37
1f28c9c144
Update README.md 2023-03-05 21:41:08 +01:00
mag37
0d6da201b7
Update dockcheck.sh
changed url
2023-03-05 21:25:22 +01:00
mag37
ecb1256fbb
Merge pull request #32 from mag37/selfupdate
selfupdate func
2023-03-05 21:24:03 +01:00
mag37
afe97c9de5
rdy for main
All in all: 
- Added a self update function, calling either a curl or a git function to update the script.
- Added a dirty changenote-message, will look into improvements later to not curl twice.
2023-03-05 21:19:54 +01:00
mag37
9b6396f6de cleaning
quoting, added env-file check.
2023-03-05 21:13:23 +01:00
mag37
5e58abd8e9
Update dockcheck.sh 2023-03-05 20:45:43 +01:00
mag37
3d7340c91c added changenotes
Addded a dirty way to write out latest changes.
Will try to improve on this later.
2023-03-05 20:44:05 +01:00
mag37
1decbd77b5 cleaning
Just minor cleaning, rearranging
2023-03-05 14:18:57 +01:00
mag37
bcc0c63413 rearranged functions
Moved up choosecontainer-function to the rest of the functions.
Cleaning.
2023-03-05 14:08:56 +01:00
mag37
4a2bc2dded Cleaning
Quoted a variable, reformatted a message
2023-03-05 13:50:28 +01:00
mag37
fd67e0dff1
Update dockcheck.sh 2023-03-04 21:35:47 +01:00
mag37
0fb95ea616
Update dockcheck.sh 2023-03-04 21:28:25 +01:00
mag37
e4cf54c166
Update dockcheck.sh 2023-03-04 21:27:18 +01:00
mag37
e677d8513b
Update dockcheck.sh 2023-03-04 21:25:32 +01:00
mag37
d366d4680c
Update dockcheck.sh 2023-03-04 20:31:38 +01:00
mag37
76337ee326
Update dockcheck.sh 2023-03-04 20:31:20 +01:00
mag37
6cd90e4597
Update dockcheck.sh 2023-03-04 20:27:13 +01:00
mag37
08ae7a8d23
Update dockcheck.sh 2023-03-04 20:21:31 +01:00
mag37
062c62d071
Update dockcheck.sh 2023-03-04 20:06:41 +01:00
mag37
13549c2018
Update dockcheck.sh 2023-03-04 20:06:08 +01:00
mag37
9094bedfd3
Update dockcheck.sh 2023-03-04 20:05:27 +01:00
mag37
0d4eb4365c
Update dockcheck.sh 2023-03-04 20:02:30 +01:00
mag37
ac77470dee
Update dockcheck.sh 2023-03-04 20:00:20 +01:00
mag37
ea7a1cd171 Added selfupdating
Added a selfupdating function.
Fixed a forgotten variable (compose-array).
2023-03-04 19:56:26 +01:00
mag37
40910d83b6
Delete example.gif 2023-03-04 09:58:55 +01:00
mag37
d7cc363931
Update README.md 2023-03-04 09:57:31 +01:00
mag37
4f8d6289c2
Update README.md
added donation buttons
added logo by [booYah187](https://github.com/booYah187)
2023-03-04 09:56:16 +01:00
mag37
79febc7356
moved examples.gif 2023-03-04 09:52:46 +01:00
mag37
8acff25f0d
added logo
created by https://github.com/booYah187
2023-03-04 09:50:29 +01:00
mag37
2391d6916b
Create temp 2023-03-04 09:47:53 +01:00
mag37
e864edc40e
Update README.md 2023-03-01 21:02:55 +01:00
mag37
aac065022c
urgent
Should not edit on production! Too stressful. Another mistake corrected.
2023-03-01 20:52:17 +01:00
mag37
3e60468d47
urgent
and another fix.
2023-03-01 20:43:06 +01:00
mag37
09c1b769ca
urgent fix
too stressed.. typo
2023-03-01 20:39:02 +01:00
mag37
5392c48a57
URGENT
Added info about breakage.
2023-03-01 20:34:29 +01:00
mag37
cc72411de4
troubleshooting
Created for troubleshooting, use if you suspect dockcheck screwed up with errors to easily review your running configs. 
Restart the faulty contianer manually from the compose-file!
2023-03-01 20:27:47 +01:00
mag37
026d5296f8
urgent fix
Screwed up the array with compose-files! It just continued filling up on each loop, should be reset at each loop reset.
Will add info to readme.
2023-03-01 19:52:30 +01:00
mag37
f6e2d50949
+Recent Changes
Added a "Recent Changes" - section up top to make it easier to see what's new with versions.
2023-02-26 23:11:40 +01:00
mag37
432edbfa75
Merge pull request #30 from mag37/testing
multi-compose + exclude
2023-02-26 13:19:37 +01:00
mag37
f233cf3b41 Added info 2023-02-26 13:16:54 +01:00
mag37
7630a95442
Merge pull request #29 from Palleri/patch-2
Added visual "new line" after update check.
2023-02-26 11:58:09 +01:00
Palleri
c7304093bd
Added visual "new line" after update check. 2023-02-26 11:24:46 +01:00
mag37
d877a86292 Added exclude-opt
Added options to allow for exclude option to be used
2023-02-26 08:03:15 +01:00
mag37
191d27097d Added exclude-option
Added option to exclude specific containers, full names separated by
comma. `dockcheck.sh -e heimdall,glances`
2023-02-26 07:49:57 +01:00
mag37
4ddb54770e multi-compose fix
Added a hacky fix for multi-compose containers, for example using overrides in
custom directories or multiple override.yml
2023-02-25 10:32:22 +01:00
mag37
c50312dc83
known: profile and multicompose
Added info about known issues related to profiles and multi-compose environments.
2023-02-25 07:56:58 +01:00
mag37
c47c703ce9
added shebang
Forgot about the shebang..
2023-02-23 19:00:35 +01:00
mag37
372e79a12c
bugsquash
Added info about pull not respecting image-tags.
2023-02-23 13:18:37 +01:00
mag37
5c2cf75b21
vers.bump - fix breakage
Fixed a breaking error - pulling new images did not use the actual image:tag, but only defaulted to latest.
Hence bumping the version to alert new users to pull the latest.
2023-02-23 13:17:07 +01:00
mag37
e754450300 fixed :tag for pull
Pull did not take tag in account when pulling. Quickfixed it to use the
actual tag of the image of the running container when pulling.
2023-02-23 13:05:06 +01:00
mag37
6ff15f6d97
Update README.md 2023-02-21 21:10:38 +01:00
mag37
cb65d78075
Create dc_brief.sh
A brief version of the script, just checking and listing all running containers with updates / no updates / errors.
2023-02-21 21:08:50 +01:00
mag37
955796c47a
Delete dupc_function.sh 2023-02-21 21:04:01 +01:00
mag37
263966dc4a
Update README.md
added .env to buglist.
2023-02-20 15:15:52 +01:00
mag37
e877cd826d
Merge pull request #25 from mag37/testing_019
added fix for .env
2023-02-20 12:08:34 +01:00
mag37
b78485ed8b version bump
Changed version number to merge with main, also added some margins to
the curl for version.
2023-02-20 11:35:51 +01:00
mag37
fa8edd0443 env-file check, colors
Made a check to see if the compose is started with a env-file, if so use
that file with the compose-command.
2023-02-19 14:21:22 +01:00
mag37
dd6a56da1b
new example 2023-02-16 13:51:22 +01:00
mag37
7f30126678
Delete 018vid.gif 2023-02-16 13:50:12 +01:00
mag37
c61dd58858
new example 2023-02-16 13:49:58 +01:00
mag37
61825370dd
Delete example.gif 2023-02-16 13:49:22 +01:00
mag37
687551ce6a
Update README.md 2023-02-15 17:01:44 +01:00
mag37
3b854eaf65
Merge pull request #23 from nnmalex/main
Fix update check
2023-02-15 16:19:10 +01:00
Alex
3ce04ddd5d
Update dockcheck.sh
With longer first line the version check doesn't work correctly any longer.
2023-02-15 15:17:23 +00:00
mag37
eeb3887879
Merge pull request #22 from mag37/testing_018
license,extra checks,reworks
2023-02-15 13:48:18 +01:00
mag37
c105c705c6
GPLv3 2023-02-15 13:19:57 +01:00
mag37
42f1daacec
Create LICENSE 2023-02-15 13:18:51 +01:00
mag37
95a603cdc3 chooseRework,pruneAdd,regctlChecks
Fixes:
- Checks if curl/wget exist to not get an empty `regctl` binary.
    - Extra check if `regctl` binary is functional before continuing.
- changed shebang to `#!/usr/bin/env bash` for portability.
- General cleaning. (y/n checks and space saving)

New:
- Rework of the `choosecontainers` function
    - `[aA]` to update ALL (was `0` before and part of the list/array)
    - numbers starting from 1 (instead of 0)
    - will prompt for new choice if picking numbers/letters out of bound.

- `docker prune` option after completed updates.
    - additionally a`-p` flag for automatic update+prune, eg `./dockcheck.sh -yp`

- Added [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0-standalone.html) license.
2023-02-15 13:16:31 +01:00
mag37
791933ffaa Update readme 2023-02-15 13:14:05 +01:00
mag37
607ead565c
code cleaning
Missed two comments, removed.
2023-02-12 20:55:21 +01:00
mag37
1490c97a87
Merge pull request #17 from mag37/dev
## Code Cleaning
- printf formatting fixes
- read formatting fixes
- find/replace instead of sed
- directly check error on regctl instead of indirectly 
- safer array-checks (not expanding without index)
2023-02-12 19:47:15 +01:00
mag
53f8e8cdf9 code cleaning
printf formatting fixes
read formatting fixes
find/replace instead of sed
directly check error on regctl instead of indirectly
safer array-checks (not expanding without index)
2023-02-12 19:40:42 +01:00
mag37
b955649a5d
BugSquash
Added note about fixed `${PWD}` breakage.
2023-02-12 06:32:10 +01:00
mag37
a2ffff2df2
BugSquash
Added note about fixed `${PWD}` breakage.
2023-02-12 06:30:18 +01:00
mag37
b9cfa851bd
cd to compose-file extras
Added some error handling of the new cd-line, if the cd breaks for some reason that container will be skipped with a message.
2023-02-11 23:46:56 +01:00
mag37
555e472528
Merge pull request #16 from F0x06/relative_path_cd
cd to the compose-file directory before bringing the container up.
2023-02-11 23:41:56 +01:00
F0x06
0dfc8ca04f Make sure to be in the same folder as 'docker-compose.yml' file before pull & up -d 2023-02-11 21:18:55 +01:00
mag37
96a8eda1cb
Merge pull request #15 from mag37/run_rework
Did some work to allow for selecting containers which are not docker compose -containers.

These containers will get skipped by default but the user have the option -r to allow updates of docker run images. This is not recommended - as you'd still need to stop and recreate the container manually to use the new image.
2023-02-10 21:25:07 +01:00
mag37
aa4c19fead
Update README.md
Added info about the docker run changes.
2023-02-10 21:17:15 +01:00
mag37
0bebe041df
Delete dockcheck_docker-run_ver.sh
Obsolete due to main script rework.
2023-02-10 21:06:53 +01:00
mag37
f1f50c8301
docker_run fixes
Wont break if one of the chosen containers are created with docker run.
Added checks if a container is started with docker run, then skipping (default) or updating the image for manual docker run recreation (flag -r required).
2023-02-10 21:06:12 +01:00
mag37
3faada230a
Update README.md 2023-02-09 21:22:30 +01:00
44 changed files with 3724 additions and 344 deletions

11
.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
# ignore users custom notify.sh
/notify*.sh
/urls.list
# ignore user config
/dockcheck.config
# ignore the auto-installed regctl
regctl
# ignore snooze file
snooze.list
# ignore updates file
updates_available.txt

11
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,11 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-yaml
- id: check-added-large-files
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- id: end-of-file-fixer
- id: mixed-line-ending
args: ['--fix=lf']

674
LICENSE Normal file
View file

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

450
README.md
View file

@ -1,87 +1,425 @@
# dockcheck
### A script checking updates for docker images **without the need of pulling** - then optionally auto-update chosen containers.
<p align="center">
<img src="extras/dockcheck_colour.png" width="300" title="dockcheck">
</p>
<p align="center">
<img src="https://img.shields.io/badge/bash-4.3-green?style=flat-square&logo=gnubash" alt="bash">
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://img.shields.io/badge/license-GPLv3-red?style=flat-square" alt="GPLv3"></a>
<img src="https://img.shields.io/github/v/tag/mag37/dockcheck?style=flat-square&label=release" alt="release">
<br>
<a href="https://ko-fi.com/mag37"><img src="https://img.shields.io/badge/-Ko--fi-grey?style=flat-square&logo=Ko-fi" alt="Buy me a Coffee"></a>
<a href="https://liberapay.com/user-bin-rob/donate"><img src="https://img.shields.io/badge/-LiberaPay-grey?style=flat-square&logo=liberapay" alt="LiberaPay"></a>
<a href="https://github.com/sponsors/mag37"><img src="https://img.shields.io/badge/-Sponsor-grey?style=flat-square&logo=github" alt="Github Sponsor"></a>
<a href="https://www.paypal.com/donate/?business=P2V5MCWRGCNBG&no_recurring=0&currency_code=SEK"><img src="https://img.shields.io/badge/-PayPal-grey?style=flat-square&logo=paypal" alt="PayPal donation"></a>
</p>
<h2 align="center">CLI tool to automate docker image updates or notifying when updates are available.</h2>
<h3 align="center">selective updates, include/exclude containers, image backups, custom labels, notification plugins, prune when done etc.</h3>
<h4 align="center">:whale: Docker Hub pull limit :chart_with_downwards_trend: not an issue for checks only for actual pulls - <a href="#whale-docker-hub-pull-limit-chart_with_downwards_trend-not-an-issue-for-checks-but-for-actual-pulls">read more</a></h4>
<h5 align="center">For Podman - see the fork <a href="https://github.com/sudo-kraken/podcheck">sudo-kraken/podcheck</a>!</h4>
With the help of [`regctl`](https://github.com/regclient/regclient). This is just a concept for inspiration, use with care.
___
## Dependencies:
Running docker (duh) and compose, either standalone or plugin.
`regctl` by [regclient](https://github.com/regclient/regclient) (will ask to download `regctl` if not in `PATH` or `PWD`)
## Changelog
- **v0.7.6**:
- New:
- Added Bark notify-template.
- Fixes:
- Sanitized message for Matrix notification.
- Fixed hostname fallback for notifications.
- Clenaed up README.md some.
- Sorted and clarified `default.config` - migrate your settings manually (optional).
- **v0.7.5**:
- 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 `-B`.
- Fixes:
- Bugfix for `-s` *Stopped* to not recreate stopped containers after update.
- **v0.7.4**:
- Added new option `-R`:
- Will skip container recreation after pulling images.
- Allows for more control and possible pipeline integration.
- Fixes:
- Bugfix for *value too great* error due to leading zeroes - solved with base10 conversion.
- Clean up of some legacy readme sections.
___
![](https://github.com/mag37/dockcheck/blob/main/example.gif)
![example.gif](extras/example.gif)
## `dockcheck.sh`
```bash
```shell
$ ./dockcheck.sh -h
Syntax: dockcheck.sh [OPTION] [part of name to filter]
Example: dockcheck.sh -a ng
Syntax: dockcheck.sh [OPTION] [comma separated names to include]
Example: dockcheck.sh -y -x 10 -d 10 -e nextcloud,heimdall
Options:
-h Print this Help.
-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.
-f Force stop+start stack after update. Caution: restarts once for every updated container within stack.
-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.
-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.
-M Prints custom releasenote urls as markdown (requires template support).
-n No updates, only checking availability.
-p Auto-Prune dangling images after update.
-r Allow checking/updating images created by `docker run`, containers need to be recreated manually.
-R Skip container recreation after pulling images.
-s Include stopped containers in the check. (Logic: docker ps -a).
-t N Set a timeout (in seconds) per container for registry checkups, 10 is default.
-u Allow automatic self updates - caution as this will pull new code and autorun it.
-v Prints current version.
-x N Set max asynchronous subprocesses, 1 default, 0 to disable, 32+ tested.
```
Basic example:
```bash
### Basic example
```shell
$ ./dockcheck.sh
. . .
[##################################################] 5/5
Containers on latest version:
glances
homer
Containers with updates available:
0) ALL
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, [q] to quit: 1,3
Enter number(s) separated by comma, [a] for all - [q] to quit: 1,2
```
Then it proceedes to run `pull` and `up -d` on every container with updates.
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.
### :beetle: Squashed Bugs:
- ~~No options for running without updates or auto update.~~
- ~~No filter to check only specific containers.~~
- ~~Faulty registry checkups stopped the updates completely.~~
- ~~No clear checks to skip containers producing errors.~~
- ~~Multi-digest images didn't correctly check with registry, giving false positives on updates.~~
- ~~Not working with filenames other than `docker-compose.yml`~~
- ~~Lists are not alphabetically sorted (due to stacks and other parameters)~~
- ~~Old `docker-compose` binary-check sometimes returned false error~~
- ~~Stacks gets updated as whole, even if only one service is chosen.~~
- ~~Path broken occationally (from inspect) - probably due to old docker-compose binary.~~
___
### :hammer: Known issues
- ~~No granular choice of what to update (except initial name filter).~~
- No detailed error feedback (just skip + list what's skipped) .
## Dependencies
## `dockcheck_docker-run_ver.sh`
### Wont auto-update the containers, only their images. (compose is recommended)
Alternative version for people who use `docker run` and no composes.
`docker run` dont support using new images just by restarting a container.
Containers need to be stopped, removed and created again to run on the new image.
- Running docker (duh) and compose, either standalone or plugin. (see [Podman fork](https://github.com/sudo-kraken/podcheck))
- Bash shell or compatible shell of at least v4.3
- POSIX `xargs`, usually default but can be installed with the `findutils` package - to enable async.
- [jq](https://github.com/jqlang/jq)
- User will be prompted to install with package manager or download static binary.
- [regclient/regctl](https://github.com/regclient/regclient) (Licensed under [Apache-2.0 License](http://www.apache.org/licenses/LICENSE-2.0))
- User will be prompted to download `regctl` if not in `PATH` or `PWD`.
- regctl requires `amd64/arm64` - see [workaround](#workaround-for-non-amd64--arm64) if other architecture is used.
## Install Instructions
## `dupc_function.sh`
Function to quickly check for updates on a single contianer or list of containers by name. **Without the need of pulling**.
Preferably placed in `.bashrc` or similar.
Example:
Download the script to a directory in **PATH**, I'd suggest using `~/.local/bin` as that's usually in **PATH**.
For OSX/macOS preferably use `/usr/local/bin`.
```shell
# basic example with curl:
curl -L https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh -o ~/.local/bin/dockcheck.sh
chmod +x ~/.local/bin/dockcheck.sh
# or oneliner with wget:
wget -O ~/.local/bin/dockcheck.sh "https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh" && chmod +x ~/.local/bin/dockcheck.sh
# OSX or macOS version with curl:
curl -L https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh -o /usr/local/bin/dockcheck.sh && chmod +x /usr/local/bin/dockcheck.sh
```
$ dupc ng
Updates available for local_nginx.
nginx_reverse is already latest.
Updates available for paperless-ng.
```
## Also check out a spinoff brother-project [Palleri/dockcheck-web](https://github.com/Palleri/dockcheck-web) for a WebUI-front!
---
## Special Thanks:
:bison: [t0rnis](https://github.com/t0rnis)
:leopard: [Palleri](https://github.com/Palleri)
Then call the script anywhere with just `dockcheck.sh`.
Add preferred `notify.sh`-template to the same directory - this will not be touched by the scripts self-update function.
## Configuration
To modify settings and have them persist through updates - copy the `default.config` to `dockcheck.config` alongside the script or in `~/.config/`.
Alternatively create an alias where specific flags and values are set.
Example `alias dc=dockcheck.sh -p -x 10 -t 3`.
## Notifications
Triggered with the `-i` flag. Will send a list of containers with updates available and a notification when `dockcheck.sh` itself has an update.
`notify_templates/notify_v2.sh` is the default notification wrapper, if `notify.sh` is present and configured, it will override.
Example of a cron scheduled job running non-interactive at 10'oclock excluding 1 container and sending notifications:
`0 10 * * * /home/user123/.local/bin/dockcheck.sh -nix 10 -e excluded_container1`
#### Installation and configuration
Set up a directory structure as below.
You only need the `notify_templates/notify_v2.sh` file and any notification templates
you wish to enable, but there is no harm in having all of them present.
```shell
.
├── notify_templates/
│ ├── notify_DSM.sh
│ ├── notify_apprise.sh
│ ├── notify_bark.sh
│ ├── notify_discord.sh
│ ├── notify_generic.sh
│ ├── notify_gotify.sh
│ ├── notify_HA.sh
│ ├── notify_matrix.sh
│ ├── notify_ntfy.sh
│ ├── notify_pushbullet.sh
│ ├── notify_pushover.sh
│ ├── notify_slack.sh
│ ├── notify_smtp.sh
│ ├── notify_telegram.sh
│ └── notify_v2.sh
├── dockcheck.config
├── dockcheck.sh
└── urls.list # optional
```
- Uncomment and set the `NOTIFY_CHANNELS=""` environment variable in `dockcheck.config` to a space separated string of your desired notification channels to enable.
- Uncomment and set the environment variables related to the enabled notification channels. Eg. `GOTIFY_DOMAIN=""` + `GOTIFY_TOKEN=""`.
It's recommended to only do configuration with variables within `dockcheck.config` and not modify `notify_templates/notify_X.sh` directly. If you wish to customize the notify templates yourself, you may copy them to your project root directory alongside the main `dockcheck.sh` (where they're also ignored by git).
Customizing `notify_v2.sh` is handled the same as customizing the templates, but it must be renamed to `notify.sh` within the `dockcheck.sh` root directory.
#### Snooze feature
Configure to receive scheduled notifications only if they're new since the last notification - within a set time frame.
**Example:** *Dockcheck is scheduled to run every hour. You will receive an update notification within an hour of availability.*
**Snooze enabled:** You will not receive a repeated notification about an already notified update within the snooze duration.
**Snooze disabled:** You will receive additional (possibly repeated) notifications every hour.
To enable snooze uncomment the `SNOOZE_SECONDS` variable in your `dockcheck.config` and set it to the number of seconds you wish to prevent duplicate alerts.
Snooze is split into three categories; container updates, `dockcheck.sh` self updates and notification template updates.
If an update becomes available for an item that is not snoozed, notifications will be sent and include all available updates for that item's category, even snoozed items.
The actual snooze duration will be 60 seconds less than `SNOOZE_SECONDS` to account for minor scheduling or run time issues.
#### Current notify templates
- Apprise (with it's [multitude](https://github.com/caronc/apprise#supported-notifications) of notifications)
- both native [caronc/apprise](https://github.com/caronc/apprise) and the standalone [linuxserver/docker-apprise-api](https://github.com/linuxserver/docker-apprise-api)
- Read the [QuickStart](extras/apprise_quickstart.md)
- [Bark](https://bark.day.app/) - iOS Push notifications.
- [Discord](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) - Discord webhooks.
- [DSM](https://www.synology.com/en-global/dsm) - Synology.
- [Gotify](https://gotify.net/) - a simple server for sending and receiving messages.
- [Home Assistant](https://www.home-assistant.io/integrations/notify/) - Connection to the notify [integrations](https://www.home-assistant.io/integrations/#notifications).
- [Matrix-Synapse](https://github.com/element-hq/synapse) - [Matrix](https://matrix.org/), open, secure, decentralised communication.
- [ntfy](https://ntfy.sh/) - HTTP-based pub-sub notifications.
- [Pushbullet](https://www.pushbullet.com/) - connecting different devices with cross-platform features.
- [Pushover](https://pushover.net/) - Simple Notifications (to your phone, wearables, desktops)
- [Slack](https://api.slack.com/tutorials/tracks/posting-messages-with-curl) - Slack curl api
- SMTP Email with [mSMTP](https://wiki.debian.org/msmtp) (or deprecated alternative [sSMTP](https://wiki.debian.org/sSMTP))
- [Telegram](https://telegram.org/) - Telegram chat API.
Further additions are welcome - suggestions or PRs!
<sub><sup>Initiated and first contributed by [yoyoma2](https://github.com/yoyoma2).</sup></sub>
#### Notification channel configuration
All required environment variables for each notification channel are provided in the default.config file as comments and must be uncommented and modified for your requirements.
For advanced users, additional functionality is available via custom configurations and environment variables.
Use cases - all configured in `dockcheck.config`:
(replace `<channel>` with the upper case name of the of the channel as listed in
`NOTIFY_CHANNELS` variable, eg `TELEGRAM_SKIPSNOOZE`)
- To bypass the snooze feature, even when enabled, add the variable `<channel>_SKIPSNOOZE` and set it to `true`.
- To configure the channel to only send container update notifications, add the variable `<channel>_CONTAINERSONLY` and set it to `true`.
- To send notifications even when there are no updates available, add the variable `<channel>_ALLOWEMPTY` and set it to `true`.
- To use another notification output format, add the variable `<channel>_OUTPUT` and set it to `csv`, `json`, or `text`. If unset or set to an invalid value, defaults to `text`.
- To send multiple notifications using the same notification template:
- Strings in the `NOTIFY_CHANNELS` list are now treated as unique names and do not necessarily refer to the notification template that will be called, though they do by default.
- Add another notification channel to `NOTIFY_CHANNELS` in `dockcheck.config`. The name can contain upper and lower case letters, numbers and underscores, but can't start with a number.
- Add the variable `<channel>_TEMPLATE` to `dockcheck.config` where `<channel>` is the name of the channel added above and set the value to an available notification template script (`slack`, `apprise`, `gotify`, etc.)
- Add all other environment variables required for the chosen template to function with `<channel>` in upper case as the prefix rather than the template name.
- For example, if `<channel>` is `mynotification` and the template configured is `slack`, you would need to set `MYNOTIFICATION_CHANNEL_ID` and `MYNOTIFICATION_ACCESS_TOKEN`.
#### Release notes addon
There's a function to use a lookup-file to add release note URL's to the notification message.
Copy the notify_templates/`urls.list` file to the script directory, it will be used automatically if it's there.
Modify it as necessary, the names of interest in the left column needs to match your container names.
To also list the URL's in the CLI output (choose containers list) use the `-I` option or variable config.
For Markdown formatting also add the `-M` option. (**this requires the template to be compatible - see gotify for example**)
The output of the notification will look something like this:
```shell
Containers on hostname with updates available:
apprise-api -> https://github.com/linuxserver/docker-apprise-api/releases
homer -> https://github.com/bastienwirtz/homer/releases
nginx -> https://github.com/docker-library/official-images/blob/master/library/nginx
...
```
The `urls.list` file is just an example and I'd gladly see that people contribute back when they add their preferred URLs to their lists.
## Asyncronous update checks with **xargs**; `-x N` option. (default=1)
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.config`. To disable the subprocess function set `MaxAsync=0`.
## 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 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:<date>_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 *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 `-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
### Using dockcheck.sh with the Synology DSM
If you run your container through the *Container Manager GUI* - only notifications are supported.
While if running manual (vanilla docker compose CLI) will allow you to use the update function too.
Some extra setup to tie together with Synology DSM - check out the [addons/DSM/README.md](./addons/DSM/README.md).
### Prometheus and node_exporter
Dockcheck can be used together with [Prometheus](https://github.com/prometheus/prometheus) and [node_exporter](https://github.com/prometheus/node_exporter) to export metrics via the file collector, scheduled with cron or likely.
This is done with the `-c` option, like this:
```shell
dockcheck.sh -c /path/to/exporter/directory
```
See the [README.md](./addons/prometheus/README.md) for more detailed information on how to set it up!
<sub><sup>Contributed by [tdralle](https://github.com/tdralle).</sup></sub>
### Zabbix config to monitor docker image updates
If you already use Zabbix - this config will show numbers of available docker image updates on host.
Example: *2 Docker Image updates on host-xyz*
See project: [thetorminal/zabbix-docker-image-updates](https://github.com/thetorminal/zabbix-docker-image-updates)
### Serve REST API to list all available updates
A custom python script to serve a REST API to get pulled into other monitoring tools like [homepage](https://github.com/gethomepage/homepage).
See [discussion here](https://github.com/mag37/dockcheck/discussions/146).
### Wrapper Script for Unraid's User Scripts
A custom bash wrapper script to allow the usage of dockcheck as a Unraid User Script plugin.
See [discussion here](https://github.com/mag37/dockcheck/discussions/145).
## Labels
Optionally add labels to compose-files. Currently these are the usable labels:
```yaml
labels:
mag37.dockcheck.update: true
mag37.dockcheck.only-specific-container: true
mag37.dockcheck.restart-stack: true
```
- `mag37.dockcheck.update: true` will when used with the `-l` option only check and update containers with this label set and skip the rest.
- `mag37.dockcheck.only-specific-container: true` works instead of the `-F` option, specifying the updated container when doing compose up, like `docker compose up -d homer`.
- `mag37.dockcheck.restart-stack: true` works instead of the `-f` option, forcing stop+restart on the whole compose-stack (Caution: Will restart on every updated container within stack).
Adding or modifying labels in compose-files requires a restart of the container to take effect.
## Workaround for non **amd64** / **arm64**
`regctl` provides binaries for amd64/arm64, to use on other architecture you could try this workaround.
Run regctl in a container wrapped in a shell script. Copied from [regclient/docs/install.md](https://github.com/regclient/regclient/blob/main/docs/install.md):
```shell
cat >regctl <<EOF
#!/bin/sh
opts=""
case "\$*" in
"registry login"*) opts="-t";;
esac
docker container run \$opts -i --rm --net host \\
-u "\$(id -u):\$(id -g)" -e HOME -v \$HOME:\$HOME \\
-v /etc/docker/certs.d:/etc/docker/certs.d:ro \\
ghcr.io/regclient/regctl:latest "\$@"
EOF
chmod 755 regctl
```
Test it with `./regctl --help` and then either add the file to the same path as *dockcheck.sh* or in your path (eg. `~/.local/bin/regctl`).
## Docker Hub pull limit :chart_with_downwards_trend: not an issue for checks but for actual pulls
Due to recent changes in [Docker Hub usage and limits](https://docs.docker.com/docker-hub/usage/)
>Unauthenticated users: 10 pulls/hour
>Authenticated users with a free account: 100 pulls/hour
This is not an issue for registry checks. But if you have a large stack and pull more than 10 updates at once consider updating more often or to create a free account.
You could use/modify the login-wrapper function in the example below to automate the login prior to running `dockcheck.sh`.
### Function to auth with docker hub before running
**Example** - Change names, paths, and remove cat+password flag if you rather get
prompted:
```shell
function dchk {
cat ~/pwd.txt | docker login --username YourUser --password-stdin
~/dockcheck.sh "$@"
}
```
## `-r flag` disclaimer and warning
**Wont auto-update the containers, only their images. (compose is recommended)**
`docker run` doesn't support using new images just by restarting a container.
Containers need to be manually stopped, removed and created again to run on the new image.
Using the `-r` option together with eg. `-i` and `-n` to just check for updates and send notifications and not update is safe though!
## Known issues
- No detailed error feedback (just skip + list what's skipped).
- Not respecting `--profile` options when re-creating the container.
- Not working well with containers created by **Portainer**.
- **Watchtower** might cause issues due to retagging images when checking for updates (and thereby pulling new images).
## Debugging
If you hit issues, you could check the output of the `extras/errorCheck.sh` script for clues.
Another option is to run the main script with debugging in a subshell `bash -x dockcheck.sh` - if there's a particular container/image that's causing issues you can filter for just that through `bash -x dockcheck.sh nginx`.
## License
dockcheck is created and released under the [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0-standalone.html) license.
## Sponsorlist
:small_orange_diamond: [avegy](https://github.com/avegy)
:small_orange_diamond: [eichhorn](https://github.com/eichhorn)
:small_orange_diamond: [stepdg](https://github.com/stepdg)
:small_orange_diamond: [acer2220](https://github.com/acer2220)
:small_orange_diamond: [shgew](https://github.com/shgew)
:small_orange_diamond: [jonas3456](https://github.com/jonas3456)
:small_orange_diamond: [4ndreasH](https://github.com/4ndreasH)
:small_orange_diamond: [markoe01](https://github.com/markoe01)
:small_orange_diamond: [mushrowan](https://github.com/mushrowan)
:small_orange_diamond:
___
## The [story](https://mag37.org/posts/project_dockcheck/) behind it. 1 year in retrospect

35
addons/DSM/README.md Normal file
View file

@ -0,0 +1,35 @@
## Using Dockcheck in DSM
Dockcheck cannot directly update containers managed in the Container Manager GUI, but it can still be used to notify you of containers with updates available. There are two ways to be notified, each with their own caveats:
1. Enabling email notifications within the Task Scheduler (_step 6i below_) will send an email that includes the entire script as run. This will not include the `urls.list` links to release notes, but it will show a full list of containers checked, up to date, and needing updates (following the args included in the scheduled task).
2. The [DSM notification template](https://github.com/mag37/dockcheck/blob/main/notify_templates/notify_DSM.sh) will enable Dockcheck to directly send an email when using the `-i` flag. This is most useful when paired with an accurate [urls.list](https://github.com/mag37/dockcheck/blob/next063/notify_templates/urls.list) file, and results in a neat succinct email notification of only containers to be updated.
This is a user preference, and both notifications are not necessary. However, regardless of the notification method, it is necessary to set up a scheduled task to run Dockcheck at a set interval (otherwise it will only run when manually triggered).
## Automate Dockcheck with DSM Task Scheduler:
1. Open Control Panel and navigate to Task Scheduler
2. Create a Scheduled Task > User-defined script
3. Task Name: Dockcheck
4. User: root
5. Schedule: _User Preference_
6. Task Settings:
1. ✔ Send run details by email (include preferred email) _This is the optional step as described above)_
2. User-defined script: `export HOME=/root && cd /path/to/dockcheck && ./dockcheck.sh -n -i -I ` _or other custom args_
8. Click OK, accept warning message
## Set up the DSM Notification template
Copy the [dockcheck/notify_templates/notify_DSM.sh](https://github.com/mag37/dockcheck/blob/main/notify_templates/notify_DSM.sh) to the same directory as where you keep `dockcheck.sh`.
Use as is (uses your default notification email setting) or edit and override manually.
![](./dsm1.png)
![](./dsm2.png)
![](./dsm3.png)
Made with much help and contribution from [@firmlyundecided](https://github.com/firmlyundecided) and [@yoyoma2](https://github.com/yoyoma2).

BIN
addons/DSM/dsm1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
addons/DSM/dsm2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
addons/DSM/dsm3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,61 @@
## [Prometheus](https://github.com/prometheus/prometheus) and [node_exporter](https://github.com/prometheus/node_exporter)
Dockcheck is capable to export metrics to prometheus via the text file collector provided by the node_exporter.
In order to do so the -c flag has to be specified followed by the file path that is configured in the text file collector of the node_exporter.
A simple cron job can be configured to export these metrics on a regular interval as shown in the sample below:
```
0 1 * * * /root/dockcheck.sh -n -c /var/lib/node_exporter/textfile_collector
```
The following metrics are exported to prometheus
```
# HELP dockcheck_images_analyzed Docker images that have been analyzed
# TYPE dockcheck_images_analyzed gauge
dockcheck_images_analyzed 22
# HELP dockcheck_images_outdated Docker images that are outdated
# TYPE dockcheck_images_outdated gauge
dockcheck_images_outdated 7
# HELP dockcheck_images_latest Docker images that are outdated
# TYPE dockcheck_images_latest gauge
dockcheck_images_latest 14
# HELP dockcheck_images_error Docker images with analysis errors
# TYPE dockcheck_images_error gauge
dockcheck_images_error 1
# HELP dockcheck_images_analyze_timestamp_seconds Last dockercheck run time
# TYPE dockcheck_images_analyze_timestamp_seconds gauge
dockcheck_images_analyze_timestamp_seconds 1737924029
```
Once those metrics are exported they can be used to define alarms as shown below
```
- alert: dockcheck_images_outdated
expr: sum by(instance) (dockcheck_images_outdated) > 0
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has {{ $value }} outdated docker images."
description: "{{ $labels.instance }} has {{ $value }} outdated docker images."
- alert: dockcheck_images_error
expr: sum by(instance) (dockcheck_images_error) > 0
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has {{ $value }} docker images having an error."
description: "{{ $labels.instance }} has {{ $value }} docker images having an error."
- alert: dockercheck_image_last_analyze
expr: (time() - dockcheck_images_analyze_timestamp_seconds) > (3600 * 24 * 3)
for: 15s
labels:
severity: warning
annotations:
summary: "{{ $labels.instance }} has not updated the dockcheck statistics for more than 3 days."
description: "{{ $labels.instance }} has not updated the dockcheck statistics for more than 3 days."
```
There is a reference Grafana dashboard in [grafana/grafana_dashboard.json](./grafana/grafana_dashboard.json).
![](./grafana/grafana_dashboard.png)

View file

@ -0,0 +1,382 @@
{
"__inputs": [
{
"name": "DS_PROMETHEUS",
"label": "prometheus",
"description": "",
"type": "datasource",
"pluginId": "prometheus",
"pluginName": "Prometheus"
}
],
"__elements": {},
"__requires": [
{
"type": "grafana",
"id": "grafana",
"name": "Grafana",
"version": "11.4.0"
},
{
"type": "datasource",
"id": "prometheus",
"name": "Prometheus",
"version": "1.0.0"
},
{
"type": "panel",
"id": "table",
"name": "Table",
"version": ""
}
],
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "last_analyze_timestamp"
},
"properties": [
{
"id": "unit",
"value": "dateTimeAsIso"
}
]
},
{
"matcher": {
"id": "byName",
"options": "last_analyze_since"
},
"properties": [
{
"id": "unit",
"value": "s"
},
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 259200
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "images_outdated"
},
"properties": [
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "images_error"
},
"properties": [
{
"id": "custom.cellOptions",
"value": {
"mode": "gradient",
"type": "color-background"
}
},
{
"id": "thresholds",
"value": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
}
}
]
}
]
},
"gridPos": {
"h": 14,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"cellHeight": "sm",
"footer": {
"countRows": false,
"fields": "",
"reducer": [
"sum"
],
"show": false
},
"frameIndex": 1,
"showHeader": true,
"sortBy": []
},
"pluginVersion": "11.4.0",
"targets": [
{
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_analyzed)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"interval": "",
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_analyzed",
"useBackend": false,
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
}
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_outdated)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_outdated",
"useBackend": false
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"disableTextWrap": false,
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_latest)",
"format": "table",
"fullMetaSearch": false,
"hide": false,
"includeNullMetadata": true,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_latest",
"useBackend": false
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "sum by(instance) (dockcheck_images_error)",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_error"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "dockcheck_images_analyze_timestamp_seconds * 1000",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_analyze_timestamp_seconds"
},
{
"datasource": {
"type": "prometheus",
"uid": "${DS_PROMETHEUS}"
},
"editorMode": "code",
"exemplar": false,
"expr": "time() - dockcheck_images_analyze_timestamp_seconds",
"format": "table",
"hide": false,
"instant": true,
"legendFormat": "{{instance}}",
"range": false,
"refId": "dockcheck_images_last_analyze"
}
],
"title": "Dockcheck Status",
"transformations": [
{
"id": "merge",
"options": {}
},
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true,
"__name__": true,
"job": true
},
"includeByName": {},
"indexByName": {
"Time": 0,
"Value #dockcheck_images_analyze_timestamp_seconds": 2,
"Value #dockcheck_images_analyzed": 4,
"Value #dockcheck_images_error": 7,
"Value #dockcheck_images_last_analyze": 3,
"Value #dockcheck_images_latest": 5,
"Value #dockcheck_images_outdated": 6,
"instance": 1,
"job": 8
},
"renameByName": {
"Value #A": "analyze_timestamp",
"Value #dockcheck_images_analyze_timestamp_seconds": "last_analyze_timestamp",
"Value #dockcheck_images_analyzed": "images_analyzed",
"Value #dockcheck_images_error": "images_error",
"Value #dockcheck_images_last_analyze": "last_analyze_since",
"Value #dockcheck_images_latest": "images_latest",
"Value #dockcheck_images_outdated": "images_outdated"
}
}
}
],
"type": "table"
}
],
"schemaVersion": 40,
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "browser",
"title": "Dockcheck Status",
"uid": "feb4pv3kv1hxca",
"version": 17,
"weekStart": ""
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

View file

@ -0,0 +1,28 @@
prometheus_exporter() {
checkedImages=$(($1 + $2 + $3))
checkTimestamp=$(date +%s)
promFileContent=()
promFileContent+=("# HELP dockcheck_images_analyzed Docker images that have been analyzed")
promFileContent+=("# TYPE dockcheck_images_analyzed gauge")
promFileContent+=("dockcheck_images_analyzed $checkedImages")
promFileContent+=("# HELP dockcheck_images_outdated Docker images that are outdated")
promFileContent+=("# TYPE dockcheck_images_outdated gauge")
promFileContent+=("dockcheck_images_outdated ${#GotUpdates[@]}")
promFileContent+=("# HELP dockcheck_images_latest Docker images that are outdated")
promFileContent+=("# TYPE dockcheck_images_latest gauge")
promFileContent+=("dockcheck_images_latest ${#NoUpdates[@]}")
promFileContent+=("# HELP dockcheck_images_error Docker images with analysis errors")
promFileContent+=("# TYPE dockcheck_images_error gauge")
promFileContent+=("dockcheck_images_error ${#GotErrors[@]}")
promFileContent+=("# HELP dockcheck_images_analyze_timestamp_seconds Last dockercheck run time")
promFileContent+=("# TYPE dockcheck_images_analyze_timestamp_seconds gauge")
promFileContent+=("dockcheck_images_analyze_timestamp_seconds $checkTimestamp")
printf "%s\n" "${promFileContent[@]}" > "$CollectorTextFileDirectory/dockcheck_info.prom\$\$"
mv -f "$CollectorTextFileDirectory/dockcheck_info.prom\$\$" "$CollectorTextFileDirectory/dockcheck_info.prom"
}

97
default.config Normal file
View file

@ -0,0 +1,97 @@
##### Custom user variables #####
## Copy this file to "dockcheck.config" to make it active
## Can be placed in ~/.config/ or alongside dockcheck.sh
##
## Uncomment and set your preferred configuration variables here
## This will not be replaced on updates
#AutoMode=true # Automatic updates, without interaction.
#AutoPrune=true # Auto-Prune dangling images after update.
#AutoSelfUpdate=true # Allow automatic self updates - caution as this will pull new code and autorun it.
#BackupForDays=7 # Enable backups of images and removes backups older than N days.
#BarWidth=50 # The character width of the progress bar
#CurlConnectTimeout=5 # Time to wait for curl to establish a connection before failing
#CurlRetryCount=3 # Max number of curl retries
#CurlRetryDelay=1 # Time between curl retries
#DaysOld="5" # Only update to new images that are N+ days old. Lists too recent with +prefix and age. 2xSlower.
#DisplaySourcedFiles=false # Display what files are being sourced/used
#DontUpdate=true # No updates; only checking availability without interaction.
#DRunUp=true # Allow checking/updating images created by `docker run`, containers need to be recreated manually.
#Exclude="one,two" # Exclude containers, separated by comma.
#ForceRestartStacks=true # Force stop+start stack after update. Caution: restarts once for every updated container within stack.
#MaxAsync=10 # Set max asynchronous subprocesses, 1 default, 0 to disable.
#MonoMode=true # Monochrome mode, no printf colour codes and hides progress bar.
#Notify=true # Inform - send a preconfigured notification.
#OnlyLabel=true # Only update if label is set. See readme.
#OnlySpecific=true # Only compose up the specific container, not the whole compose. (useful for master-compose structure).
#PrintMarkdownURL=true # Prints custom releasenote urls as markdown
#PrintReleaseURL=true # Prints custom releasenote urls alongside each container with updates (requires urls.list)`
#SkipRecreate # Skip container recreation after pulling images.
#Stopped="-a" # Include stopped containers in the check. (Logic: docker ps -a).
#Timeout=10 # Set a timeout (in seconds) per container for registry checkups.
##### NOTIFY SETTINGS BELOW #####
##
## All commented values are examples only. Modify as needed.
##
## Uncomment the line below and specify the notification channels you wish to enable in a space separated string
# NOTIFY_CHANNELS="apprise bark discord DSM file generic gotify HA matrix ntfy pushbullet pushover slack smtp telegram"
#
## Uncomment the line below and specify the number of seconds to delay notifications to enable snooze
# SNOOZE_SECONDS=86400
#
## Uncomment and set to true to disable notifications when dockcheck itself has updates.
# DISABLE_DOCKCHECK_NOTIFICATION=false
## Uncomment and set to true to disable notifications when notify scripts themselves have updates.
# DISABLE_NOTIFY_NOTIFICATION=false
#
## Apprise configuration variables. Set APPRISE_PAYLOAD to make a CLI call or set APPRISE_URL to make an API request instead.
# APPRISE_PAYLOAD='mailto://myemail:mypass@gmail.com
# mastodons://{token}@{host}
# pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
# tgram://{bot_token}/{chat_id}/'
# APPRISE_URL="http://apprise.mydomain.tld:1234/notify/apprise"
#
# BARK_KEY="key-value"
#
# DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/<token string>"
#
# DSM_SENDMAILTO="me@mydomain.com"
# DSM_SUBJECTTAG="Email Subject Prefix"
#
# FILE_PATH="${ScriptWorkDir}/updates_available.txt"
#
# GOTIFY_DOMAIN="https://gotify.domain.tld"
# GOTIFY_TOKEN="token-value"
#
# HA_ENTITY="entity"
# HA_TOKEN="token"
# HA_URL="https://your.homeassistant.url"
#
# MATRIX_ACCESS_TOKEN="token-value"
# MATRIX_ROOM_ID="myroom"
# MATRIX_SERVER_URL="https://matrix.yourdomain.tld"
#
## https://ntfy.sh or your custom domain with https:// and no trailing /
# NTFY_DOMAIN="https://ntfy.sh"
# NTFY_TOPIC_NAME="YourUniqueTopicName"
## Auth method, set to either format -> "user:password" OR ":tk_12345678". If using tokens, don't forget the ":"
# NTFY_AUTH=""
#
# PUSHBULLET_URL="https://api.pushbullet.com/v2/pushes"
# PUSHBULLET_TOKEN="token-value"
#
# PUSHOVER_URL="https://api.pushover.net/1/messages.json"
# PUSHOVER_USER_KEY="userkey"
# PUSHOVER_TOKEN="token-value"
#
# SLACK_CHANNEL_ID=mychannel
# SLACK_ACCESS_TOKEN=xoxb-token-value
#
# SMTP_MAIL_FROM="me@mydomain.tld"
# SMTP_MAIL_TO="you@yourdomain.tld"
# SMTP_SUBJECT_TAG="dockcheck"
#
# TELEGRAM_CHAT_ID="mychatid"
# TELEGRAM_TOKEN="token-value"
# TELEGRAM_TOPIC_ID="0"

View file

@ -1,162 +1,705 @@
#!/bin/bash
VERSION="v0.1.5"
#!/usr/bin/env bash
VERSION="v0.7.6"
# ChangeNotes: Bugfixes and sanitation. Cleanup of default.config - migrate settings manually (optional).
Github="https://github.com/mag37/dockcheck"
RawUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh"
### Check if there's a new release of the script:
LatestRelease="$(curl -s -r 0-30 https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh | sed -n "/VERSION/s/VERSION=//p" | tr -d '"')"
[ "$VERSION" != "$LatestRelease" ] && printf "New version available! Latest: "$LatestRelease" - Local: "$VERSION" \nGrab it here: "$Github" \n\n"
set -uo pipefail
shopt -s nullglob
shopt -s failglob
### Help Function:
Help() {
echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]"
echo "Example: dockcheck.sh -a ng"
echo
echo "Options:"
echo "-h Print this Help."
echo "-a|y Automatic updates, without interaction."
echo "-n No updates, only checking availability."
# Variables for self updating
ScriptArgs=( "$@" )
ScriptPath="$(readlink -f "$0")"
ScriptWorkDir="$(dirname "$ScriptPath")"
# Source helper functions
source_if_exists_or_fail() {
if [[ -s "$1" ]]; then
source "$1"
[[ "${DisplaySourcedFiles:-false}" == true ]] && echo " * sourced config: ${1}"
return 0
else
return 1
fi
}
while getopts "aynh" options; do
# User customizable defaults
source_if_exists_or_fail "${HOME}/.config/dockcheck.config" || source_if_exists_or_fail "${ScriptWorkDir}/dockcheck.config"
# Help Function
Help() {
echo "Syntax: dockcheck.sh [OPTION] [comma separated names to include]"
echo "Example: dockcheck.sh -y -x 10 -d 10 -e nextcloud,heimdall"
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 D 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."
echo "-f Force stop+start stack after update. Caution: restarts once for every updated container within stack."
echo "-F Only compose up the specific container, not the whole compose stack (useful for master-compose structure)."
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 "-l Only include containers with label set. See readme."
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."
echo "-p Auto-prune dangling images after update."
echo "-r Allow checking/updating images created by 'docker run', containers need to be recreated manually."
echo "-R Skip container recreation after pulling images."
echo "-s Include stopped containers in the check. (Logic: docker ps -a)."
echo "-t N Set a timeout (in seconds) per container for registry checkups, 10 is default."
echo "-u Allow automatic self updates - caution as this will pull new code and autorun it."
echo "-v Prints current version."
echo "-x N Set max asynchronous subprocesses, 1 default, 0 to disable, 32+ tested."
echo
echo "Project source: $Github"
}
# Print current backups function
print_backups() {
printf "\n%b---%b Currently backed up images %b---%b\n\n" "$c_teal" "$c_blue" "$c_teal" "$c_reset"
docker images | sed -ne '/^REPOSITORY/p' -ne '/^dockcheck/p'
}
# Initialise variables
Timeout=${Timeout:-10}
MaxAsync=${MaxAsync:-1}
BarWidth=${BarWidth:-50}
AutoMode=${AutoMode:-false}
DontUpdate=${DontUpdate:-false}
AutoPrune=${AutoPrune:-false}
AutoSelfUpdate=${AutoSelfUpdate:-false}
OnlyLabel=${OnlyLabel:-false}
Notify=${Notify:-false}
ForceRestartStacks=${ForceRestartStacks:-false}
DRunUp=${DRunUp:-false}
MonoMode=${MonoMode:-false}
PrintReleaseURL=${PrintReleaseURL:-false}
PrintMarkdownURL=${PrintMarkdownURL:-false}
Stopped=${Stopped:-""}
CollectorTextFileDirectory=${CollectorTextFileDirectory:-}
Exclude=${Exclude:-}
DaysOld=${DaysOld:-}
BackupForDays=${BackupForDays:-}
OnlySpecific=${OnlySpecific:-false}
SpecificContainer=${SpecificContainer:-""}
SkipRecreate=${SkipRecreate:-false}
Excludes=()
GotUpdates=()
NoUpdates=()
GotErrors=()
SelectedUpdates=()
CurlArgs="--retry ${CurlRetryCount:=3} --retry-delay ${CurlRetryDelay:=1} --connect-timeout ${CurlConnectTimeout:=5} -sf"
regbin=""
jqbin=""
# Colours
c_red="\033[0;31m"
c_green="\033[0;32m"
c_yellow="\033[0;33m"
c_blue="\033[0;34m"
c_teal="\033[0;36m"
c_reset="\033[0m"
# Timestamps
RunTimestamp=$(date +'%Y-%m-%d_%H%M')
RunEpoch=$(date +'%s')
while getopts "ayb:BfFhiIlmMnprsuvc:e:d:t:x:R" options; do
case "${options}" in
a|y) UpdYes="yes" ;;
n) UpdYes="no" ;;
h|*) Help ; exit 0 ;;
a|y) AutoMode=true ;;
b) BackupForDays="${OPTARG}" ;;
B) print_backups; exit 0 ;;
c) CollectorTextFileDirectory="${OPTARG}" ;;
d) DaysOld=${OPTARG} ;;
e) Exclude=${OPTARG} ;;
f) ForceRestartStacks=true ;;
F) OnlySpecific=true ;;
i) Notify=true ;;
I) PrintReleaseURL=true ;;
l) OnlyLabel=true ;;
m) MonoMode=true ;;
M) PrintMarkdownURL=true ;;
n) DontUpdate=true; AutoMode=true;;
p) AutoPrune=true ;;
R) SkipRecreate=true ;;
r) DRunUp=true ;;
s) Stopped="-a" ;;
t) Timeout="${OPTARG}" ;;
u) AutoSelfUpdate=true ;;
v) printf "%s\n" "$VERSION"; exit 0 ;;
x) MaxAsync=${OPTARG} ;;
h|*) Help; exit 2 ;;
esac
done
shift "$((OPTIND-1))"
### Set $1 to a variable for name filtering later.
SearchName="$1"
# Set $1 to a variable for name filtering later, rewriting if multiple
SearchName="${1:-}"
if [[ ! -z "$SearchName" ]]; then
SearchName="^(${SearchName//,/|})$"
fi
### Check if required binary exists in PATH or directory:
if [[ $(builtin type -P "regctl") ]]; then
regbin="regctl"
elif [[ -f "./regctl" ]]; then
regbin="./regctl"
else
printf "Required dependency 'regctl' missing, do you want it downloaded? y/[n] "
read GetDep
if [ "$GetDep" != "${GetDep#[Yy]}" ]; then
### Check arch:
case "$(uname --machine)" in
x86_64|amd64) architecture="amd64" ;;
arm64|aarch64) architecture="arm64";;
*) echo "Architecture not supported, exiting." ; exit ;;
esac
curl -L https://github.com/regclient/regclient/releases/latest/download/regctl-linux-$architecture >./regctl
chmod 755 ./regctl
regbin="./regctl"
else
printf "%s\n" "Dependency missing, quitting."
exit
# Check if there's a new release of the script
LatestSnippet="$(curl ${CurlArgs} -r 0-200 "$RawUrl" || printf "undefined")"
LatestRelease="$(echo "${LatestSnippet}" | sed -n "/VERSION/s/VERSION=//p" | tr -d '"')"
LatestChanges="$(echo "${LatestSnippet}" | sed -n "/ChangeNotes/s/# ChangeNotes: //p")"
# Basic notify configuration check
if [[ "${Notify}" == true ]] && [[ ! -s "${ScriptWorkDir}/notify.sh" ]] && [[ -z "${NOTIFY_CHANNELS:-}" ]]; then
printf "Using v2 notifications with -i flag passed but no notify channels configured in dockcheck.config. This will result in no notifications being sent.\n"
fi
# Setting up options and sourcing functions
if [[ "$DontUpdate" == true ]]; then AutoMode=true; fi
if [[ "$MonoMode" == true ]]; then declare c_{red,green,yellow,blue,teal,reset}=""; fi
if [[ "$Notify" == true ]]; then
source_if_exists_or_fail "${ScriptWorkDir}/notify.sh" || source_if_exists_or_fail "${ScriptWorkDir}/notify_templates/notify_v2.sh" || Notify=false
fi
if [[ -n "$Exclude" ]]; then
IFS=',' read -ra Excludes <<< "$Exclude"
unset IFS
fi
if [[ -n "$DaysOld" ]]; then
if ! [[ $DaysOld =~ ^[0-9]+$ ]]; then
printf "Days -d argument given (%s) is not a number.\n" "$DaysOld"
exit 2
fi
fi
### Check docker compose binary:
if docker compose &> /dev/null ; then
DockerBin="docker compose"
elif docker-compose -v &> /dev/null; then
DockerBin="docker-compose"
else
printf "%s\n" "No docker compose binary available, quitting."
exit
if [[ -n "$BackupForDays" ]]; then
if ! [[ $BackupForDays =~ ^[0-9]+$ ]]; then
printf "-b argument given (%s) is not a number.\n" "$BackupForDays"
exit 2
fi
[[ "$AutoPrune" == true ]] && printf "%bWARNING: When -b option is used, -p has no function.%b\n" "$c_yellow" "$c_reset"
fi
if [[ -n "$CollectorTextFileDirectory" ]]; then
if ! [[ -d $CollectorTextFileDirectory ]]; then
printf "The directory (%s) does not exist.\n" "$CollectorTextFileDirectory"
exit 2
else
source "${ScriptWorkDir}/addons/prometheus/prometheus_collector.sh"
fi
fi
### Numbered List -function:
options() {
num=0
for i in "${NumberedUpdates[@]}"; do
echo "$num) $i"
((num++))
done
exec_if_exists() {
if [[ $(type -t $1) == function ]]; then "$@"; fi
}
exec_if_exists_or_fail() {
[[ $(type -t $1) == function ]] && "$@"
}
self_update_curl() {
cp "$ScriptPath" "$ScriptPath".bak
if command -v curl &>/dev/null; then
curl ${CurlArgs} -L $RawUrl > "$ScriptPath"; chmod +x "$ScriptPath" || { printf "ERROR: Failed to curl updated Dockcheck.sh script. Skipping update.\n"; return 1; }
printf "\n%b---%b starting over with the updated version %b---%b\n" "$c_yellow" "$c_teal" "$c_yellow" "$c_reset"
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 1 # Exit the old instance
elif command -v wget &>/dev/null; then
wget --waitretry=1 --timeout=15 -t 10 $RawUrl -O "$ScriptPath"; chmod +x "$ScriptPath"
printf "\n%b---%b starting over with the updated version %b---%b\n" "$c_yellow" "$c_teal" "$c_yellow" "$c_reset"
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 0 # exit the old instance
else
printf "\n%bcurl/wget not available %b- download the update manually: %b%s %b\n" "$c_red" "$c_reset" "$c_teal" "$Github" "$c_reset"
fi
}
self_update() {
cd "$ScriptWorkDir" || { printf "%bPath error,%b skipping update.\n" "$c_red" "$c_reset"; return; }
if command -v git &>/dev/null && [[ "$(git ls-remote --get-url 2>/dev/null)" =~ .*"mag37/dockcheck".* ]]; then
printf "\n%s\n" "Pulling the latest version."
git pull --force || { printf "%bGit error,%b manually pull/clone.\n" "$c_red" "$c_reset"; return; }
printf "\n%s\n" "--- starting over with the updated version ---"
cd - || { printf "%bPath error.%b\n" "$c_red" "$c_reset"; return; }
exec "$ScriptPath" "${ScriptArgs[@]}" # run the new script with old arguments
exit 0 # exit the old instance
else
cd - || { printf "%bPath error.%b\n" "$c_red" "$c_reset"; return; }
self_update_curl
fi
}
### Choose from list -function:
choosecontainers() {
while [[ "$ChoiceClean" =~ [A-Za-z] || -z "$ChoiceClean" ]]; do
read -p "Enter number(s) separated by comma, [q] to quit: " Choice
if [[ "$Choice" =~ [qQnN] ]] ; then
while [[ -z "${ChoiceClean:-}" ]]; do
read -r -p "Enter number(s) separated by comma, [a] for all - [q] to quit: " Choice
if [[ "$Choice" =~ [qQnN] ]]; then
[[ -n "${BackupForDays:-}" ]] && remove_backups
exit 0
elif [ "$Choice" == "0" ] ; then
SelectedUpdates=( "${NumberedUpdates[@]:1}" )
ChoiceClean=$(echo "$Choice" |sed 's/[,.:;]/ /g')
elif [[ "$Choice" =~ [aAyY] ]]; then
SelectedUpdates=( "${GotUpdates[@]}" )
ChoiceClean=${Choice//[,.:;]/ }
else
ChoiceClean=$(echo "$Choice" |sed 's/[,.:;]/ /g')
for s in $ChoiceClean; do
SelectedUpdates+=( "${NumberedUpdates[$s]}" )
ChoiceClean=${Choice//[,.:;]/ }
for CC in $ChoiceClean; do
CC=$((10#$CC)) # Base 10 interpretation to strip leading zeroes
if [[ "$CC" -lt 1 || "$CC" -gt $UpdCount ]]; then # Reset choice if out of bounds
echo "Number not in list: $CC"; unset ChoiceClean; break 1
else
SelectedUpdates+=( "${GotUpdates[$CC-1]}" )
fi
done
fi
done
printf "\nUpdating containers:\n"
printf "%s\n" "${SelectedUpdates[@]}"
printf "\n"
}
### Check the image-hash of every running container VS the registry
for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
printf ". "
RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}')
LocalHash=$(docker image inspect "$RepoUrl" --format '{{.RepoDigests}}')
RegHash=$($regbin image digest --list "$RepoUrl" 2>/dev/null)
# Add container to GotErrors if regctl encounter problems.
if [ $? -eq 0 ] ; then
if [[ "$LocalHash" = *"$RegHash"* ]] ; then NoUpdates+=("$i"); else GotUpdates+=("$i"); fi
datecheck() {
ImageDate="$1"
DaysMax="$2"
ImageEpoch=$(date -d "$ImageDate" +%s 2>/dev/null) || ImageEpoch=$(date -f "%Y-%m-%d" -j "$ImageDate" +%s)
ImageAge=$(( ( RunEpoch - ImageEpoch )/86400 ))
if [[ "$ImageAge" -gt "$DaysMax" ]]; then
return 0
else
GotErrors+=("$i")
return 1
fi
done
}
### Sort arrays alphabetically
IFS=$'\n'
NoUpdates=($(sort <<<"${NoUpdates[*]}"))
GotUpdates=($(sort <<<"${GotUpdates[*]}"))
GotErrors=($(sort <<<"${GotErrors[*]}"))
remove_backups() {
IFS=$'\n'
CleanupCount=0
for backup_img in $(docker images --format "{{.Repository}} {{.Tag}}" | sed -n '/^dockcheck/p'); do
repo_name=${backup_img% *}
backup_tag=${backup_img#* }
backup_date=${backup_tag%%_*}
# UNTAGGING HERE
if datecheck "$backup_date" "$BackupForDays"; then
[[ "$CleanupCount" == 0 ]] && printf "\n%bRemoving backed up images older then %s days.%b\n" "$c_blue" "$BackupForDays" "$c_reset"
docker rmi "${repo_name}:${backup_tag}" && ((CleanupCount+=1))
fi
done
unset IFS
if [[ "$CleanupCount" == 0 ]]; then
printf "\nNo backup images to remove.\n"
else
[[ "$CleanupCount" -gt 1 ]] && b_phrase="backups" || b_phrase="backup"
printf "\n%b%s%b %s removed.%b\n" "$c_green" "$CleanupCount" "$c_teal" "$b_phrase" "$c_reset"
fi
}
progress_bar() {
QueCurrent="$1"
QueTotal="$2"
BarWidth=${BarWidth:-50}
((Percent=100*QueCurrent/QueTotal))
((Complete=BarWidth*Percent/100))
((Left=BarWidth-Complete)) || true # to not throw error when result is 0
BarComplete=$(printf "%${Complete}s" | tr " " "#")
BarLeft=$(printf "%${Left}s" | tr " " "-")
if [[ "$QueTotal" != "$QueCurrent" ]]; then
printf "\r[%s%s] %s/%s " "$BarComplete" "$BarLeft" "$QueCurrent" "$QueTotal"
else
printf "\r[%b%s%b] %s/%s \n" "$c_teal" "$BarComplete" "$c_reset" "$QueCurrent" "$QueTotal"
fi
}
# Function to add user-provided urls to releasenotes
releasenotes() {
unset Updates
for update in "${GotUpdates[@]}"; do
found=false
while read -r container url; do
if [[ "$update" == "$container" ]] && [[ "$PrintMarkdownURL" == true ]]; then Updates+=("- [$update]($url)"); found=true;
elif [[ "$update" == "$container" ]]; then Updates+=("$update -> $url"); found=true;
fi
done < "${ScriptWorkDir}/urls.list"
if [[ "$found" == false ]] && [[ "$PrintMarkdownURL" == true ]]; then Updates+=("- $update -> url missing");
elif [[ "$found" == false ]]; then Updates+=("$update -> url missing");
else continue;
fi
done
}
# Static binary downloader for dependencies
binary_downloader() {
BinaryName="$1"
BinaryUrl="$2"
case "$(uname -m)" in
x86_64|amd64) architecture="amd64" ;;
arm64|aarch64) architecture="arm64";;
*) printf "\n%bArchitecture not supported, exiting.%b\n" "$c_red" "$c_reset"; exit 1;;
esac
GetUrl="${BinaryUrl/TEMP/"$architecture"}"
if command -v curl &>/dev/null; then curl ${CurlArgs} -L "$GetUrl" > "$ScriptWorkDir/$BinaryName" || { printf "ERROR: Failed to curl binary dependency. Rerun the script to retry.\n"; exit 1; }
elif command -v wget &>/dev/null; then wget --waitretry=1 --timeout=15 -t 10 "$GetUrl" -O "$ScriptWorkDir/$BinaryName";
else printf "\n%bcurl/wget not available - get %s manually from the repo link, exiting.%b" "$c_red" "$BinaryName" "$c_reset"; exit 1;
fi
[[ -f "$ScriptWorkDir/$BinaryName" ]] && chmod +x "$ScriptWorkDir/$BinaryName"
}
distro_checker() {
isRoot=false
[[ ${EUID:-} == 0 ]] && isRoot=true
if [[ -f /etc/alpine-release ]] ; then
[[ "$isRoot" == true ]] && PkgInstaller="apk add" || PkgInstaller="doas apk add"
elif [[ -f /etc/arch-release ]]; then
[[ "$isRoot" == true ]] && PkgInstaller="pacman -S" || PkgInstaller="sudo pacman -S"
elif [[ -f /etc/debian_version ]]; then
[[ "$isRoot" == true ]] && PkgInstaller="apt-get install" || PkgInstaller="sudo apt-get install"
elif [[ -f /etc/redhat-release ]]; then
[[ "$isRoot" == true ]] && PkgInstaller="dnf install" || PkgInstaller="sudo dnf install"
elif [[ -f /etc/SuSE-release ]]; then
[[ "$isRoot" == true ]] && PkgInstaller="zypper install" || PkgInstaller="sudo zypper install"
elif [[ $(uname -s) == "Darwin" ]]; then PkgInstaller="brew install"
else PkgInstaller="ERROR"; printf "\n%bNo distribution could be determined%b, falling back to static binary.\n" "$c_yellow" "$c_reset"
fi
}
# Dependency check + installer function
dependency_check() {
AppName="$1"
AppVar="$2"
AppUrl="$3"
if command -v "$AppName" &>/dev/null; then export "$AppVar"="$AppName";
elif [[ -f "$ScriptWorkDir/$AppName" ]]; then export "$AppVar"="$ScriptWorkDir/$AppName";
else
printf "\nRequired dependency %b'%s'%b missing, do you want to install it?\n" "$c_teal" "$AppName" "$c_reset"
read -r -p "y: With packagemanager (sudo). / s: Download static binary. y/s/[n] " GetBin
GetBin=${GetBin:-no} # set default to no if nothing is given
if [[ "$GetBin" =~ [yYsS] ]]; then
[[ "$GetBin" =~ [yY] ]] && distro_checker
if [[ -n "${PkgInstaller:-}" && "${PkgInstaller:-}" != "ERROR" ]]; then
[[ $(uname -s) == "Darwin" && "$AppName" == "regctl" ]] && AppName="regclient"
if $PkgInstaller "$AppName"; then
AppName="$1"
export "$AppVar"="$AppName"
printf "\n%b%b installed.%b\n" "$c_green" "$AppName" "$c_reset"
else
PkgInstaller="ERROR"
printf "\n%bPackagemanager install failed%b, falling back to static binary.\n" "$c_yellow" "$c_reset"
fi
fi
if [[ "$GetBin" =~ [sS] ]] || [[ "$PkgInstaller" == "ERROR" ]]; then
binary_downloader "$AppName" "$AppUrl"
[[ -f "$ScriptWorkDir/$AppName" ]] && { export "$AppVar"="$ScriptWorkDir/$1" && printf "\n%b%s downloaded.%b\n" "$c_green" "$AppName" "$c_reset"; }
fi
else printf "\n%bDependency missing, exiting.%b\n" "$c_red" "$c_reset"; exit 1;
fi
fi
# Final check if binary is correct
[[ "$1" == "jq" ]] && VerFlag="--version"
[[ "$1" == "regctl" ]] && VerFlag="version"
${!AppVar} "$VerFlag" &> /dev/null || { printf "%s\n" "$AppName is not working - try to remove it and re-download it, exiting."; exit 1; }
}
dependency_check "regctl" "regbin" "https://github.com/regclient/regclient/releases/latest/download/regctl-linux-TEMP"
dependency_check "jq" "jqbin" "https://github.com/jqlang/jq/releases/latest/download/jq-linux-TEMP"
# Numbered List function - pads with zero
list_options() {
local total="${#Updates[@]}"
[[ ${#total} < 2 ]] && local pads=2 || local pads="${#total}"
local num=1
for update in "${Updates[@]}"; do
printf "%0*d - %s\n" "$pads" "$num" "$update"
((num++))
done
}
# Version check & initiate self update
if [[ "$LatestSnippet" != "undefined" ]]; then
if [[ "$VERSION" != "$LatestRelease" ]]; then
printf "New version available! %b%s%b ⇒ %b%s%b \n Change Notes: %s \n" "$c_yellow" "$VERSION" "$c_reset" "$c_green" "$LatestRelease" "$c_reset" "$LatestChanges"
if [[ "$AutoMode" == false ]]; then
read -r -p "Would you like to update? y/[n]: " SelfUpdate
[[ "$SelfUpdate" =~ [yY] ]] && self_update
elif [[ "$AutoMode" == true ]] && [[ "$AutoSelfUpdate" == true ]]; then self_update;
else
[[ "$Notify" == true ]] && { exec_if_exists_or_fail dockcheck_notification "$VERSION" "$LatestRelease" "$LatestChanges" || printf "Could not source notification function.\n"; }
fi
fi
else
printf "ERROR: Failed to curl latest Dockcheck.sh release version.\n"
fi
# Version check for notify templates
[[ "$Notify" == true ]] && [[ ! -s "${ScriptWorkDir}/notify.sh" ]] && { exec_if_exists_or_fail notify_update_notification || printf "Could not source notify notification function.\n"; }
# Check docker compose binary
docker info &>/dev/null || { printf "\n%bYour current user does not have permissions to the docker socket - may require root / docker group. Exiting.%b\n" "$c_red" "$c_reset"; exit 1; }
if docker compose version &>/dev/null; then DockerBin="docker compose" ;
elif docker-compose -v &>/dev/null; then DockerBin="docker-compose" ;
elif docker -v &>/dev/null; then
printf "%s\n" "No docker compose binary available, using plain docker (Not recommended!)"
printf "%s\n" "'docker run' will ONLY update images, not the container itself."
else
printf "%s\n" "No docker binaries available, exiting."
exit 1
fi
# Listing typed exclusions
if [[ -n ${Excludes[*]:-} ]]; then
printf "\n%bExcluding these names:%b\n" "$c_blue" "$c_reset"
printf "%s\n" "${Excludes[@]}"
printf "\n"
fi
# Variables for progress_bar function
ContCount=$(docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | wc -l)
RegCheckQue=0
# Testing and setting timeout binary
t_out=$(command -v timeout || echo "")
if [[ $t_out ]]; then
t_out=$(realpath "$t_out" 2>/dev/null || readlink -f "$t_out")
if [[ $t_out =~ "busybox" ]]; then
t_out="timeout ${Timeout}"
else t_out="timeout --foreground ${Timeout}"
fi
else t_out=""
fi
check_image() {
i="$1"
local Excludes=($Excludes_string)
for e in "${Excludes[@]}"; do
if [[ "$i" == "$e" ]]; then
printf "%s\n" "Skip $i"
return
fi
done
# Skipping non-compose containers unless option is set
ContLabels=$(docker inspect "$i" --format '{{json .Config.Labels}}')
ContPath=$($jqbin -r '."com.docker.compose.project.working_dir"' <<< "$ContLabels")
[[ "$ContPath" == "null" ]] && ContPath=""
if [[ -z "$ContPath" ]] && [[ "$DRunUp" == false ]]; then
printf "%s\n" "NoUpdates !$i - not checked, no compose file"
return
fi
# Checking if Label Only -option is set, and if container got the label
ContUpdateLabel=$($jqbin -r '."mag37.dockcheck.update"' <<< "$ContLabels")
[[ "$ContUpdateLabel" == "null" ]] && ContUpdateLabel=""
[[ "$OnlyLabel" == true ]] && { [[ "$ContUpdateLabel" != true ]] && { echo "Skip $i"; return; } }
local NoUpdates GotUpdates GotErrors
ImageId=$(docker inspect "$i" --format='{{.Image}}')
RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}')
LocalHash=$(docker image inspect "$ImageId" --format '{{.RepoDigests}}')
# Checking for errors while setting the variable
if RegHash=$($t_out "$regbin" -v error image digest --list "$RepoUrl" 2>&1); then
if [[ "$LocalHash" == *"$RegHash"* ]]; then
printf "%s\n" "NoUpdates $i"
else
if [[ -n "${DaysOld:-}" ]] && ! datecheck $("$regbin" -v error image inspect "$RepoUrl" --format='{{.Created}}' | cut -d" " -f1) "$DaysOld" ; then
printf "%s\n" "NoUpdates +$i ${ImageAge}d"
else
printf "%s\n" "GotUpdates $i"
fi
fi
else
printf "%s\n" "GotErrors $i - ${RegHash}" # Reghash contains an error code here
fi
}
# Make required functions and variables available to subprocesses
export -f check_image datecheck
export Excludes_string="${Excludes[*]:-}" # Can only export scalar variables
export t_out regbin RepoUrl DaysOld DRunUp jqbin OnlyLabel RunTimestamp RunEpoch
# Check for POSIX xargs with -P option, fallback without async
if (echo "test" | xargs -P 2 >/dev/null 2>&1) && [[ "$MaxAsync" != 0 ]]; then
XargsAsync="-P $MaxAsync"
else
XargsAsync=""
[[ "$MaxAsync" != 0 ]] && printf "%bMissing POSIX xargs, consider installing 'findutils' for asynchronous lookups.%b\n" "$c_yellow" "$c_reset"
fi
# Asynchronously check the image-hash of every running container VS the registry
while read -r line; do
((RegCheckQue+=1))
if [[ "$MonoMode" == false ]]; then progress_bar "$RegCheckQue" "$ContCount"; fi
Got=${line%% *} # Extracts the first word (NoUpdates, GotUpdates, GotErrors)
item=${line#* }
case "$Got" in
NoUpdates) NoUpdates+=("$item") ;;
GotUpdates) GotUpdates+=("$item") ;;
GotErrors) GotErrors+=("$item") ;;
Skip) ;;
*) echo "Error! Unexpected output from subprocess: ${line}" ;;
esac
done < <( \
docker ps $Stopped --filter "name=$SearchName" --format '{{.Names}}' | \
xargs $XargsAsync -I {} bash -c 'check_image "{}"' \
)
[[ "$OnlyLabel" == true ]] && printf "\n%bLabel option active:%b Only checking containers with labels set.\n" "$c_blue" "$c_reset"
# Sort arrays alphabetically
IFS=$'\n'
NoUpdates=($(sort <<<"${NoUpdates[*]:-}"))
GotUpdates=($(sort <<<"${GotUpdates[*]:-}"))
unset IFS
### Create new Array to use for the numbered list:
NumberedUpdates=(ALL "${GotUpdates[@]}")
### List what containers got updates or not
if [ -n "$NoUpdates" ] ; then
printf "\n\033[32;1mContainers on latest version:\033[0m\n"
# Run the prometheus exporter function
if [[ -n "${CollectorTextFileDirectory:-}" ]]; then
exec_if_exists_or_fail prometheus_exporter ${#NoUpdates[@]} ${#GotUpdates[@]} ${#GotErrors[@]} || printf "%s\n" "Could not source prometheus exporter function."
fi
# Define how many updates are available
UpdCount="${#GotUpdates[@]}"
# List what containers got updates or not
if [[ -n ${NoUpdates[*]:-} ]]; then
printf "\n%bContainers on latest version:%b\n" "$c_green" "$c_reset"
printf "%s\n" "${NoUpdates[@]}"
fi
if [ -n "$GotErrors" ] ; then
printf "\n\033[33;1mContainers with errors, wont get updated:\033[0m\n"
if [[ -n ${GotErrors[*]:-} ]]; then
printf "\n%bContainers with errors, won't get updated:%b\n" "$c_red" "$c_reset"
printf "%s\n" "${GotErrors[@]}"
printf "%binfo:%b 'unauthorized' often means not found in a public registry.\n" "$c_blue" "$c_reset"
fi
if [ -n "$GotUpdates" ] ; then
printf "\n\033[31;1mContainers with updates available:\033[0m\n"
[ -z "$UpdYes" ] && options || printf "%s\n" "${GotUpdates[@]}"
if [[ -n ${GotUpdates[*]:-} ]]; then
printf "\n%bContainers with updates available:%b\n" "$c_yellow" "$c_reset"
if [[ -s "$ScriptWorkDir/urls.list" ]] && [[ "$PrintReleaseURL" == true ]]; then releasenotes; else Updates=("${GotUpdates[@]}"); fi
[[ "$AutoMode" == false ]] && list_options || printf "%s\n" "${Updates[@]}"
[[ "$Notify" == true ]] && { exec_if_exists_or_fail send_notification "${GotUpdates[@]}" || printf "\nCould not source notification function.\n"; }
else
[[ "$Notify" == true ]] && [[ ! -s "${ScriptWorkDir}/notify.sh" ]] && { exec_if_exists_or_fail send_notification "${GotUpdates[@]}" || printf "\nCould not source notification function.\n"; }
fi
### Optionally get updates if there's any
if [ -n "$GotUpdates" ] ; then
if [ -z "$UpdYes" ] ; then
printf "\n\033[36;1mChoose what containers to update.\033[0m\n"
choosecontainers
# Optionally get updates if there's any
if [[ -n "${GotUpdates:-}" ]]; then
if [[ "$AutoMode" == false ]]; then
printf "\n%bChoose what containers to update.%b\n" "$c_teal" "$c_reset"
choosecontainers
else
SelectedUpdates=( "${GotUpdates[@]}" )
fi
if [ "$UpdYes" == "${UpdYes#[Nn]}" ] ; then
for i in "${SelectedUpdates[@]}"
do
ContPath=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.working_dir" }}')
ContConfigFile=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.project.config_files" }}')
ContName=$(docker inspect "$i" --format '{{ index .Config.Labels "com.docker.compose.service" }}')
### Checking if "com.docker.compose.project.config_files" returns the full path to the config file or just the file name
if [[ $ContConfigFile = '/'* ]] ; then
ComposeFile="$ContConfigFile"
else
ComposeFile="$ContPath/$ContConfigFile"
if [[ "$DontUpdate" == false ]]; then
printf "\n%bUpdating container(s):%b\n" "$c_blue" "$c_reset"
printf "%s\n" "${SelectedUpdates[@]}"
NumberofUpdates="${#SelectedUpdates[@]}"
CurrentQue=0
for i in "${SelectedUpdates[@]}"; do
((CurrentQue+=1))
printf "\n%bNow updating (%s/%s): %b%s%b\n" "$c_teal" "$CurrentQue" "$NumberofUpdates" "$c_blue" "$i" "$c_reset"
ContConfig=$(docker inspect "$i" --format '{{json .}}')
ContImage=$($jqbin -r '."Config"."Image"' <<< "$ContConfig")
ImageId=$($jqbin -r '."Image"' <<< "$ContConfig")
ContPath=$($jqbin -r '."Config"."Labels"."com.docker.compose.project.working_dir"' <<< "$ContConfig")
[[ "$ContPath" == "null" ]] && ContPath=""
# Add new backup tag prior to pulling if option is set
if [[ -n "${BackupForDays:-}" ]]; then
ImageConfig=$(docker image inspect "$ImageId" --format '{{ json . }}')
ContRepoDigests=$($jqbin -r '.RepoDigests[0]' <<< "$ImageConfig")
[[ "$ContRepoDigests" == "null" ]] && ContRepoDigests=""
ContRepo=${ContImage%:*}
ContApp=${ContRepo#*/}
[[ "$ContImage" =~ ":" ]] && ContTag=${ContImage#*:} || ContTag="latest"
BackupName="dockcheck/${ContApp}:${RunTimestamp}_${ContTag}"
docker tag "$ImageId" "$BackupName"
printf "%b%s backed up as %s%b\n" "$c_teal" "$i" "$BackupName" "$c_reset"
fi
$DockerBin -f "$ComposeFile" pull "$ContName"
$DockerBin -f "$ComposeFile" up -d "$ContName"
# Checking if compose-values are empty - hence started with docker run
if [[ -z "$ContPath" ]]; then
if [[ "$DRunUp" == true ]]; then
docker pull "$ContImage"
printf "%s\n" "$i got a new image downloaded, rebuild manually with preferred 'docker run'-parameters"
else
printf "\n%b%s%b has no compose labels, probably started with docker run - %bskipping%b\n\n" "$c_yellow" "$i" "$c_reset" "$c_yellow" "$c_reset"
fi
continue
fi
if docker pull "$ContImage"; then
# Removal of the <none>-tag image left behind from backup
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
done
printf "\n%bDone pulling updates.%b\n" "$c_green" "$c_reset"
if [[ "$SkipRecreate" == true ]]; then
printf "%bSkipping container recreation due to -R.%b\n" "$c_yellow" "$c_reset"
else
printf "%bRecreating updated containers.%b\n" "$c_blue" "$c_reset"
CurrentQue=0
for i in "${SelectedUpdates[@]}"; do
((CurrentQue+=1))
unset CompleteConfs
# Extract labels and metadata
ContConfig=$(docker inspect "$i" --format '{{json .}}')
ContLabels=$($jqbin -r '."Config"."Labels"' <<< "$ContConfig")
ContPath=$($jqbin -r '."com.docker.compose.project.working_dir"' <<< "$ContLabels")
[[ "$ContPath" == "null" ]] && ContPath=""
ContConfigFile=$($jqbin -r '."com.docker.compose.project.config_files"' <<< "$ContLabels")
[[ "$ContConfigFile" == "null" ]] && ContConfigFile=""
ContName=$($jqbin -r '."com.docker.compose.service"' <<< "$ContLabels")
[[ "$ContName" == "null" ]] && ContName=""
ContEnv=$($jqbin -r '."com.docker.compose.project.environment_file"' <<< "$ContLabels")
[[ "$ContEnv" == "null" ]] && ContEnv=""
ContRestartStack=$($jqbin -r '."mag37.dockcheck.restart-stack"' <<< "$ContLabels")
[[ "$ContRestartStack" == "null" ]] && ContRestartStack=""
ContOnlySpecific=$($jqbin -r '."mag37.dockcheck.only-specific-container"' <<< "$ContLabels")
[[ "$ContOnlySpecific" == "null" ]] && ContRestartStack=""
ContStateRunning=$($jqbin -r '."State"."Running"' <<< "$ContConfig")
[[ "$ContStateRunning" == "null" ]] && ContStateRunning=""
if [[ "$ContStateRunning" == "true" ]]; then
printf "\n%bNow recreating (%s/%s): %b%s%b\n" "$c_teal" "$CurrentQue" "$NumberofUpdates" "$c_blue" "$i" "$c_reset"
else
printf "\n%bSkipping recreation of %b%s%b as it's not running.%b\n" "$c_yellow" "$c_blue" "$i" "$c_yellow" "$c_reset"
continue
fi
# Checking if compose-values are empty - hence started with docker run
[[ -z "$ContPath" ]] && { echo "Not a compose container, skipping."; continue; }
# cd to the compose-file directory to account for people who use relative volumes
cd "$ContPath" || { printf "\n%bPath error - skipping%b %s" "$c_red" "$c_reset" "$i"; continue; }
# Reformatting path + multi compose
if [[ $ContConfigFile == '/'* ]]; then
CompleteConfs=$(for conf in ${ContConfigFile//,/ }; do printf -- "-f %s " "$conf"; done)
else
CompleteConfs=$(for conf in ${ContConfigFile//,/ }; do printf -- "-f %s/%s " "$ContPath" "$conf"; done)
fi
# Check if the container got an environment file set and reformat it
ContEnvs=""
if [[ -n "$ContEnv" ]]; then ContEnvs=$(for env in ${ContEnv//,/ }; do printf -- "--env-file %s " "$env"; done); fi
# Set variable when compose up should only target the specific container, not the stack
if [[ $OnlySpecific == true ]] || [[ $ContOnlySpecific == true ]]; then SpecificContainer="$ContName"; fi
# Check if the whole stack should be restarted
if [[ "$ContRestartStack" == true ]] || [[ "$ForceRestartStacks" == true ]]; then
${DockerBin} ${CompleteConfs} stop; ${DockerBin} ${CompleteConfs} ${ContEnvs} up -d || { printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1; }
else
${DockerBin} ${CompleteConfs} ${ContEnvs} up -d ${SpecificContainer} || { printf "\n%bDocker error, exiting!%b\n" "$c_red" "$c_reset" ; exit 1; }
fi
done
fi
printf "\n%bAll updates done!%b\n" "$c_green" "$c_reset"
# Trigger pruning only when backup-function is not used
if [[ -z "${BackupForDays:-}" ]]; then
if [[ "$AutoPrune" == false ]] && [[ "$AutoMode" == false ]]; then printf "\n"; read -rep "Would you like to prune all dangling images? y/[n]: " AutoPrune; fi
if [[ "$AutoPrune" == true ]] || [[ "$AutoPrune" =~ [yY] ]]; then printf "\nAuto pruning.."; docker image prune -f; fi
fi
else
printf "\nNo updates installed, exiting.\n"
printf "\nNo updates installed.\n"
fi
else
printf "\nNo updates available, exiting.\n"
printf "\nNo updates available.\n"
fi
# Clean up old backup image tags if -b is used
[[ -n "${BackupForDays:-}" ]] && remove_backups
exit 0

View file

@ -1,144 +0,0 @@
#!/bin/bash
VERSION="v0.1.5"
Github="https://github.com/mag37/dockcheck"
### Check if there's a new release of the script:
LatestRelease="$(curl -s -r 0-30 https://raw.githubusercontent.com/mag37/dockcheck/main/dockcheck.sh | sed -n "/VERSION/s/VERSION=//p" | tr -d '"')"
[ "$VERSION" != "$LatestRelease" ] && printf "New version available! Latest: "$LatestRelease" - Local: "$VERSION" \nGrab it here: "$Github" \n\n"
### Help Function:
Help() {
echo "Syntax: dockcheck.sh [OPTION] [part of name to filter]"
echo "Example: dockcheck.sh -a ng"
echo
echo "Options:"
echo "-h Print this Help."
echo "-a|y Automatic updates, without interaction."
echo "-n No updates, only checking availability."
}
while getopts "aynh" options; do
case "${options}" in
a|y) UpdYes="yes" ;;
n) UpdYes="no" ;;
h|*) Help ; exit 0 ;;
esac
done
shift "$((OPTIND-1))"
### Set $1 to a variable for name filtering later.
SearchName="$1"
### Check if required binary exists in PATH or directory:
if [[ $(builtin type -P "regctl") ]]; then
regbin="regctl"
elif [[ -f "./regctl" ]]; then
regbin="./regctl"
else
printf "Required dependency 'regctl' missing, do you want it downloaded? y/[n] "
read GetDep
if [ "$GetDep" != "${GetDep#[Yy]}" ]; then
### Check arch:
case "$(uname --machine)" in
x86_64|amd64) architecture="amd64" ;;
arm64|aarch64) architecture="arm64";;
*) echo "Architecture not supported, exiting." ; exit ;;
esac
curl -L https://github.com/regclient/regclient/releases/latest/download/regctl-linux-$architecture >./regctl
chmod 755 ./regctl
regbin="./regctl"
else
printf "%s\n" "Dependency missing, quitting."
exit
fi
fi
### Numbered List -function:
options() {
num=0
for i in "${NumberedUpdates[@]}"; do
echo "$num) $i"
((num++))
done
}
### Choose from list -function:
choosecontainers() {
while [[ "$ChoiceClean" =~ [A-Za-z] || -z "$ChoiceClean" ]]; do
read -p "Enter number(s) separated by comma, [q] to quit: " Choice
if [[ "$Choice" =~ [qQnN] ]] ; then
exit 0
elif [ "$Choice" == "0" ] ; then
SelectedUpdates=( "${NumberedUpdates[@]:1}" )
ChoiceClean=$(echo "$Choice" |sed 's/[,.:;]/ /g')
else
ChoiceClean=$(echo "$Choice" |sed 's/[,.:;]/ /g')
for s in $ChoiceClean; do
SelectedUpdates+=( "${NumberedUpdates[$s]}" )
done
fi
done
printf "\nUpdating containers:\n"
printf "%s\n" "${SelectedUpdates[@]}"
printf "\n"
}
### Check the image-hash of every running container VS the registry
for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
printf ". "
RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}')
LocalHash=$(docker image inspect "$RepoUrl" --format '{{.RepoDigests}}')
RegHash=$($regbin image digest --list "$RepoUrl" 2>/dev/null)
# Add container to GotErrors if regctl encounter problems.
if [ $? -eq 0 ] ; then
if [[ "$LocalHash" = *"$RegHash"* ]] ; then NoUpdates+=("$i"); else GotUpdates+=("$i"); fi
else
GotErrors+=("$i")
fi
done
### Sort arrays alphabetically
IFS=$'\n'
NoUpdates=($(sort <<<"${NoUpdates[*]}"))
GotUpdates=($(sort <<<"${GotUpdates[*]}"))
GotErrors=($(sort <<<"${GotErrors[*]}"))
unset IFS
### Create new Array to use for the numbered list:
NumberedUpdates=(ALL "${GotUpdates[@]}")
### List what containers got updates or not
if [ -n "$NoUpdates" ] ; then
printf "\n\033[32;1mContainers on latest version:\033[0m\n"
printf "%s\n" "${NoUpdates[@]}"
fi
if [ -n "$GotErrors" ] ; then
printf "\n\033[33;1mContainers with errors, wont get updated:\033[0m\n"
printf "%s\n" "${GotErrors[@]}"
fi
if [ -n "$GotUpdates" ] ; then
printf "\n\033[31;1mContainers with updates available:\033[0m\n"
[ -z "$UpdYes" ] && options || printf "%s\n" "${GotUpdates[@]}"
fi
### Optionally get updates if there's any
if [ -n "$GotUpdates" ] ; then
if [ -z "$UpdYes" ] ; then
printf "\n\033[36;1mChoose what container-images to update.\033[0m\n"
choosecontainers
else
SelectedUpdates=( "${GotUpdates[@]}" )
fi
if [ "$UpdYes" == "${UpdYes#[Nn]}" ] ; then
for i in "${SelectedUpdates[@]}"; do
ContImage=$(docker inspect "$i" --format='{{.Config.Image}}')
docker pull $ContImage
printf "%s\n" "$i got a new image downloaded, rebuild manually with preferred 'docker run'-parameters"
done
else
printf "\nNo updates installed, exiting.\n"
fi
else
printf "\nNo updates available, exiting.\n"
fi
exit 0

View file

@ -1,29 +0,0 @@
#!/bin/bash
### Requires the regctl binary.
### Get it here: https://github.com/regclient/regclient/releases
### Preferably placed in .bashrc or similar
### Set the full path to the binary or just regctl if in PATH:
regctl="/home/gw-tdc/dockers/regctl"
dupc () {
if [[ "$@" == "help" ]]; then
echo "No container name given, here's the list of currently running containers:"
docker ps --format '{{.Names}}'
else
for i in $(docker ps --filter "name=$@" --format '{{.Names}}')
do
RepoUrl=$(docker inspect $i --format='{{.Config.Image}}')
LocalHash=$(docker image inspect $RepoUrl --format '{{.RepoDigests}}')
RegHash=$($regctl image digest --list $RepoUrl 2>/dev/null)
if [ $? -eq 0 ] ; then
if [[ "$LocalHash" = *"$RegHash"* ]] ; then printf "$i is already latest.\n" ; else printf "$i got updates.\n" ; fi
else
printf "$i got errors, no check possible.\n"
fi
done
fi
}
dupc $1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

BIN
extras/apprise-ex1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

BIN
extras/apprise-ex2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View file

@ -0,0 +1,110 @@
# A small guide on getting started with Apprise notifications.
## Standalone docker container: [linuxserver/apprise-api](https://hub.docker.com/r/linuxserver/apprise-api)
Set up the docker compose as preferred:
```yaml
---
version: "2.1"
services:
apprise-api:
image: lscr.io/linuxserver/apprise-api:latest
container_name: apprise-api
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- /path/to/apprise-api/config:/config
ports:
- 8000:8000
restart: unless-stopped
```
Then browse to the webui.
![](apprise-ex1.png)
Here you'll click **Configuration Manager**, read the overview and then click on **Configuration**.
Under **Configuration** you'll craft/paste your notification config.
![](apprise-ex2.png)
The simplest way is just paste the url's as is (like in the example above).
There are many ways to customize with tags, groups, json and more. Read [caronc/apprise-api](https://github.com/caronc/apprise-api) for more info!
Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works.
You can also use the [caronc/apprise-api](https://github.com/caronc/apprise-api) to host the api as a frontend to an already existing **Apprise**-setup on the host.
### Customize the **notify.sh** file.
After you're done with the setup of the container and tried your notifications, you need to follow the configuration setup (explained in detail in the README).
Briefly: Copy `default.config` to `dockcheck.config` then edit it to change the following, `APPRISE_URL` matching your environment:
```bash
NOTIFY_CHANNELS="apprise"
APPRISE_URL="http://apprise.mydomain.tld:1234/notify/apprise"
```
That's it!
___
___
## On host installed **Apprise**
Follow the official guide on [caronc/apprise](https://github.com/caronc/apprise)!
### A brief, basic "get started"
- Install **apprise**
- python package `pip install apprise`
- packaged in EPEL/Fedora `dnf install apprise`
- packaged in AUR `[yay/pikaur/paru/other] apprise`
- Create a config file with your notification credentials (source of notifications):
```ini
mailto://user:password@yahoo.com
slack://token_a/token_b/token_c
kodi://example.com
```
Then either source the notifications with `-c=/path/to/config/apprise` or store them in *PATH* to skip referencing (`~/.apprise` or `~/.config/apprise`).
- Test apprise with a single notification:
- `apprise -vv -t 'test title' -b 'test notification body' 'mailto://myemail:mypass@gmail.com'`
- Set up your notification URL's and test them.
- Look at the [apprise wiki: Notification Services](https://github.com/caronc/apprise/wiki) for more info about how the url syntax for different services works.
### When done, customize the **notify.sh** file.
After you're done with the setup of the container and tried your notifications, you can copy the `notify_apprise.sh` file to `notify.sh` and start editing it.
Replace the url's corresponding to the services you've configured.
```bash
send_notification() {
Updates=("$@")
UpdToString=$( printf "%s\n" "${Updates[@]}" )
FromHost=$(hostname)
printf "\nSending Apprise notification\n"
MessageTitle="$FromHost - updates available."
# Setting the MessageBody variable here.
read -d '\n' MessageBody << __EOF
Containers on $FromHost with updates available:
$UpdToString
__EOF
# Modify to fit your setup:
apprise -vv -t "$MessageTitle" -b "$MessageBody" \
mailto://myemail:mypass@gmail.com \
mastodons://{token}@{host} \
pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b \
tgram://{bot_token}/{chat_id}/
}
```
That's all!
___
___

51
extras/dc_brief.sh Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env bash
### If not in PATH, set full path. Else just "regctl"
regbin="regctl"
### options to allow exclude:
while getopts "e:" options; do
case "${options}" in
e) Exclude=${OPTARG} ;;
*) exit 0 ;;
esac
done
shift "$((OPTIND-1))"
### Create array of excludes
IFS=',' read -r -a Excludes <<< "$Exclude" ; unset IFS
SearchName="$1"
for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
for e in "${Excludes[@]}" ; do [[ "$i" == "$e" ]] && continue 2 ; done
printf ". "
RepoUrl=$(docker inspect "$i" --format='{{.Config.Image}}')
LocalHash=$(docker image inspect "$RepoUrl" --format '{{.RepoDigests}}')
### Checking for errors while setting the variable:
if RegHash=$($regbin image digest --list "$RepoUrl" 2>/dev/null) ; then
if [[ "$LocalHash" = *"$RegHash"* ]] ; then NoUpdates+=("$i"); else GotUpdates+=("$i"); fi
else
GotErrors+=("$i")
fi
done
### Sort arrays alphabetically
IFS=$'\n'
NoUpdates=($(sort <<<"${NoUpdates[*]}"))
GotUpdates=($(sort <<<"${GotUpdates[*]}"))
GotErrors=($(sort <<<"${GotErrors[*]}"))
unset IFS
### List what containers got updates or not
if [[ -n ${NoUpdates[*]} ]] ; then
printf "\n\033[0;32mContainers on latest version:\033[0m\n"
printf "%s\n" "${NoUpdates[@]}"
fi
if [[ -n ${GotErrors[*]} ]] ; then
printf "\n\033[0;31mContainers with errors, wont get updated:\033[0m\n"
printf "%s\n" "${GotErrors[@]}"
fi
if [[ -n ${GotUpdates[*]} ]] ; then
printf "\n\033[0;33mContainers with updates available:\033[0m\n"
printf "%s\n" "${GotUpdates[@]}"
fi
printf "\n\n"

BIN
extras/dockcheck_colour.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

38
extras/errorCheck.sh Executable file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env bash
SearchName="$1"
for i in $(docker ps --filter "name=$SearchName" --format '{{.Names}}') ; do
echo "------------ $i ------------"
ContLabels=$(docker inspect "$i" --format '{{json .Config.Labels}}')
ContImage=$(docker inspect "$i" --format='{{.Config.Image}}')
ContPath=$(jq -r '."com.docker.compose.project.working_dir"' <<< "$ContLabels")
[ "$ContPath" == "null" ] && ContPath=""
[ -z "$ContPath" ] && { "$i has no compose labels - skipping" ; continue ; }
ContConfigFile=$(jq -r '."com.docker.compose.project.config_files"' <<< "$ContLabels")
[ "$ContConfigFile" == "null" ] && ContConfigFile=""
ContName=$(jq -r '."com.docker.compose.service"' <<< "$ContLabels")
[ "$ContName" == "null" ] && ContName=""
ContEnv=$(jq -r '."com.docker.compose.project.environment_file"' <<< "$ContLabels")
[ "$ContEnv" == "null" ] && ContEnv=""
ContUpdateLabel=$(jq -r '."mag37.dockcheck.update"' <<< "$ContLabels")
[ "$ContUpdateLabel" == "null" ] && ContUpdateLabel=""
ContRestartStack=$(jq -r '."mag37.dockcheck.restart-stack"' <<< "$ContLabels")
[ "$ContRestartStack" == "null" ] && ContRestartStack=""
if [[ $ContConfigFile = '/'* ]] ; then
ComposeFile="$ContConfigFile"
else
ComposeFile="$ContPath/$ContConfigFile"
fi
echo -e "Service name:\t\t$ContName"
echo -e "Project working dir:\t$ContPath"
echo -e "Compose files:\t\t$ComposeFile"
echo -e "Environment files:\t$ContEnv"
echo -e "Container image:\t$ContImage"
echo -e "Update label:\t$ContUpdateLabel"
echo -e "Restart Stack label:\t$ContRestartStack"
echo
echo "Mounts:"
docker inspect -f '{{ range .Mounts }}{{ .Source }}:{{ .Destination }}{{ printf "\n" }}{{ end }}' "$i"
echo
done

BIN
extras/example.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 KiB

BIN
extras/example_old.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

1
extras/temp Normal file
View file

@ -0,0 +1 @@
temp

View file

@ -0,0 +1,69 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_DSM_VERSION="v0.5"
# INFO: ssmtp is deprecated - consider to use msmtp instead.
#
# mSMTP/sSMTP has to be installed and configured manually.
# The existing DSM Notification Email configuration will be used automatically.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set DSM_SENDMAILTO and DSM_SUBJECTTAG in your dockcheck.config file.
MSMTP=$(which msmtp)
SSMTP=$(which ssmtp)
SENDMAIL=$(which sendmail)
if [ -n "$MSMTP" ] ; then
MailPkg=$MSMTP
elif [ -n "$SSMTP" ] ; then
MailPkg=$SSMTP
elif [ -n "$SENDMAIL" ] ; then
MailPkg=$SENDMAIL
else
echo "No msmtp, ssmtp or sendmail binary found in PATH: $PATH" ; exit 1
fi
trigger_DSM_notification() {
if [[ -n "$1" ]]; then
DSM_channel="$1"
else
DSM_channel="DSM"
fi
UpperChannel="${DSM_channel^^}"
DSMSendmailToVar="${UpperChannel}_SENDMAILTO"
DSMSubjectTagVar="${UpperChannel}_SUBJECTTAG"
CfgFile="/usr/syno/etc/synosmtp.conf"
# User variables:
# Automatically sends to your usual destination for synology DSM notification emails.
# You can also manually override by assigning something else to DSM_SENDMAILTO in dockcheck.config.
SendMailTo=${!DSMSendmailToVar:-$(grep 'eventmail1' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')}
# e.g. DSM_SENDMAILTO="me@mydomain.com"
SubjectTag=${!DSMSubjectTagVar:-$(grep 'eventsubjectprefix' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')}
# e.g. DSM_SUBJECTTAG="Email Subject Prefix"
SenderName=$(grep 'smtp_from_name' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')
SenderMail=$(grep 'smtp_from_mail' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')
SenderMail=${SenderMail:-$(grep 'eventmail1' $CfgFile | sed -n 's/.*"\([^"]*\)".*/\1/p')}
$MailPkg $SendMailTo << __EOF
From: "$SenderName" <$SenderMail>
date:$(date -R)
To: <$SendMailTo>
Subject: $SubjectTag $MessageTitle
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
$MessageBody
From $SenderName
__EOF
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
# This ensures DSM's container manager will also see the update
/var/packages/ContainerManager/target/tool/image_upgradable_checker
}

44
notify_templates/notify_HA.sh Executable file
View file

@ -0,0 +1,44 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_HA_VERSION="v0.2"
#
# This is an integration that makes it possible to send notifications via Home Assistant (https://www.home-assistant.io/integrations/notify/)
# You need to generate a long-lived access token in Home Sssistant to be used here (https://developers.home-assistant.io/docs/auth_api/#long-lived-access-token)
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set HA_ENTITY, HA_URL and HA_TOKEN in your dockcheck.config file.
trigger_HA_notification() {
if [[ -n "$1" ]]; then
HA_channel="$1"
else
HA_channel="HA"
fi
UpperChannel="${HA_channel^^}"
HAEntityVar="${UpperChannel}_ENTITY"
HAUrlVar="${UpperChannel}_URL"
HATokenVar="${UpperChannel}_TOKEN"
if [[ -z "${!HAEntityVar:-}" ]] || [[ -z "${!HAUrlVar:-}" ]] || [[ -z "${!HATokenVar:-}" ]]; then
printf "The ${HA_channel} notification channel is enabled, but required configuration variables are missing. Home assistant notifications will not be sent.\n"
remove_channel HA
return 0
fi
AccessToken="${!HATokenVar}"
Url="${!HAUrlVar}/api/services/notify/${!HAEntityVar}"
JsonData=$( "$jqbin" -n \
--arg body "$MessageBody" \
'{"title": "dockcheck update", "message": $body}' )
curl -S -o /dev/null ${CurlArgs} \
-H "Authorization: Bearer $AccessToken" \
-H "Content-Type: application/json" \
-d "$JsonData" -X POST $Url
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,51 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_APPRISE_VERSION="v0.4"
#
# Required receiving services must already be set up.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set APPRISE_PAYLOAD in your dockcheck.config file.
# If API, set APPRISE_URL instead.
trigger_apprise_notification() {
if [[ -n "$1" ]]; then
apprise_channel="$1"
else
apprise_channel="apprise"
fi
UpperChannel="${apprise_channel^^}"
ApprisePayloadVar="${UpperChannel}_PAYLOAD"
AppriseUrlVar="${UpperChannel}_URL"
if [[ -z "${!ApprisePayloadVar:-}" ]] && [[ -z "${!AppriseUrlVar:-}" ]]; then
printf "The ${apprise_channel} notification channel is enabled, but required configuration variables are missing. Apprise notifications will not be sent.\n"
remove_channel apprise
return 0
fi
if [[ -n "${!ApprisePayloadVar:-}" ]]; then
apprise -vv -t "$MessageTitle" -b "$MessageBody" \
${!ApprisePayloadVar}
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
fi
# e.g. APPRISE_PAYLOAD='mailto://myemail:mypass@gmail.com
# mastodons://{token}@{host}
# pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
# tgram://{bot_token}/{chat_id}/'
if [[ -n "${!AppriseUrlVar:-}" ]]; then
AppriseURL="${!AppriseUrlVar}"
curl -S -o /dev/null ${CurlArgs} -X POST -F "title=$MessageTitle" -F "body=$MessageBody" -F "tags=all" $AppriseURL # e.g. APPRISE_URL=http://apprise.mydomain.tld:1234/notify/apprise
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
fi
}

View file

@ -0,0 +1,46 @@
#!/bin/bash
# NOTIFY_BARK_VERSION="v1.0"
trigger_bark_notification() {
local channel="$1"
if [[ -z "$jqbin" ]]; then
for path in "$jqbin" "jq" "./jq" "../jq" "./jq-linux-TEMP" "../jq-linux-TEMP"; do
if command -v "$path" &>/dev/null; then jqbin="$path"; break; fi
done
fi
[[ -z "$jqbin" ]] && { echo "Error: jq missing"; return 1; }
[[ -z "$BARK_KEY" ]] && { echo "Error: Key not set"; return 1; }
local sound="${BARK_SOUND:-hello}"
local group="${BARK_GROUP:-Dockcheck}"
local icon_url="${BARK_ICON_URL:-https://raw.githubusercontent.com/mag37/dockcheck/main/logo.png}"
local title="${MessageTitle%.}"
local newline=$'\n'
local formatted_body="## $title${newline}${newline}---${newline}${newline}$MessageBody"
local json_payload=$( "$jqbin" -n \
--arg title "$title" \
--arg body "$formatted_body" \
--arg group "$group" \
--arg sound "$sound" \
--arg icon "$icon_url" \
'{
"title": $title,
"markdown": $body,
"group": $group,
"sound": $sound,
"icon": $icon,
}' )
if curl -s -f -X POST "https://api.day.app/$BARK_KEY" \
-H "Content-Type: application/json; charset=utf-8" \
-d "$json_payload" > /dev/null 2>&1; then
echo "Bark notification sent successfully (Markdown): $title"
fi
}

View file

@ -0,0 +1,39 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_DISCORD_VERSION="v0.5"
#
# Required receiving services must already be set up.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set DISCORD_WEBHOOK_URL in your dockcheck.config file.
trigger_discord_notification() {
if [[ -n "$1" ]]; then
discord_channel="$1"
else
discord_channel="discord"
fi
UpperChannel="${discord_channel^^}"
DiscordWebhookUrlVar="${UpperChannel}_WEBHOOK_URL"
if [[ -z "${!DiscordWebhookUrlVar:-}" ]]; then
printf "The ${discord_channel} notification channel is enabled, but required configuration variables are missing. Discord notifications will not be sent.\n"
remove_channel discord
return 0
fi
DiscordWebhookUrl="${!DiscordWebhookUrlVar}" # e.g. DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/<token string>
JsonData=$( "$jqbin" -n \
--arg username "$FromHost" \
--arg body "$MessageBody" \
'{"username": $username, "content": $body}' )
curl -S -o /dev/null ${CurlArgs} -X POST -H "Content-Type: application/json" -d "$JsonData" "$DiscordWebhookUrl"
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,22 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_FILE_VERSION="v0.1"
#
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
trigger_file_notification() {
if [[ -n "$1" ]]; then
file_channel="$1"
UpperChannel=$(tr '[:lower:]' '[:upper:]' <<< "$file_channel")
else
file_channel="file"
UpperChannel="FILE"
fi
FilePathVar="${UpperChannel}_PATH"
NotifyFile="${!FilePathVar:=${ScriptWorkDir}/updates_available.txt}"
echo "${MessageBody}" > ${NotifyFile}
}

View file

@ -0,0 +1,9 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_GENERIC_VERSION="v0.2"
#
# generic sample, the "Hello World" of notification addons
trigger_generic_notification() {
printf "\n$MessageTitle\n"
printf "\n$MessageBody\n"
}

View file

@ -0,0 +1,48 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_GOTIFY_VERSION="v0.5"
#
# Required receiving services must already be set up.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set GOTIFY_TOKEN and GOTIFY_DOMAIN in your dockcheck.config file.
trigger_gotify_notification() {
if [[ -n "$1" ]]; then
gotify_channel="$1"
else
gotify_channel="gotify"
fi
UpperChannel="${gotify_channel^^}"
GotifyTokenVar="${UpperChannel}_TOKEN"
GotifyUrlVar="${UpperChannel}_DOMAIN"
if [[ -z "${!GotifyTokenVar:-}" ]] || [[ -z "${!GotifyUrlVar:-}" ]]; then
printf "The ${gotify_channel} notification channel is enabled, but required configuration variables are missing. Gotify notifications will not be sent.\n"
remove_channel gotify
return 0
fi
GotifyToken="${!GotifyTokenVar}" # e.g. GOTIFY_TOKEN=token-value
GotifyUrl="${!GotifyUrlVar}/message?token=${GotifyToken}" # e.g. GOTIFY_URL=https://gotify.domain.tld
if [[ "$PrintMarkdownURL" == true ]]; then
ContentType="text/markdown"
else
ContentType="text/plain"
fi
JsonData=$( "$jqbin" -n \
--arg body "$MessageBody" \
--arg title "$MessageTitle" \
--arg type "$ContentType" \
'{message: $body, title: $title, priority: 5, extras: {"client::display": {"contentType": $type}}}' )
curl -S -o /dev/null ${CurlArgs} --data "${JsonData}" -H 'Content-Type: application/json' -X POST "${GotifyUrl}" 1> /dev/null
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,40 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_MATRIX_VERSION="v0.5"
#
# Required receiving services must already be set up.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set MATRIX_ACCESS_TOKEN, MATRIX_ROOM_ID, and MATRIX_SERVER_URL in your dockcheck.config file.
trigger_matrix_notification() {
if [[ -n "$1" ]]; then
matrix_channel="$1"
else
matrix_channel="matrix"
fi
UpperChannel="${matrix_channel^^}"
AccessTokenVar="${UpperChannel}_ACCESS_TOKEN"
RoomIdVar="${UpperChannel}_ROOM_ID"
MatrixServerVar="${UpperChannel}_SERVER_URL"
if [[ -z "${!AccessTokenVar:-}" ]] || [[ -z "${!RoomIdVar:-}" ]] || [[ -z "${!MatrixServerVar:-}" ]]; then
printf "The ${matrix_channel} notification channel is enabled, but required configuration variables are missing. Matrix notifications will not be sent.\n"
remove_channel matrix
return 0
fi
AccessToken="${!AccessTokenVar}" # e.g. MATRIX_ACCESS_TOKEN=token-value
RoomId="${!RoomIdVar}" # e.g. MATRIX_ROOM_ID=myroom
MatrixServer="${!MatrixServerVar}" # e.g. MATRIX_SERVER_URL=http://matrix.yourdomain.tld
MsgBody=$($jqbin -Rn --arg body "$MessageBody" '{msgtype:"m.text", body:$body}')
# URL Example: https://matrix.org/_matrix/client/r0/rooms/!xxxxxx:example.com/send/m.room.message?access_token=xxxxxxxx
curl -S -o /dev/null ${CurlArgs} -X POST "$MatrixServer/_matrix/client/r0/rooms/$RoomId/send/m.room.message?access_token=$AccessToken" -H 'Content-Type: application/json' -d "$MsgBody"
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,56 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_NTFYSH_VERSION="v0.7"
#
# Setup app and subscription at https://ntfy.sh
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set NTFY_DOMAIN and NTFY_TOPIC_NAME in your dockcheck.config file.
trigger_ntfy_notification() {
if [[ -n "$1" ]]; then
ntfy_channel="$1"
else
ntfy_channel="ntfy"
fi
UpperChannel="${ntfy_channel^^}"
NtfyDomainVar="${UpperChannel}_DOMAIN"
NtfyTopicNameVar="${UpperChannel}_TOPIC_NAME"
NtfyAuthVar="${UpperChannel}_AUTH"
if [[ -z "${!NtfyDomainVar:-}" ]] || [[ -z "${!NtfyTopicNameVar:-}" ]]; then
printf "The ${ntfy_channel} notification channel is enabled, but required configuration variables are missing. Ntfy notifications will not be sent.\n"
remove_channel ntfy
return 0
fi
NtfyUrl="${!NtfyDomainVar}/${!NtfyTopicNameVar}"
# e.g.
# NTFY_DOMAIN=ntfy.sh
# NTFY_TOPIC_NAME=YourUniqueTopicName
if [[ "$PrintMarkdownURL" == true ]]; then
ContentType="Markdown: yes"
else
ContentType="Markdown: no" #text/plain
fi
if [[ -n "${!NtfyAuthVar:-}" ]]; then
NtfyAuth="-u ${!NtfyAuthVar}"
else
NtfyAuth=""
fi
curl -S -o /dev/null ${CurlArgs} \
-H "Title: $MessageTitle" \
-H "$ContentType" \
-d "$MessageBody" \
$NtfyAuth \
-L "$NtfyUrl"
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,38 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_PUSHBULLET_VERSION="v0.4"
#
# Required receiving services must already be set up.
# Requires jq installed and in PATH.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set PUSHBULLET_TOKEN and PUSHBULLET_URL in your dockcheck.config file.
trigger_pushbullet_notification() {
if [[ -n "$1" ]]; then
pushbullet_channel="$1"
else
pushbullet_channel="pushbullet"
fi
UpperChannel="${pushbullet_channel^^}"
PushUrlVar="${UpperChannel}_URL"
PushTokenVar="${UpperChannel}_TOKEN"
if [[ -z "${!PushUrlVar:-}" ]] || [[ -z "${!PushTokenVar:-}" ]]; then
printf "The ${pushbullet_channel} notification channel is enabled, but required configuration variables are missing. Pushbullet notifications will not be sent.\n"
remove_channel pushbullet
return 0
fi
PushUrl="${!PushUrlVar}" # e.g. PUSHBULLET_URL=https://api.pushbullet.com/v2/pushes
PushToken="${!PushTokenVar}" # e.g. PUSHBULLET_TOKEN=token-value
# Requires jq to process json data
"$jqbin" -n --arg title "$MessageTitle" --arg body "$MessageBody" '{body: $body, title: $title, type: "note"}' | curl -S -o /dev/null ${CurlArgs} -X POST -H "Access-Token: $PushToken" -H "Content-type: application/json" $PushUrl -d @-
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,45 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_PUSHOVER_VERSION="v0.4"
#
# Required receiving services must already be set up.
# Requires jq installed and in PATH.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set PUSHOVER_USER_KEY, PUSHOVER_TOKEN, and PUSHOVER_URL in your dockcheck.config file.
trigger_pushover_notification() {
if [[ -n "$1" ]]; then
pushover_channel="$1"
else
pushover_channel="pushover"
fi
UpperChannel="${pushover_channel^^}"
PushoverUrlVar="${UpperChannel}_URL"
PushoverUserKeyVar="${UpperChannel}_USER_KEY"
PushoverTokenVar="${UpperChannel}_TOKEN"
if [[ -z "${!PushoverUrlVar:-}" ]] || [[ -z "${!PushoverUserKeyVar:-}" ]] || [[ -z "${!PushoverTokenVar:-}" ]]; then
printf "The ${pushover_channel} notification channel is enabled, but required configuration variables are missing. Pushover notifications will not be sent.\n"
remove_channel pushover
return 0
fi
PushoverUrl="${!PushoverUrlVar}" # e.g. PUSHOVER_URL=https://api.pushover.net/1/messages.json
PushoverUserKey="${!PushoverUserKeyVar}" # e.g. PUSHOVER_USER_KEY=userkey
PushoverToken="${!PushoverTokenVar}" # e.g. PUSHOVER_TOKEN=token-value
# Sending the notification via Pushover
curl -S -o /dev/null ${CurlArgs} -X POST \
-F "token=$PushoverToken" \
-F "user=$PushoverUserKey" \
-F "title=$MessageTitle" \
-F "message=$MessageBody" \
$PushoverUrl
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,40 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_SLACK_VERSION="v0.4"
#
# Setup app and token at https://api.slack.com/tutorials/tracks/posting-messages-with-curl
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set SLACK_ACCESS_TOKEN, and SLACK_CHANNEL_ID in your dockcheck.config file.
trigger_slack_notification() {
if [[ -n "$1" ]]; then
slack_channel="$1"
else
slack_channel="slack"
fi
UpperChannel="${slack_channel^^}"
AccessTokenVar="${UpperChannel}_ACCESS_TOKEN"
ChannelIDVar="${UpperChannel}_CHANNEL_ID"
if [[ -z "${!AccessTokenVar:-}" ]] || [[ -z "${!ChannelIDVar:-}" ]]; then
printf "The ${slack_channel} notification channel is enabled, but required configuration variables are missing. Slack notifications will not be sent.\n"
remove_channel slack
return 0
fi
AccessToken="${!AccessTokenVar}" # e.g. SLACK_ACCESS_TOKEN=some-token
ChannelID="${!ChannelIDVar}" # e.g. CHANNEL_ID=mychannel
SlackUrl="https://slack.com/api/chat.postMessage"
curl -S -o /dev/null ${CurlArgs} \
-d "text=$MessageBody" -d "channel=$ChannelID" \
-H "Authorization: Bearer $AccessToken" \
-X POST $SlackUrl
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,63 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_SMTP_VERSION="v0.5"
# INFO: ssmtp is depcerated - consider to use msmtp instead.
#
# mSMTP/sSMTP has to be installed and configured manually.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set SMTP_MAIL_FROM, SMTP_MAIL_TO, and SMTP_SUBJECT_TAG in your dockcheck.config file.
MSMTP=$(which msmtp)
SSMTP=$(which ssmtp)
SENDMAIL=$(which sendmail)
if [ -n "$MSMTP" ] ; then
MailPkg=$MSMTP
elif [ -n "$SSMTP" ] ; then
MailPkg=$SSMTP
elif [ -n "$SENDMAIL" ] ; then
MailPkg=$SENDMAIL
else
echo "No msmtp, ssmtp or sendmail binary found in PATH: $PATH" ; exit 1
fi
trigger_smtp_notification() {
if [[ -n "$1" ]]; then
smtp_channel="$1"
else
smtp_channel="smtp"
fi
UpperChannel="${smtp_channel^^}"
SendMailFromVar="${UpperChannel}_MAIL_FROM"
SendMailToVar="${UpperChannel}_MAIL_TO"
SubjectTagVar="${UpperChannel}_SUBJECT_TAG"
if [[ -z "${!SendMailFromVar:-}" ]] || [[ -z "${!SendMailToVar:-}" ]] || [[ -z "${!SubjectTagVar:-}" ]]; then
printf "The ${smtp_channel} notification channel is enabled, but required configuration variables are missing. SMTP notifications will not be sent.\n"
remove_channel smtp
return 0
fi
SendMailFrom="${!SendMailFromVar}" # e.g. MAIL_FROM=me@mydomain.tld
SendMailTo="${!SendMailToVar}" # e.g. MAIL_TO=me@mydomain.tld
SubjectTag="${!SubjectTagVar}" # e.g. SUBJECT_TAG=dockcheck
$MailPkg $SendMailTo << __EOF
From: "$FromHost" <$SendMailFrom>
date:$(date -R)
To: <$SendMailTo>
Subject: [$SubjectTag] $MessageTitle $FromHost
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
$MessageBody
__EOF
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,52 @@
### DISCLAIMER: This is a third party addition to dockcheck - best effort testing.
NOTIFY_TELEGRAM_VERSION="v0.5"
#
# Required receiving services must already be set up.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script.
# Do not modify this file directly within the "notify_templates" subdirectory. Set TELEGRAM_CHAT_ID and TELEGRAM_TOKEN in your dockcheck.config file.
trigger_telegram_notification() {
if [[ -n "$1" ]]; then
telegram_channel="$1"
else
telegram_channel="telegram"
fi
UpperChannel="${telegram_channel^^}"
TelegramTokenVar="${UpperChannel}_TOKEN"
TelegramChatIdVar="${UpperChannel}_CHAT_ID"
TelegramTopicIdVar="${UpperChannel}_TOPIC_ID"
if [[ -z "${!TelegramChatIdVar:-}" ]] || [[ -z "${!TelegramTokenVar:-}" ]]; then
printf "The ${telegram_channel} notification channel is enabled, but required configuration variables are missing. Telegram notifications will not be sent.\n"
remove_channel telegram
return 0
fi
if [[ "$PrintMarkdownURL" == true ]]; then
ParseMode="Markdown"
else
ParseMode="HTML"
fi
TelegramToken="${!TelegramTokenVar}" # e.g. TELEGRAM_TOKEN=token-value
TelegramChatId="${!TelegramChatIdVar}" # e.g. TELEGRAM_CHAT_ID=mychatid
TelegramUrl="https://api.telegram.org/bot$TelegramToken"
TelegramTopicID=${!TelegramTopicIdVar:="0"}
JsonData=$( "$jqbin" -n \
--arg chatid "$TelegramChatId" \
--arg text "$MessageBody" \
--arg thread "$TelegramTopicID" \
--arg parse_mode "$ParseMode" \
'{"chat_id": $chatid, "text": $text, "message_thread_id": $thread, "disable_notification": false, "parse_mode": $parse_mode, "disable_web_page_preview": true}' )
curl -S -o /dev/null ${CurlArgs} -X POST "$TelegramUrl/sendMessage" -H 'Content-Type: application/json' -d "$JsonData"
if [[ $? -gt 0 ]]; then
NotifyError=true
fi
}

View file

@ -0,0 +1,406 @@
NOTIFY_V2_VERSION="v0.7"
#
# If migrating from an older notify template, remove your existing notify.sh file.
# Leave (or place) this file in the "notify_templates" subdirectory within the same directory as the main dockcheck.sh script.
# If you instead wish make your own modifications, make a copy in the same directory as the main dockcheck.sh script and rename to notify.sh.
# Enable and configure all required notification variables in your dockcheck.config file, e.g.:
# NOTIFY_CHANNELS=apprise gotify slack
# SLACK_TOKEN=xoxb-some-token-value
# GOTIFY_TOKEN=some.token
# Number of seconds to snooze identical update notifications based on local image name
# or dockcheck.sh/notify.sh template file updates.
# Actual snooze will be 60 seconds less to avoid the chance of missed notifications due to minor scheduling or script run time issues.
snooze="${SNOOZE_SECONDS:-}"
SnoozeFile="${ScriptWorkDir}/snooze.list"
[[ ! -f "${SnoozeFile}" ]] && touch "${SnoozeFile}"
enabled_notify_channels=( ${NOTIFY_CHANNELS:-} )
# Global output string variable for modification by functions
UpdToString=""
FormattedOutput=""
get_channel_template() {
local UpperChannel="${1^^}"
local TemplateVar="${UpperChannel}_TEMPLATE"
if [[ -n "${!TemplateVar:-}" ]]; then
printf "${!TemplateVar}"
else
printf "$1"
fi
}
declare -A unique_templates
for channel in "${enabled_notify_channels[@]}"; do
template=$(get_channel_template "${channel}")
unique_templates["${template}"]=1
done
enabled_notify_templates=( "${!unique_templates[@]}" )
FromHost="$(cat /etc/hostname 2>/dev/null)" || FromHost="$(hostname 2>/dev/null)" || FromHost="UNKNOWN"
CurrentEpochTime=$(date +"%Y-%m-%dT%H:%M:%S")
CurrentEpochSeconds=$(date +%s)
NotifyError=false
for template in "${enabled_notify_templates[@]}"; do
source_if_exists_or_fail "${ScriptWorkDir}/notify_${template}.sh" || \
source_if_exists_or_fail "${ScriptWorkDir}/notify_templates/notify_${template}.sh" || \
printf "The notification channel template ${template} is enabled, but notify_${template}.sh was not found. Check the ${ScriptWorkDir} directory or the notify_templates subdirectory.\n"
done
skip_snooze() {
local UpperChannel="${1^^}"
local SkipSnoozeVar="${UpperChannel}_SKIPSNOOZE"
if [[ "${!SkipSnoozeVar:-}" == "true" ]]; then
printf "true"
else
printf "false"
fi
}
allow_empty() {
local UpperChannel="${1^^}"
local AllowEmptyVar="${UpperChannel}_ALLOWEMPTY"
if [[ "${!AllowEmptyVar:-}" == "true" ]]; then
printf "true"
else
printf "false"
fi
}
containers_only() {
local UpperChannel="${1^^}"
local ContainersOnlyVar="${UpperChannel}_CONTAINERSONLY"
if [[ "${!ContainersOnlyVar:-}" == "true" ]]; then
printf "true"
else
printf "false"
fi
}
output_format() {
local UpperChannel="${1^^}"
local OutputFormatVar="${UpperChannel}_OUTPUT"
if [[ -z "${!OutputFormatVar:-}" ]]; then
printf "text"
else
printf "${!OutputFormatVar:-}"
fi
}
remove_channel() {
local temp_array=()
for channel in "${enabled_notify_channels[@]}"; do
local channel_template=$(get_channel_template "${channel}")
[[ "${channel_template}" != "$1" ]] && temp_array+=("${channel}")
done
enabled_notify_channels=( "${temp_array[@]}" )
}
is_snoozed() {
if [[ -n "${snooze}" ]] && [[ -f "${SnoozeFile}" ]]; then
local found=$(grep -w "$1" "${SnoozeFile}" || printf "")
if [[ -n "${found}" ]]; then
read -a arr <<< "${found}"
CheckEpochSeconds=$(( $(date -d "${arr[1]}" +%s 2>/dev/null) + ${snooze} - 60 )) || CheckEpochSeconds=$(( $(date -f "%Y-%m-%d" -j "${arr[1]}" +%s) + ${snooze} - 60 ))
if [[ "${CurrentEpochSeconds}" -le "${CheckEpochSeconds}" ]]; then
printf "true"
else
printf "false"
fi
else
printf "false"
fi
else
printf "false"
fi
}
unsnoozed_count() {
unset Unsnoozed
Unsnoozed=()
for element in "$@"
do
read -a item <<< "${element}"
if [[ $(is_snoozed "${item[0]}") == "false" ]]; then
Unsnoozed+=("${element}")
fi
done
printf "${#Unsnoozed[@]}"
}
update_snooze() {
for arg in "$@"
do
read -a entry <<< "${arg}"
found=$(grep -w "${entry[0]}" "${SnoozeFile}" || printf "")
if [[ -n "${found}" ]]; then
sed -e "s/${entry[0]}.*/${entry[0]} ${CurrentEpochTime}/" "${SnoozeFile}" > "${SnoozeFile}.new"
mv "${SnoozeFile}.new" "${SnoozeFile}"
else
printf "${entry[0]} ${CurrentEpochTime}\n" >> "${SnoozeFile}"
fi
done
}
cleanup_snooze() {
unset NotifyEntries
NotifyEntries=()
switch=""
for arg in "$@"
do
read -a entry <<< "${arg}"
NotifyEntries+=("${entry[0]}")
done
if [[ ! "${NotifyEntries[@]}" == *".sh"* ]]; then
switch="-v"
fi
while read -r entry datestamp; do
if [[ ! "${NotifyEntries[@]}" == *"$entry"* ]]; then
sed -e "/${entry}/d" "${SnoozeFile}" > "${SnoozeFile}.new"
mv "${SnoozeFile}.new" "${SnoozeFile}"
fi
done <<< "$(grep ${switch} '\.sh ' ${SnoozeFile})"
}
format_output() {
local UpdateType="$1"
local OutputFormat="$2"
local FormattedTextTemplate="$3"
local tempcsv=""
if [[ ! "${UpdateType}" == "dockcheck_update" ]]; then
tempcsv="${UpdToString// -> /,}"
tempcsv="${tempcsv//.sh /.sh,}"
else
tempcsv="${UpdToString}"
fi
if [[ "${OutputFormat}" == "csv" ]]; then
if [[ -z "${UpdToString}" ]]; then
FormattedOutput="None"
else
FormattedOutput="${tempcsv}"
fi
elif [[ "${OutputFormat}" == "json" ]]; then
if [[ -z "${UpdToString}" ]]; then
FormattedOutput='{"updates": []}'
else
if [[ "${UpdateType}" == "container_update" ]]; then
# container updates case
FormattedOutput=$(jq --compact-output --null-input --arg updates "${tempcsv}" '($updates | split("\\n")) | map(split(",")) | {"updates": map({"container_name": .[0], "release_notes": .[1]})} | del(..|nulls)')
elif [[ "${UpdateType}" == "notify_update" ]]; then
# script updates case
FormattedOutput=$(jq --compact-output --null-input --arg updates "${tempcsv}" '($updates | split("\\n")) | map(split(",")) | {"updates": map({"script_name": .[0], "installed_version": .[1], "latest_version": .[2]})}')
elif [[ "${UpdateType}" == "dockcheck_update" ]]; then
# dockcheck update case
FormattedOutput=$(jq --compact-output --null-input --arg updates "${tempcsv}" '($updates | split("\\n")) | map(split(",")) | {"updates": map({"script_name": .[0], "installed_version": .[1], "latest_version": .[2], "release_notes": (.[3:] | join(","))})}')
else
FormattedOutput="Invalid input"
fi
fi
else
if [[ -z "${UpdToString}" ]]; then
FormattedOutput="None"
else
if [[ "${UpdateType}" == "container_update" ]]; then
FormattedOutput="${FormattedTextTemplate/<insert_text_cu>/${UpdToString}}"
elif [[ "${UpdateType}" == "notify_update" ]]; then
FormattedOutput="${FormattedTextTemplate/<insert_text_nu>/${UpdToString}}"
elif [[ "${UpdateType}" == "dockcheck_update" ]]; then
FormattedOutput="${FormattedTextTemplate/<insert_text_iv>/$4}"
FormattedOutput="${FormattedOutput/<insert_text_lv>/$5}"
FormattedOutput="${FormattedOutput/<insert_text_rn>/$6}"
else
FormattedOutput="Invalid input"
fi
fi
fi
}
skip_notification() {
# Skip notification logic. Default to false. Handle all cases, and only those cases, where notifications should be skipped.
local SkipNotification="false"
local Channel="$1"
local UnsnoozedCount="$2"
local NotificationType="$3"
if [[ $(containers_only "${Channel}") == "true" ]] && [[ "${NotificationType}" != "container" ]]; then
# Do not send notifications through channels only configured for container update notifications
SkipNotification="true"
else
# Handle empty update cases separately
if [[ -z "${UpdToString}" ]]; then
if [[ $(allow_empty "${Channel}") == "false" ]]; then
# Do not send notifications if there are none and allow_empty is false
SkipNotification="true"
fi
else
if [[ $(skip_snooze "${Channel}") == "false" ]] && [[ ${UnsnoozedCount} -eq 0 ]]; then
# Do not send notifications if there are any, they are all snoozed, and skip_snooze is false
SkipNotification="true"
fi
fi
fi
printf "${SkipNotification}"
}
send_notification() {
[[ -s "$ScriptWorkDir"/urls.list ]] && releasenotes || Updates=("$@")
[[ -n "${snooze}" ]] && cleanup_snooze "${Updates[@]}"
UnsnoozedContainers=$(unsnoozed_count "${Updates[@]}")
NotifyError=false
Notified="false"
# To be added in the MessageBody if "-d X" was used
# Trailing space is left intentionally for clean output
[[ -n "$DaysOld" ]] && msgdaysold="with images ${DaysOld}+ days old " || msgdaysold=""
MessageTitle="$FromHost - updates ${msgdaysold}available."
UpdToString=$( printf '%s\\n' "${Updates[@]}" )
UpdToString="${UpdToString%, }"
UpdToString=${UpdToString%\\n}
for channel in "${enabled_notify_channels[@]}"; do
local SkipNotification=$(skip_notification "${channel}" "${UnsnoozedContainers}" "container")
if [[ "${SkipNotification}" == "false" ]]; then
local template=$(get_channel_template "${channel}")
# Formats UpdToString variable per channel settings
format_output "container_update" "$(output_format "${channel}")" "🐋 Containers on $FromHost with updates available:\n<insert_text_cu>\n"
# Setting the MessageBody variable here.
printf -v MessageBody "${FormattedOutput}"
printf "\nSending ${channel} notification"
exec_if_exists_or_fail trigger_${template}_notification "${channel}" || \
printf "\nAttempted to send notification to channel ${channel}, but the function was not found. Make sure notify_${template}.sh is available in the ${ScriptWorkDir} directory or notify_templates subdirectory."
Notified="true"
fi
done
if [[ "${Notified}" == "true" ]]; then
[[ -n "${snooze}" ]] && [[ -n "${UpdToString}" ]] && [[ "${NotifyError}" == "false" ]] && update_snooze "${Updates[@]}"
printf "\n"
fi
return 0
}
### Set DISABLE_DOCKCHECK_NOTIFICATION=false in dockcheck.config
### to not send notifications when dockcheck itself has updates.
dockcheck_notification() {
if [[ ! "${DISABLE_DOCKCHECK_NOTIFICATION:-}" == "true" ]]; then
UnsnoozedDockcheck=$(unsnoozed_count "dockcheck\.sh")
NotifyError=false
Notified=false
MessageTitle="$FromHost - New version of dockcheck available."
UpdToString="dockcheck.sh,$1,$2,\"$3\""
for channel in "${enabled_notify_channels[@]}"; do
local SkipNotification=$(skip_notification "${channel}" "${UnsnoozedDockcheck}" "dockcheck")
if [[ "${SkipNotification}" == "false" ]]; then
local template=$(get_channel_template "${channel}")
# Formats UpdToString variable per channel settings
format_output "dockcheck_update" "$(output_format "${channel}")" "Installed version: <insert_text_iv>\nLatest version: <insert_text_lv>\n\nChangenotes: <insert_text_rn>\n" "$1" "$2" "$3"
# Setting the MessageBody variable here.
printf -v MessageBody "${FormattedOutput}"
printf "\nSending dockcheck update notification - ${channel}"
exec_if_exists_or_fail trigger_${template}_notification "${channel}" || \
printf "\nAttempted to send notification to channel ${channel}, but the function was not found. Make sure notify_${template}.sh is available in the ${ScriptWorkDir} directory or notify_templates subdirectory."
Notified="true"
fi
done
if [[ "${Notified}" == "true" ]]; then
[[ -n "${snooze}" ]] && [[ "${NotifyError}" == "false" ]] && update_snooze "dockcheck.sh"
printf "\n"
fi
fi
return 0
}
### Set DISABLE_NOTIFY_NOTIFICATION=false in dockcheck.config
### to not send notifications when notify scripts themselves have updates.
notify_update_notification() {
if [[ ! "${DISABLE_NOTIFY_NOTIFICATION:-}" == "true" ]]; then
NotifyError=false
NotifyUpdates=()
Notified=false
UpdateChannels=( "${enabled_notify_templates[@]}" "v2" )
for NotifyScript in "${UpdateChannels[@]}"; do
UpperChannel="${NotifyScript^^}"
VersionVar="NOTIFY_${UpperChannel}_VERSION"
if [[ -n "${!VersionVar:-}" ]]; then
RawNotifyUrl="https://raw.githubusercontent.com/mag37/dockcheck/main/notify_templates/notify_${NotifyScript}.sh"
LatestNotifySnippet="$(curl ${CurlArgs} -r 0-150 "$RawNotifyUrl" || printf "undefined")"
if [[ ! "${LatestNotifySnippet}" == "undefined" ]]; then
LatestNotifyRelease="$(echo "$LatestNotifySnippet" | sed -n "/${VersionVar}/s/${VersionVar}=//p" | tr -d '"')"
if [[ "${!VersionVar}" != "${LatestNotifyRelease}" ]] ; then
NotifyUpdates+=("${NotifyScript}.sh ${!VersionVar} -> ${LatestNotifyRelease}")
fi
fi
fi
done
UpdatesPlusDockcheck=("${NotifyUpdates[@]}")
UpdatesPlusDockcheck+=("dockcheck.sh")
[[ -n "${snooze}" ]] && cleanup_snooze "${UpdatesPlusDockcheck[@]}"
UnsnoozedTemplates=$(unsnoozed_count "${NotifyUpdates[@]}")
MessageTitle="$FromHost - New version of notify templates available."
UpdToString=$( printf '%s\\n' "${NotifyUpdates[@]}" )
UpdToString="${UpdToString%, }"
UpdToString=${UpdToString%\\n}
for channel in "${enabled_notify_channels[@]}"; do
local SkipNotification=$(skip_notification "${channel}" "${UnsnoozedTemplates}" "notify")
if [[ "${SkipNotification}" == "false" ]]; then
local template=$(get_channel_template "${channel}")
# Formats UpdToString variable per channel settings
format_output "notify_update" "$(output_format "${channel}")" "Notify templates on $FromHost with updates available:\n<insert_text_nu>\n"
# Setting the MessageBody variable here.
printf -v MessageBody "${FormattedOutput}"
printf "\nSending notify template update notification - ${channel}"
exec_if_exists_or_fail trigger_${template}_notification "${channel}" || \
printf "\nAttempted to send notification to channel ${channel}, but the function was not found. Make sure notify_${template}.sh is available in the ${ScriptWorkDir} directory or notify_templates subdirectory."
Notified="true"
fi
done
if [[ "${Notified}" == "true" ]]; then
[[ -n "${snooze}" ]] && [[ -n "${UpdToString}" ]] && [[ "${NotifyError}" == "false" ]] && update_snooze "${NotifyUpdates[@]}"
printf "\n"
fi
fi
return 0
}

105
notify_templates/urls.list Normal file
View file

@ -0,0 +1,105 @@
# Additions are welcome! Append your list to the git-repo, use generic names and sensible urls.
# Modify, add and (if necessary) remove to fit your needs.
# This is a list of container names and releasenote urls, separated by space.
actual_server https://actualbudget.org/blog
adguardhome https://github.com/AdguardTeam/AdGuardHome/releases
apprise-api https://github.com/linuxserver/docker-apprise-api/releases
audiobookshelf https://github.com/advplyr/audiobookshelf/releases
authentik_server https://github.com/goauthentik/authentik/releases
authentik_worker https://github.com/goauthentik/authentik/releases
barassistant https://github.com/karlomikus/bar-assistant//releases
barassistant_api https://github.com/karlomikus/bar-assistant/releases
bazarr https://github.com/morpheus65535/bazarr/releases
bazarr-ls https://github.com/linuxserver/docker-bazarr/releases
beszel https://github.com/henrygd/beszel/releases
booklore https://github.com/booklore-app/BookLore/releases
bookstack https://github.com/BookStackApp/BookStack/releases
bruceforce-vaultwarden-backup https://github.com/Bruceforce/vaultwarden-backup/blob/main/CHANGELOG.md
caddy https://github.com/caddyserver/caddy/releases
calibre https://github.com/linuxserver/docker-calibre/releases
calibre-web https://github.com/linuxserver/docker-calibre-web/releases
cleanuperr https://github.com/flmorg/cleanuperr/releases
collabora https://github.com/CollaboraOnline/online/releases
cross-seed https://github.com/cross-seed/cross-seed/releases
crowdsec https://github.com/crowdsecurity/crowdsec/releases
cup https://github.com/sergi0g/cup/releases
databasus https://github.com/databasus/databasus/releases
dockge https://github.com/louislam/dockge/releases
dozzle https://github.com/amir20/dozzle/releases
esphome https://github.com/esphome/esphome/releases
feishin https://github.com/jeffvli/feishin/releases
flatnotes https://github.com/dullage/flatnotes/releases
forgejo https://codeberg.org/forgejo/forgejo/releases
fressrss https://github.com/FreshRSS/FreshRSS/releases
frigate https://github.com/blakeblackshear/frigate/releases
gerbil https://github.com/fosrl/gerbil/releases
glances https://github.com/nicolargo/glances/releases
gluetun https://github.com/qdm12/gluetun/releases
go2rtc https://github.com/AlexxIT/go2rtc/releases
godoxy https://github.com/yusing/godoxy/releases
gotify https://github.com/gotify/server/releases
hbbr https://github.com/rustdesk/rustdesk-server/releases
hbbs https://github.com/rustdesk/rustdesk-server/releases
homarr https://github.com/homarr-labs/homarr/releases
home-assistant https://github.com/home-assistant/core/releases/
homepage https://github.com/gethomepage/homepage/releases
homer https://github.com/bastienwirtz/homer/releases
immich_machine_learning https://github.com/immich-app/immich/releases
immich_postgres https://github.com/tensorchord/VectorChord/releases
immich_redis https://github.com/valkey-io/valkey/releases
immich_server https://github.com/immich-app/immich/releases
jellyfin https://github.com/jellyfin/jellyfin/releases
jellyseerr https://github.com/Fallenbagel/jellyseerr/releases
jellystat https://github.com/CyferShepard/Jellystat/releases
karakeep https://github.com/karakeep-app/karakeep/releases
librespeed https://github.com/librespeed/speedtest/releases
lidarr https://github.com/Lidarr/Lidarr/releases/
lidarr-ls https://github.com/linuxserver/docker-lidarr/releases
lubelogger https://github.com/hargata/lubelog/releases
mattermost https://github.com/mattermost/mattermost/releases
mealie https://github.com/mealie-recipes/mealie/releases
meilisearch https://github.com/meilisearch/meilisearch/releases
monica https://github.com/monicahq/monica/releases
mqtt https://github.com/eclipse/mosquitto/tags
navidrome https://github.com/navidrome/navidrome/releases
newt https://github.com/fosrl/newt/releases
nextcloud-aio-mastercontainer https://github.com/nextcloud/all-in-one/releases
nginx https://github.com/docker-library/official-images/blob/master/library/nginx
opencloud https://github.com/opencloud-eu/opencloud/releases
outline https://github.com/outline/outline/releases
owncast https://github.com/owncast/owncast/releases
pangolin https://github.com/fosrl/pangolin/releases
prowlarr https://github.com/Prowlarr/Prowlarr/releases
prowlarr-ls https://github.com/linuxserver/docker-prowlarr/releases
qbittorrent https://www.qbittorrent.org/news
qbittorrent-nox https://www.qbittorrent.org/news
radarr https://github.com/Radarr/Radarr/releases/
radarr-ls https://github.com/linuxserver/docker-radarr/releases
readarr https://github.com/Readarr/Readarr/releases
readeck https://codeberg.org/readeck/readeck/releases
recyclarr https://github.com/recyclarr/recyclarr/releases
roundcubemail https://github.com/roundcube/roundcubemail/releases
sabnzbd https://github.com/linuxserver/docker-sabnzbd/releases
scanopy https://github.com/scanopy/scanopy/releases
scrutiny https://github.com/AnalogJ/scrutiny/releases
sftpgo https://github.com/drakkan/sftpgo/releases
slskd https://github.com/slskd/slskd/releases
snappymail https://github.com/the-djmaze/snappymail/releases
stirling-pdf https://github.com/Stirling-Tools/Stirling-PDF/releases
sonarr https://github.com/Sonarr/Sonarr/releases/
sonarr-ls https://github.com/linuxserver/docker-sonarr/releases
synapse https://github.com/element-hq/synapse/releases
syncthing https://github.com/syncthing/syncthing/releases
tailscale https://github.com/tailscale/tailscale/releases
tautulli https://github.com/Tautulli/Tautulli/releases
thelounge https://github.com/thelounge/thelounge/releases
traefik https://github.com/traefik/traefik/releases
uptime-kuma https://github.com/louislam/uptime-kuma/releases
vaultwarden-server https://github.com/dani-garcia/vaultwarden/releases
vikunja https://github.com/go-vikunja/vikunja/releases
wallos https://github.com/ellite/Wallos/releases
watchtower https://github.com/beatkind/watchtower/releases
wopiserver https://github.com/cs3org/wopiserver/releases
wud https://github.com/getwud/wud/releases
zigbee2mqtt https://github.com/Koenkk/zigbee2mqtt/releases