Migration Tool
Overview
Watchtower includes a notify-upgrade command to help convert legacy notification configurations to Shoutrrr URLs for use with the NOTIFICATION URL.
It parses legacy Watchtower notification configurations and outputs Shoutrrr URLs to a temporary file inside the Watchtower container.
Usage
The notify-upgrade command converts legacy Watchtower notification configurations into Shoutrrr URLs and writes them to a temporary file inside the container.
Running the Command
The notify-upgrade can be run either against a Watchtower container that is already running or as a single-run instance that allows you to convert a Docker Compose configuration or Docker CLI flag / environment variable configuration.
Existing Deployment
If Watchtower is already deployed and running with your legacy notification configuration, you can execute notify-upgrade directly inside the container:
docker exec watchtower /watchtower notify-upgradeThis works because the Watchtower binary is installed at /watchtower and notify-upgrade is a built-in subcommand.
The common mistake is running docker exec watchtower notify-upgrade, which fails because notify-upgrade is not a standalone executable in $PATH.
notify-upgrade inside an existing container does not stop or restart the main Watchtower process.
docker exec runs a separate, short-lived process.
The only side effect is that the notify-upgrade process will stay alive for up to 5 minutes while waiting for you to retrieve the temporary file, after which it cleans up and exits.Single-Use Run
If you have not yet deployed Watchtower or if you want to run notify-upgrade as a one-off command without starting the persistent Watchtower update loop, then run a temporary container configured with notify-upgrade as the command.
services:
watchtower:
image: nickfedor/watchtower:latest
command: notify-upgrade
environment:
WATCHTOWER_NOTIFICATIONS: email
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: smtp.example.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: 587
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: user@example.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: secret
WATCHTOWER_NOTIFICATION_EMAIL_FROM: sender@example.com
WATCHTOWER_NOTIFICATION_EMAIL_TO: recipient@example.com
volumes:
- /var/run/docker.sock:/var/run/docker.socknotify-upgrade command inspects the container’s current configuration, so it must be started with your legacy notification settings.Retrieving the Generated File
After running notify-upgrade, the converted Shoutrrr URL is written to a temporary file in the container’s working directory, with a filename like watchtower-notif-urls-XXXXXX.
The command logs the exact container path and prints a copy command, for example:
INFO To get the environment file, use: docker cp abc123:watchtower-notif-urls-123456789 ./watchtower-notifications.envCopy it to your local machine with:
docker cp <CONTAINER>:<FILE_PATH> ./watchtower-notifications.envThe temporary file is automatically removed after 5 minutes or when the container stops, so copy it promptly after generation.
If you are running notify-upgrade as a one-off command (docker run --rm ...), the process will wait up to 5 minutes before exiting.
Migration Walkthrough
Select the tab that matches your legacy notification service.
- Run the following Docker Compose configuration / Docker CLI command:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
WATCHTOWER_NOTIFICATIONS: email
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: smtp.example.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: 587
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: user@example.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: secret
WATCHTOWER_NOTIFICATION_EMAIL_FROM: sender@example.com
WATCHTOWER_NOTIFICATION_EMAIL_TO: recipient@example.com
volumes:
- /var/run/docker.sock:/var/run/docker.sock- With the container running, execute the
notify-upgradecommand:
docker exec watchtower /watchtower notify-upgradeThen copy the resulting file out of the container:
docker cp <CONTAINER>:<FILE_PATH> ./watchtower-notifications.env- The following converted Shoutrrr URL should be produced:
smtp://user@example.com:secret@smtp.example.com:587/?fromaddress=sender@example.com&toaddresses=recipient@example.com&encryption=ExplicitTLS&usestarttls=yes- Replace the deprecated configuration with the coverted Shoutrrr URL:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
WATCHTOWER_NOTIFICATION_URL: smtp://user@example.com:secret@smtp.example.com:587/?fromaddress=sender@example.com&toaddresses=recipient@example.com&encryption=ExplicitTLS&usestarttls=yes
WATCHTOWER_NOTIFICATIONS_DELAY: "10"
WATCHTOWER_NOTIFICATION_TITLE_TAG: Watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock- Avoid using unrecognized flags like
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_SSL, as they are ignored and may cause confusion. - Use the
encryptionandusestarttlsURL parameters in thesmtp://URL to control TLS behavior rather than deprecated flags.
Automated Migration Script
If you have a docker-compose.yaml with a watchtower service configured for legacy notifications, you can use the script below to run the entire migration process end-to-end. It starts the container, executes notify-upgrade, extracts the generated file, prints its contents, and cleans up.
#!/usr/bin/env bash
set -euo pipefail
SERVICE="${1:-watchtower}"
OUTPUT="${2:-./watchtower-notifications.env}"
CONTAINER=$(docker compose run -d "${SERVICE}" notify-upgrade)
trap 'docker rm -f "${CONTAINER}" >/dev/null 2>&1 || true' EXIT
if ! docker ps -q --filter "id=${CONTAINER}" | grep -q .; then
echo "notify-upgrade container exited before producing output. Logs:" >&2
docker logs "${CONTAINER}" >&2 || true
exit 1
fi
FILE=""
TIMEOUT=300
INTERVAL=2
ELAPSED=0
while [[ ${ELAPSED} -lt ${TIMEOUT} ]]; do
FILE=$(docker logs "${CONTAINER}" 2>&1 | grep -oE 'watchtower-notif-urls-[^ ]+' | tail -1 || true)
if [[ -n "${FILE}" ]]; then
break
fi
sleep "${INTERVAL}"
ELAPSED=$((ELAPSED + INTERVAL))
done
if [[ -z "${FILE}" ]]; then
echo "Timed out waiting for notify-upgrade output. Logs:" >&2
docker logs "${CONTAINER}" >/dev/null 2>&1 || true
exit 1
fi
docker cp "${CONTAINER}:${FILE}" "${OUTPUT}"
echo "=== Generated Shoutrrr URL ==="
cat "${OUTPUT}"- The service must already be defined in
docker-compose.yamlwith your legacy notification environment variables. The script assumes the service name defaults towatchtower. - The command will self-cleanup after 5 minutes or when the script exits.
- Slack channel customization is not preserved by
notify-upgrade. The generated URL always uses the defaultwebhookchannel. If you need a custom channel, then manually edit the resulting Shoutrrr URL after migration.