Automatically update docker containers whenever new image is released using watchtower.
This is a great solution, especially when you are using portainer for container management (continuous mode) or jenkins (run-once mode). I will focus on the latter solution.
Display help information.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --help
Watchtower automatically updates running Docker containers whenever a new image is released. More information available at https://github.com/containrrr/watchtower/. Usage: watchtower [flags] Flags: -a, --api-version string api version to use by docker client (default "1.25") -c, --cleanup Remove previously used images after updating -d, --debug Enable debug mode with verbose logging --enable-lifecycle-hooks Enable the execution of commands triggered by pre- and post-update lifecycle hooks -h, --help help for watchtower -H, --host string daemon socket to connect to (default "unix:///var/run/docker.sock") --http-api-metrics Runs Watchtower with the Prometheus metrics API enabled --http-api-periodic-polls Also run periodic updates (specified with --interval and --schedule) if HTTP API is enabled --http-api-token string Sets an authentication token to HTTP API requests. --http-api-update Runs Watchtower in HTTP API mode, so that image updates must to be triggered by a request --include-restarting Will also include restarting containers -S, --include-stopped Will also include created and exited containers -i, --interval int Poll interval (in seconds) (default 86400) -e, --label-enable Watch containers where the com.centurylinklabs.watchtower.enable label is true -m, --monitor-only Will only monitor for new images, not update the containers --no-color Disable ANSI color escape codes in log output --no-pull Do not pull any new images --no-restart Do not restart any containers --no-startup-message Prevents watchtower from sending a startup message --notification-email-delay int Delay before sending notifications, expressed in seconds --notification-email-from string Address to send notification emails from --notification-email-server string SMTP server to send notification emails through --notification-email-server-password string SMTP server password for sending notifications --notification-email-server-port int SMTP server port to send notification emails through (default 25) --notification-email-server-tls-skip-verify Controls whether watchtower verifies the SMTP server's certificate chain and host name. Should only be used for testing. --notification-email-server-user string SMTP server user for sending notifications --notification-email-subjecttag string Subject prefix tag for notifications via mail --notification-email-to string Address to send notification emails to --notification-gotify-tls-skip-verify Controls whether watchtower verifies the Gotify server's certificate chain and host name. Should only be used for testing. --notification-gotify-token string The Gotify Application required to query the Gotify API --notification-gotify-url string The Gotify URL to send notifications to --notification-msteams-data The MSTeams notifier will try to extract log entry fields as MSTeams message facts --notification-msteams-hook string The MSTeams WebHook URL to send notifications to --notification-report Use the session report as the notification template data --notification-slack-channel string A string which overrides the webhook's default channel. Example: #my-custom-channel --notification-slack-hook-url string The Slack Hook URL to send notifications to --notification-slack-icon-emoji string An emoji code string to use in place of the default icon --notification-slack-icon-url string An icon image URL string to use in place of the default icon --notification-slack-identifier string A string which will be used to identify the messages coming from this watchtower instance (default "watchtower") --notification-template string The shoutrrr text/template for the messages --notification-url stringArray The shoutrrr URL to send notifications to -n, --notifications strings Notification types to send (valid: email, slack, msteams, gotify, shoutrrr) --notifications-hostname string Custom hostname for notification titles --notifications-level string The log level used for sending notifications. Possible values: panic, fatal, error, warn, info or debug (default "info") --remove-volumes Remove attached volumes before updating --revive-stopped Will also start stopped containers that were updated, if include-stopped is active --rolling-restart Restart containers one at a time -R, --run-once Run once now and exit -s, --schedule string The cron expression which defines when to update --scope string Defines a monitoring scope for the Watchtower instance. -t, --stop-timeout duration Timeout before a container is forcefully stopped (default 10s) -v, --tlsverify use TLS and verify the remote --trace Enable trace mode with very verbose logging - caution, exposes credentials --warn-on-head-failure string When to warn about HEAD pull requests failing. Possible values: always, auto or never
Check every container for new image.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --monitor-only --run-once --no-startup-message
time="2022-08-03T18:53:32Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T18:53:32Z" level=info msg="Using no notifications" notify=no time="2022-08-03T18:53:32Z" level=info msg="Checking all containers (except explicitly disabled with label)" notify=no time="2022-08-03T18:53:32Z" level=info msg="Running a one time update." notify=no time="2022-08-03T18:53:38Z" level=info msg="Found new portainer/portainer-ce:latest image (9b512274f720)" time="2022-08-03T18:53:42Z" level=info msg="Found new vaultwarden/server:latest image (fc5bcff95ea6)" time="2022-08-03T18:53:45Z" level=info msg="Found new jgraph/drawio:latest image (bc01f6bbc120)" time="2022-08-03T18:53:47Z" level=info msg="Found new b4bz/homer:latest image (987af447b8a4)" time="2022-08-03T18:53:49Z" level=info msg="Found new lscr.io/linuxserver/hedgedoc:latest image (0c3e5faf791a)" time="2022-08-03T18:53:51Z" level=info msg="Found new lscr.io/linuxserver/mariadb:latest image (80297b3a5c68)" time="2022-08-03T18:53:55Z" level=info msg="Found new dgtlmoon/changedetection.io:latest image (6c5efaea3f4b)" time="2022-08-03T18:53:58Z" level=info msg="Found new mpepping/cyberchef:latest image (4b4f1b3ee788)" time="2022-08-03T18:54:01Z" level=info msg="Found new searxng/searxng:latest image (fa2dbd23b296)" time="2022-08-03T18:54:04Z" level=info msg="Found new tzahi12345/youtubedl-material:latest image (8fd9447216a4)" time="2022-08-03T18:54:08Z" level=info msg="Found new redis:alpine image (9c5d9fbede14)" time="2022-08-03T18:54:12Z" level=info msg="Found new binwiederhier/ntfy:latest image (d1f2647f8fc8)" time="2022-08-03T18:54:15Z" level=info msg="Found new louislam/uptime-kuma:1 image (01d047a5d477)" time="2022-08-03T18:54:15Z" level=info msg="Session done" Failed=0 Scanned=16 Updated=13 notify=no time="2022-08-03T18:54:15Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Check specific container for new image.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --monitor-only --run-once --no-startup-message vault_vaultwarden_1
time="2022-08-03T19:06:00Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T19:06:00Z" level=info msg="Using no notifications" notify=no time="2022-08-03T19:06:00Z" level=info msg="Only checking containers with name \"vault_vaultwarden_1\"" notify=no time="2022-08-03T19:06:00Z" level=info msg="Running a one time update." notify=no time="2022-08-03T19:06:03Z" level=info msg="Found new vaultwarden/server:latest image (fc5bcff95ea6)" time="2022-08-03T19:06:03Z" level=info msg="Session done" Failed=0 Scanned=1 Updated=1 notify=no time="2022-08-03T19:06:03Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Update specific container.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once --no-startup-message vault_vaultwarden_1
time="2022-08-03T19:07:28Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T19:07:28Z" level=info msg="Using no notifications" notify=no time="2022-08-03T19:07:28Z" level=info msg="Only checking containers with name \"vault_vaultwarden_1\"" notify=no time="2022-08-03T19:07:28Z" level=info msg="Running a one time update." notify=no time="2022-08-03T19:07:32Z" level=info msg="Found new vaultwarden/server:latest image (fc5bcff95ea6)" time="2022-08-03T19:07:32Z" level=info msg="Stopping /vault_vaultwarden_1 (355f21ac33a2) with SIGTERM" time="2022-08-03T19:07:34Z" level=info msg="Creating /vault_vaultwarden_1" time="2022-08-03T19:07:36Z" level=info msg="Session done" Failed=0 Scanned=1 Updated=1 notify=no time="2022-08-03T19:07:36Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Update specific container and remove old image.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once --no-startup-message --cleanup ytdl_ytdl_material_1
time="2022-08-03T19:10:22Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T19:10:22Z" level=info msg="Using no notifications" notify=no time="2022-08-03T19:10:22Z" level=info msg="Only checking containers with name \"ytdl_ytdl_material_1\"" notify=no time="2022-08-03T19:10:22Z" level=info msg="Running a one time update." notify=no time="2022-08-03T19:10:26Z" level=info msg="Found new tzahi12345/youtubedl-material:latest image (8fd9447216a4)" time="2022-08-03T19:10:26Z" level=info msg="Stopping /ytdl_ytdl_material_1 (8ca23375b28c) with SIGTERM" time="2022-08-03T19:10:37Z" level=info msg="Creating /ytdl_ytdl_material_1" time="2022-08-03T19:10:39Z" level=info msg="Removing image d599d76ad855" time="2022-08-03T19:11:09Z" level=info msg="Session done" Failed=0 Scanned=1 Updated=1 notify=no time="2022-08-03T19:11:09Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Update specific container, display debug information and remove old image.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once --no-startup-message --cleanup --debug docs_hedgedoc_1
time="2022-08-03T19:11:45Z" level=debug time="2022-08-03T19:11:45Z" level=debug msg="Sleeping for a second to ensure the docker api client has been properly initialized." time="2022-08-03T19:11:46Z" level=debug msg="Making sure everything is sane before starting" time="2022-08-03T19:11:46Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T19:11:46Z" level=info msg="Using no notifications" notify=no time="2022-08-03T19:11:46Z" level=info msg="Only checking containers with name \"docs_hedgedoc_1\"" notify=no time="2022-08-03T19:11:46Z" level=info msg="Running a one time update." notify=no time="2022-08-03T19:11:46Z" level=debug msg="Checking containers for updated images" time="2022-08-03T19:11:46Z" level=debug msg="Retrieving running containers" time="2022-08-03T19:11:46Z" level=debug msg="Trying to load authentication credentials." container=/docs_hedgedoc_1 image="lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:46Z" level=debug msg="No credentials for lscr.io found" config_file=/config.json time="2022-08-03T19:11:46Z" level=debug msg="Got image name: lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:46Z" level=debug msg="Checking if pull is needed" container=/docs_hedgedoc_1 image="lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:46Z" level=debug msg="Building challenge URL" URL="https://lscr.io/v2/" time="2022-08-03T19:11:46Z" level=debug msg="Got response to challenge request" header="Bearer realm=\"https://ghcr.io/token\",service=\"ghcr.io\",scope=\"repository:user/image:pull\"" status="401 Unauthorized" time="2022-08-03T19:11:46Z" level=debug msg="Checking challenge header content" realm="https://ghcr.io/token" service=ghcr.io time="2022-08-03T19:11:46Z" level=debug msg="Setting scope for auth token" image=lscr.io/linuxserver/hedgedoc scope="repository:lscr.io/linuxserver/hedgedoc:pull" time="2022-08-03T19:11:46Z" level=debug msg="No credentials found." time="2022-08-03T19:11:47Z" level=debug msg="Parsing image ref" host=lscr.io image=linuxserver/hedgedoc normalized="lscr.io/linuxserver/hedgedoc:latest" tag=latest time="2022-08-03T19:11:47Z" level=debug msg="Doing a HEAD request to fetch a digest" url="https://lscr.io/v2/linuxserver/hedgedoc/manifests/latest" time="2022-08-03T19:11:47Z" level=debug msg="Could not do a head request for \"lscr.io/linuxserver/hedgedoc:latest\", falling back to regular pull." container=/docs_hedgedoc_1 image="lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:47Z" level=debug msg="Reason: registry responded to head request with \"401 Unauthorized\", auth: \"Bearer realm=\\\"https://ghcr.io/token\\\",service=\\\"ghcr.io\\\",scope=\\\"repository:linuxserver/hedgedoc:pull\\\"\"" container=/docs_hedgedoc_1 image="lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:47Z" level=debug msg="Pulling image" container=/docs_hedgedoc_1 image="lscr.io/linuxserver/hedgedoc:latest" time="2022-08-03T19:11:48Z" level=info msg="Found new lscr.io/linuxserver/hedgedoc:latest image (0c3e5faf791a)" time="2022-08-03T19:11:48Z" level=info msg="Stopping /docs_hedgedoc_1 (cf864823fb44) with SIGTERM" time="2022-08-03T19:11:54Z" level=debug msg="Removing container cf864823fb44" time="2022-08-03T19:11:55Z" level=info msg="Creating /docs_hedgedoc_1" time="2022-08-03T19:11:55Z" level=debug msg="Starting container /docs_hedgedoc_1 (2589a6687b58)" time="2022-08-03T19:11:57Z" level=info msg="Removing image 96ed4362fd19" time="2022-08-03T19:12:29Z" level=info msg="Session done" Failed=0 Scanned=1 Updated=1 notify=no time="2022-08-03T19:12:29Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Check every container for new image and send notification using ntfy.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --monitor-only --run-once --no-startup-message --notifications shoutrrr --notification-url "generic+https://notify.octocat.cloud/watchtower?title=WatchtowerUpdates"
time="2022-08-03T19:26:42Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T19:26:42Z" level=info msg="Using notifications: generic+https" notify=no time="2022-08-03T19:26:42Z" level=info msg="Checking all containers (except explicitly disabled with label)" notify=no time="2022-08-03T19:26:42Z" level=info msg="Running a one time update." notify=no time="2022-08-03T19:26:54Z" level=info msg="Found new portainer/portainer-ce:latest image (9b512274f720)" time="2022-08-03T19:26:57Z" level=info msg="Found new jgraph/drawio:latest image (bc01f6bbc120)" time="2022-08-03T19:27:00Z" level=info msg="Found new b4bz/homer:latest image (987af447b8a4)" time="2022-08-03T19:27:02Z" level=info msg="Found new lscr.io/linuxserver/mariadb:latest image (80297b3a5c68)" time="2022-08-03T19:27:05Z" level=info msg="Found new dgtlmoon/changedetection.io:latest image (6c5efaea3f4b)" time="2022-08-03T19:27:08Z" level=info msg="Found new mpepping/cyberchef:latest image (4b4f1b3ee788)" time="2022-08-03T19:27:11Z" level=info msg="Found new searxng/searxng:latest image (fa2dbd23b296)" time="2022-08-03T19:27:14Z" level=info msg="Found new redis:alpine image (9c5d9fbede14)" time="2022-08-03T19:27:20Z" level=info msg="Found new binwiederhier/ntfy:latest image (d1f2647f8fc8)" time="2022-08-03T19:27:23Z" level=info msg="Found new louislam/uptime-kuma:1 image (01d047a5d477)" time="2022-08-03T19:27:23Z" level=info msg="Session done" Failed=0 Scanned=16 Updated=10 notify=no time="2022-08-03T19:27:23Z" level=info msg="Waiting for the notification goroutine to finish" notify=no

Update every running container and remove old images.
$ docker run -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once --no-startup-message --cleanup
time="2022-08-03T21:22:25Z" level=info msg="Watchtower 1.4.0" notify=no time="2022-08-03T21:22:25Z" level=info msg="Using no notifications" notify=no time="2022-08-03T21:22:25Z" level=info msg="Checking all containers (except explicitly disabled with label)" notify=no time="2022-08-03T21:22:25Z" level=info msg="Running a one time update." notify=no time="2022-08-03T21:22:37Z" level=info msg="Found new portainer/portainer-ce:latest image (9b512274f720)" time="2022-08-03T21:22:40Z" level=info msg="Found new jgraph/drawio:latest image (bc01f6bbc120)" time="2022-08-03T21:22:43Z" level=info msg="Found new b4bz/homer:latest image (987af447b8a4)" time="2022-08-03T21:22:45Z" level=info msg="Found new lscr.io/linuxserver/mariadb:latest image (80297b3a5c68)" time="2022-08-03T21:22:48Z" level=info msg="Found new dgtlmoon/changedetection.io:latest image (6c5efaea3f4b)" time="2022-08-03T21:22:52Z" level=info msg="Found new mpepping/cyberchef:latest image (4b4f1b3ee788)" time="2022-08-03T21:22:55Z" level=info msg="Found new searxng/searxng:latest image (fa2dbd23b296)" time="2022-08-03T21:22:58Z" level=info msg="Found new redis:alpine image (9c5d9fbede14)" time="2022-08-03T21:23:03Z" level=info msg="Found new binwiederhier/ntfy:latest image (d1f2647f8fc8)" time="2022-08-03T21:23:06Z" level=info msg="Found new louislam/uptime-kuma:1 image (01d047a5d477)" time="2022-08-03T21:23:06Z" level=info msg="Stopping /uptime_uptime-kuma_1 (8b598f8c9d9f) with SIGTERM" time="2022-08-03T21:23:11Z" level=info msg="Stopping /notify_ntfy_1 (5fca2dbaf9d6) with SIGTERM" time="2022-08-03T21:23:12Z" level=info msg="Stopping /search_redis-search_1 (9f0434ef8988) with SIGTERM" time="2022-08-03T21:23:14Z" level=info msg="Stopping /search_search_1 (00eb06fe2ee1) with SIGTERM" time="2022-08-03T21:23:25Z" level=info msg="Stopping /toolbox_toolbox_1 (f8d669809c9c) with SIGTERM" time="2022-08-03T21:23:26Z" level=info msg="Stopping /changedetection_changedetection_1 (ece9f2884be8) with SIGTERM" time="2022-08-03T21:23:37Z" level=info msg="Stopping /docs_mariadb_1 (0225cbf2d76a) with SIGTERM" time="2022-08-03T21:23:42Z" level=info msg="Stopping /dashboard_homer_1 (7bd7f4cf0def) with SIGTERM" time="2022-08-03T21:23:44Z" level=info msg="Stopping /draw_draw_1 (650ecd8cbd02) with SIGTERM" time="2022-08-03T21:23:47Z" level=info msg="Stopping /portainer (4417ada44347) with SIGTERM" time="2022-08-03T21:23:48Z" level=info msg="Creating /portainer" time="2022-08-03T21:23:50Z" level=info msg="Creating /draw_draw_1" time="2022-08-03T21:23:54Z" level=info msg="Creating /dashboard_homer_1" time="2022-08-03T21:23:57Z" level=info msg="Creating /docs_mariadb_1" time="2022-08-03T21:24:00Z" level=info msg="Creating /changedetection_changedetection_1" time="2022-08-03T21:24:03Z" level=info msg="Creating /toolbox_toolbox_1" time="2022-08-03T21:24:08Z" level=info msg="Creating /search_search_1" time="2022-08-03T21:24:12Z" level=info msg="Creating /search_redis-search_1" time="2022-08-03T21:24:16Z" level=info msg="Creating /notify_ntfy_1" time="2022-08-03T21:24:20Z" level=info msg="Creating /uptime_uptime-kuma_1" time="2022-08-03T21:24:24Z" level=info msg="Removing image 0153b5916fa4" time="2022-08-03T21:24:24Z" level=info msg="Removing image 9dcd83a87127" time="2022-08-03T21:24:25Z" level=info msg="Removing image 6cc6dadb6baa" time="2022-08-03T21:24:30Z" level=info msg="Removing image bf7b7ef595d0" time="2022-08-03T21:25:06Z" level=info msg="Removing image 465a74a8f1d2" time="2022-08-03T21:25:07Z" level=info msg="Removing image 42020bc23b55" time="2022-08-03T21:25:07Z" level=info msg="Removing image ee24f59e6e26" time="2022-08-03T21:25:10Z" level=info msg="Removing image 1de7398797c7" time="2022-08-03T21:25:10Z" level=info msg="Removing image 3a6672e62038" time="2022-08-03T21:25:14Z" level=info msg="Removing image e5c6e4452448" time="2022-08-03T21:25:14Z" level=info msg="Session done" Failed=0 Scanned=16 Updated=10 notify=no time="2022-08-03T21:25:14Z" level=info msg="Waiting for the notification goroutine to finish" notify=no
Simple as that.