Using Watchtower, you can effortlessly update the active version of your containerized application by pulling a fresh image from the Docker Hub or your custom image registry. Watchtower will fetch the updated image, gracefully halt the current container, and then restart it with the same parameters that were applied during its initial deployment. In this tutorial, we’ll approach updating running containers in two ways: by running the Watchtower as a docker container and running it via the shell script.
Table of Contents
Running Watchtower in a container
docker run \
--name=watchtower \
--env=WATCHTOWER_MONITOR_ONLY=true \
--env='WATCHTOWER_NOTIFICATION_URL=ntfy://ntfy.sh/your-ntfy-channel' \
--env=WATCHTOWER_NOTIFICATIONS=shoutrrr \
--env=TZ=Europe/Warsaw \
--env=WATCHTOWER_LIFECYCLE_HOOKS=1 \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--workdir=/ \
--restart=unless-stopped \
--detach=true docker.io/containrrr/watchtower:latest
This Docker run command is creating and starting a Docker container for Watchtower. Let’s break down the components of the command:
docker run
: Initiates the creation and execution of a Docker container.--name=watchtower
: Assigns the name “watchtower” to the Docker container.--env=WATCHTOWER_MONITOR_ONLY=true
: Sets the environment variableWATCHTOWER_MONITOR_ONLY
totrue
, indicating that Watchtower should only monitor for updates but not perform automatic updates. Set the value tofalse
if you want automatic updates of your containers.--env='WATCHTOWER_NOTIFICATION_URL=ntfy://ntfy.sh/your-ntfy-channel'
: Specifies the notification URL for Watchtower updates. In this case, it is set up to use the Ntfy service with a custom channel. Read more about the notification possibilities here: https://containrrr.dev/watchtower/notifications/--env=WATCHTOWER_NOTIFICATIONS=shoutrrr
: Sets the method of notifications to be used when there are updates. Here, it is configured to use the Shoutrrr notification service.--env=TZ=Europe/Warsaw
: Sets the time zone inside the container to Europe/Warsaw. This is important for applications that rely on accurate time information.--env=WATCHTOWER_LIFECYCLE_HOOKS=1
: Enables Watchtower lifecycle hooks, allowing for additional actions to be performed before or after the update process.--volume=/var/run/docker.sock:/var/run/docker.sock
: Mounts the Docker socket from the host into the container. This allows Watchtower to communicate with the Docker daemon on the host and manage other containers.--workdir=/
: Sets the working directory within the container to the root directory.--restart=unless-stopped
: Configures the container to restart automatically unless explicitly stopped.--detach=true
: Runs the container in detached mode, allowing it to operate in the background.docker.io/containrrr/watchtower:latest
: Specifies the Docker image to be used for creating the container. The:latest
tag indicates the use of the latest version of the Watchtower image.
WATCHTOWER_LIFECYCLE_HOOKS
is an environment variable used with Watchtower, a container management tool designed to automatically update running Docker containers to their latest versions. When the WATCHTOWER_LIFECYCLE_HOOKS
variable is set, it enables Watchtower to execute lifecycle hooks during the update process. These hooks allow for additional actions to be performed before or after the update operation.
Lifecycle hooks provide a way to customize the behavior of Watchtower according to specific needs or requirements. By setting the WATCHTOWER_LIFECYCLE_HOOKS
variable, you signal to Watchtower that it should consider and execute any defined hooks during the update process.
For example, you might use lifecycle hooks to perform tasks such as:
- Pre-update tasks: Execute commands or scripts before the container is updated. This could involve stopping certain services, creating backups, or any other preparation steps.
- Post-update tasks: Perform actions after the container has been updated. This might include restarting dependent services, logging the update event, or any other activities needed to ensure a smooth transition.
Running Watchtower in a script (cron)
You can use a helper script I’ve created, that will run Watchower and then send the notification about updated containers to the Apprise endpoint. Apprise allows you to send a notification to almost all of the most popular notification services available to us today such as: email, Telegram, Discord, Slack, Amazon SNS, Gotify, etc.
#!/bin/zsh
#
# Docker Update Check and Notification Script
#
# This script checks for updates in Docker containers using watchtower,
# and sends a notification via Apprise if updates are found. The notification
# includes the number of updated containers and the detailed output from watchtower.
#
# Make sure to set your Apprise notification service URL (APPRISE_URL) before running this script.
#
# Set your Apprise notification service URL
APPRISE_URL="https://your-apprise-url/notify/apprise"
# Specify the watchtower image
WATCHTOWER_IMAGE="docker.io/containrrr/watchtower:latest"
# Function to check for updates and send notification
check_and_notify_updates() {
local updated_containers
local hostname=$(hostname)
# Function to check for updates and update containers
check_and_update_containers() {
echo "Checking for updates..."
updated_containers=$(docker run --name watchtower --rm -v /var/run/docker.sock:/var/run/docker.sock $WATCHTOWER_IMAGE --run-once 2>&1)
echo "watchtower output: $updated_containers"
}
# Function to send notification using curl
send_notification() {
local title="$1"
local body="$2"
curl -k -X POST -F "title=$title" -F "body=$body" "$APPRISE_URL"
}
# Main execution
check_and_update_containers
# Extract the number of updated containers from the output
num_updated_containers=$(echo "$updated_containers" | grep -oP 'Updated=\K\d+')
# Check if there were updates
if [ "$num_updated_containers" -gt 0 ]; then
echo "Updates found. Sending notification..."
send_notification "[$hostname] Docker: $num_updated_containers containers updated" "Watchtower output:\n$updated_containers"
else
echo "No updates found."
fi
}
# Call the function
check_and_notify_updates
The script can be used in cron, for example. Save the above script in a docker_update.zsh
file (I’m assuming your shell is zsh, because why would you still be using bash?) and then execute crontab -e
, then add the following line:
0 3 * * * /home/your-user/scripts/docker_update.zsh
This will check and update your containers every night at 3:00 AM. This is how the output of the script looks like, if you configure Apprise to send notifications to your Gmail inbox:
