### Install Mike Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Install the Mike tool using pip. This is the first step to enable versioned documentation. ```bash pip install mike ``` -------------------------------- ### Install MkDocs Dependencies Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Installs the necessary Python packages for building and serving the documentation. Ensure your virtual environment is activated. ```bash pip install -r build/mkdocs/docs-requirements.txt ``` -------------------------------- ### Check Go Version Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Verify your installed Go version. Ensure you have the latest version installed. ```bash go version ``` -------------------------------- ### Docker Compose Example with Custom Template Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md This example demonstrates how to configure Watchtower with a custom notification template using Docker Compose. ```yaml services: watchtower: image: watchtower-image volumes: - /var/run/docker.sock:/var/run/docker.sock environment: WATCHTOWER_NOTIFICATION_REPORT: "true" WATCHTOWER_NOTIFICATION_URL: > discord://token@channel slack://watchtower@token-a/token-b/token-c WATCHTOWER_NOTIFICATION_TEMPLATE: | {{- if .Report -}} {{- with .Report -}} {{len .Scanned}} Scanned, {{len .Updated}} Updated, {{len .Restarted}} Restarted, {{len .Failed}} Failed {{- if ( or .Updated .Restarted .Failed ) -}} {{- range .Updated -}} - {{.Name}} ({{.ImageName}}): {{.CurrentImageID.ShortID}} updated to {{.LatestImageID.ShortID}} {{- end -}} {{- range .Fresh -}} - {{.Name}} ({{.ImageName}}): {{.State}} {{- end -}} {{- range .Restarted -}} - {{.Name}} ({{.ImageName}}): {{.State}} {{- end -}} {{- range .Skipped -}} - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} {{- end -}} {{- range .Failed -}} - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} {{- end -}} {{- end -}} {{- end -}} {{- if .Entries -}} Logs: {{- end -}} {{- range .Entries -}}{{.Time.Format "2006-01-02T15:04:05Z07:00"}} [{{.Level}}] {{.Message}}{{"\n"}}{{- end -}} {{- end -}} ``` -------------------------------- ### Docker CLI Example with Custom Template Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md This example shows how to run Watchtower using the Docker CLI and set a custom notification template via an environment variable. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATION_REPORT="true" \ -e WATCHTOWER_NOTIFICATION_TEMPLATE="\ {{- if .Report -}} \ {{- with .Report -}} \ {{len .Scanned}} Scanned, {{len .Updated}} Updated, {{len .Restarted}} Restarted, {{len .Failed}} Failed \ {{- if ( or .Updated .Restarted .Failed ) -}} \ {{- range .Updated -}} \ - {{.Name}} ({{.ImageName}}): {{.CurrentImageID.ShortID}} updated to {{.LatestImageID.ShortID}} \ {{- end -}} \ {{- range .Fresh -}} \ - {{.Name}} ({{.ImageName}}): {{.State}} \ {{- end -}} \ {{- range .Restarted -}} \ - {{.Name}} ({{.ImageName}}): {{.State}} \ {{- end -}} \ {{- range .Skipped -}} \ - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} \ {{- end -}} \ {{- range .Failed -}} \ - {{.Name}} ({{.ImageName}}): {{.State}}: {{.Error}} \ {{- end -}} \ {{- end -}} \ {{- end -}} \ {{- if .Entries -}} \ \ Logs: \ {{- end -}} \ {{- range .Entries -}}{{.Time.Format \"2006-01-02T15:04:05Z07:00\"}} [{{.Level}}] {{.Message}}{{`\n`}}{{- end -}} \ {{- end -}} \ " \ watchtower-image ``` -------------------------------- ### Example Output for Found New Image Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md Example output for a log entry with msg="Found new image" when using the simple template. ```text Found new image: repo/image:latest (abcdef123456) ``` -------------------------------- ### Docker Compose Configuration with HTTP API Enabled Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/http-api/index.md Example Docker Compose setup for Watchtower, enabling the HTTP API for updates and metrics, and configuring port mappings. ```yaml services: app-monitored-by-watchtower: image: myapps/monitored-by-watchtower labels: - "com.centurylinklabs.watchtower.enable=true" watchtower: image: nickfedor/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock command: --http-api-update --http-api-metrics environment: - WATCHTOWER_HTTP_API_TOKEN=mytoken labels: - "com.centurylinklabs.watchtower.enable=false" ports: - 8080:8080 restart: unless-stopped ``` -------------------------------- ### Example Notification Output Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md This is an example of the output generated by the default report template for a session with one updated container and an error log. ```text 5 Scanned, 1 Updated, 1 Restarted, 0 Failed - /container (repo/image:latest): abcdef12 updated to 34567890 - /restarted-container (repo/image:latest): Restarted Logs: 2025-08-20T06:00:13-07:00 [error] Operation failed. Try again later. ``` -------------------------------- ### Download Watchtower Binary for Windows (amd64) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/installation/index.md This PowerShell script downloads, extracts, and installs the Watchtower executable for Windows (amd64) to the current directory. It checks for successful installation. ```powershell iwr (iwr https://api.github.com/repos/nicholas-fedor/watchtower/releases/latest | ConvertFrom-Json).assets.where({$_.name -like "*windows_amd64*.zip"}).browser_download_url -OutFile watchtower.zip; Add-Type -AssemblyName System.IO.Compression.FileSystem; $zip = [System.IO.Compression.ZipFile]::OpenRead("$PWD\watchtower.zip"); $zip.Entries | Where-Object {$_.Name -eq 'watchtower.exe'} | ForEach-Object {[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, "$PWD\watchtower.exe", $true)}; $zip.Dispose(); Remove-Item watchtower.zip; if (Test-Path ".\watchtower.exe") { Write-Host "Successfully installed watchtower.exe to current directory" } else { Write-Host "Failed to install watchtower.exe" } ``` -------------------------------- ### Declare Multiple Dependencies Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md This example demonstrates how to declare multiple dependencies for a service using the Watchtower depends-on label. ```dockerfile LABEL com.centurylinklabs.watchtower.depends-on="database,cache,queue" ``` -------------------------------- ### Define Post-update Hook Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Set up a post-update hook using a Docker label. This command runs after the new container has started. The monitored container must have the necessary tools installed. ```dockerfile LABEL com.centurylinklabs.watchtower.lifecycle.post-update="echo 'Container updated successfully'" ``` -------------------------------- ### Docker Run Commands for Legacy Links Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md Demonstrates starting a database and a web application with a legacy Docker link. Watchtower respects these links for update sequencing. ```bash docker run -d --name mysql mysql:8.0 ``` ```bash docker run -d --name webapp --link mysql:db nginx ``` -------------------------------- ### Example Gotify Configuration using Docker CLI Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure Gotify notifications by providing a `gotify://` URL directly in the Docker CLI command. This is the recommended method. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --notification-url "gotify://my.gotify.tld/SuperSecretToken" ``` -------------------------------- ### Docker Compose for Private Registry Monitoring Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/usage/index.md A complete docker-compose.yml file to run a container from a private registry (GitHub Registry example) and monitor it with Watchtower. This example also customizes the update interval. ```yaml version: "3" services: cavo: image: ghcr.io//: ports: - "443:3443" - "80:3080" watchtower: image: nickfedor/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock - /root/.docker/config.json:/config.json command: --interval 30 ``` -------------------------------- ### Build Documentation Locally Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Builds the static documentation site locally for validation. This command checks for errors without starting a server. ```bash mkdocs build --config-file build/mkdocs/mkdocs.yaml ``` -------------------------------- ### Create and Activate Python Virtual Environment Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Sets up an isolated Python environment for managing project dependencies. Activate it before installing packages. ```bash python -m venv watchtower-docs . watchtower-docs/bin/activate ``` -------------------------------- ### Configure Single Global Mirror in daemon.json Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/registry-mirrors/index.md Example of configuring a single global registry mirror within the Docker daemon's configuration file. ```json { "registry-mirrors": [ "https://docker-mirror.company.com" ] } ``` -------------------------------- ### Example MSTeams Configuration using Docker CLI Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure Microsoft Teams notifications using the `teams://` URL format with Docker CLI. This is the recommended method. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --notification-url "teams:?color=%23406170&host=https://default.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/abc123/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=XXXXXXXX" ``` -------------------------------- ### Clone Watchtower Repository Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Use this command to clone the Watchtower repository locally. Ensure you have Git installed. ```bash git clone https://github.com/nicholas-fedor/watchtower.git cd watchtower ``` -------------------------------- ### Enable Split Notifications Per Container Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example demonstrating how to configure Watchtower to send individual notifications for each updated container. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATION_URL="slack://hook:xxxx-yyyy-zzzz@webhook?botname=watchtower" \ -e WATCHTOWER_NOTIFICATION_SPLIT_BY_CONTAINER=true \ nickfedor/watchtower ``` -------------------------------- ### Example MSTeams Configuration using Docker Compose Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure Microsoft Teams notifications using the `teams://` URL format with Docker Compose. This is the recommended method. ```yaml services: watchtower: image: nickfedor/watchtower:latest environment: WATCHTOWER_NOTIFICATION_URL: "teams:?color=%23406170&host=https://default.environment.api.powerplatform.com/powerautomate/automations/direct/workflows/abc123/triggers/manual/paths/invoke?api-version=1&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=XXXXXXXX" volumes: - /var/run/docker.sock:/var/run/docker.sock ``` -------------------------------- ### Watchtower Notification Summary Log Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example log output from Watchtower indicating the successfully parsed notification services upon startup. ```text time="2026-01-28T16:07:24+01:00" level=info msg="Using notifications: discord, telegram" ``` -------------------------------- ### Example Legacy Email Notification Configuration (Docker CLI Flags) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md This snippet demonstrates the legacy configuration for email notifications using command-line flags with Docker CLI. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --notifications email \ --notification-email-server smtp.example.com \ --notification-email-server-port 587 \ --notification-email-server-user user@example.com \ --notification-email-server-password secret \ --notification-email-from sender@example.com \ --notification-email-to recipient@example.com ``` -------------------------------- ### Example Legacy Email Notification Configuration (Docker Compose) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md This snippet shows the legacy configuration for email notifications using Docker Compose. ```yaml 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 ``` -------------------------------- ### Monitor a Container with a Per-Container Cooldown via Docker CLI Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/image-cooldown/index.md Start a container and apply a specific cooldown delay of 72 hours using a label. ```bash docker run -d \ --name myapp \ --label=com.centurylinklabs.watchtower.cooldown-delay="72h" \ myorg/myapp:latest ``` -------------------------------- ### Example Docker Compose Deployment with Go Hook Source: https://github.com/nicholas-fedor/watchtower/blob/main/examples/lifecycle-hooks/synology-stop/README.md Deploy Watchtower and a service (e.g., nginx) using Docker Compose. The service is configured to use the Go implementation of the Synology stop hook as a pre-update lifecycle hook. ```yaml services: watchtower: image: nicholas-fedor/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: WATCHTOWER_LIFECYCLE_HOOKS: true restart: unless-stopped nginx: image: nginx:latest volumes: - ./Scripts/synology-stop:/synology-stop:ro ports: - 8080:80 labels: - com.centurylinklabs.watchtower.lifecycle.pre-update: "/synology-stop" environment: - SYNO_URL=http://192.168.1.100:5000 - SYNO_USER=watchtower - SYNO_PASS=supersecretpassword ``` -------------------------------- ### Download Watchtower Binary for Linux (amd64) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/installation/index.md This Bash script downloads and extracts the Watchtower binary for Linux (amd64) to the current directory. It verifies if the binary was successfully installed. ```bash curl -L $(curl -s https://api.github.com/repos/nicholas-fedor/watchtower/releases/latest | grep -o 'https://[^"']*) | tar -xz -C . watchtower && if [ -f ./watchtower ]; then echo "Successfully installed watchtower to current directory"; else echo "Failed to install watchtower"; fi ``` -------------------------------- ### Backup Logic Based on Labels Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Customize backup behavior using container labels. This example uses a 'backup-type' label to determine if a full, incremental, or default backup should be performed. Requires jq. ```bash #!/bin/bash BACKUP_TYPE=$(echo $WT_CONTAINER | jq -r '.labels["com.centurylinklabs.watchtower.backup-type"] // "default"') case $BACKUP_TYPE in "full") echo "Performing full backup" # Full backup logic ;; "incremental") echo "Performing incremental backup" # Incremental backup logic ;; *) echo "Performing default backup" # Default backup logic ;; esac ``` -------------------------------- ### Example Gotify Configuration using Docker Compose Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure Gotify notifications using Docker Compose by setting the `WATCHTOWER_NOTIFICATION_URL` environment variable with a `gotify://` URL. This is the recommended method. ```yaml services: watchtower: image: nickfedor/watchtower:latest environment: WATCHTOWER_NOTIFICATION_URL: "gotify://my.gotify.tld/SuperSecretToken" volumes: - /var/run/docker.sock:/var/run/docker.sock ``` -------------------------------- ### Mount config.json in Docker Run Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/private-registries/index.md Mount the created `config.json` file into the Watchtower container when starting it with `docker run`. ```bash docker run [...] -v /config.json:/config.json nickfedor/watchtower ``` -------------------------------- ### Example Legacy Email Notification Configuration (Docker CLI Env Vars) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md This snippet shows the legacy configuration for email notifications using environment variables with Docker CLI. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ -e WATCHTOWER_NOTIFICATIONS=email \ -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.example.com \ -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587 \ -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=user@example.com \ -e WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=secret \ -e WATCHTOWER_NOTIFICATION_EMAIL_FROM=sender@example.com \ -e WATCHTOWER_NOTIFICATION_EMAIL_TO=recipient@example.com \ nickfedor/watchtower ``` -------------------------------- ### Monitor nginx:latest Container Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/overview/index.md This example shows a container running the 'nginx:latest' image. Watchtower will update this container if the 'latest' tag on the nginx image is updated. Be aware that 'latest' can include breaking changes. ```bash CONTAINER ID IMAGE STATUS PORTS NAMES abc123def456 nginx:latest Up 10 minutes 0.0.0.0:80->80/tcp webserver ``` -------------------------------- ### Start Watchtower with a Global Cooldown via Docker CLI Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/image-cooldown/index.md Run Watchtower as a container and set a global cooldown delay of 24 hours using an environment variable. ```bash docker run -d \ --name watchtower \ -e WATCHTOWER_COOLDOWN_DELAY=24h \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower ``` -------------------------------- ### Run Watchtower Container Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/usage/index.md Start the Watchtower container in detached mode. Ensure the Docker socket is mounted for Watchtower to interact with the Docker API. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ --restart unless-stopped \ nickfedor/watchtower ``` -------------------------------- ### Monitor nginx:1.29 Container Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/overview/index.md This example demonstrates a container using a specific semantic version tag, 'nginx:1.29'. Watchtower will update this container only when new patch versions within the 1.29 series are released and tagged as '1.29'. ```bash CONTAINER ID IMAGE STATUS PORTS NAMES def456ghi789 nginx:1.29 Up 10 minutes 0.0.0.0:80->80/tcp webserver ``` -------------------------------- ### Serve All Deployed Versions Locally Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Serve all deployed versions of the documentation locally for testing version switching and navigation. Ensure 'mike deploy' has been run first. ```bash mike serve --config-file build/mkdocs/mkdocs.yaml ``` -------------------------------- ### Build Application Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Compile and package the Watchtower executable binary. Ensure GO111MODULE is set if needed. ```bash go build ``` -------------------------------- ### Serve Single Version Locally with MkDocs Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Serve the current documentation state locally for quick previews during development without versioning features. This does not require deployment commits. ```bash mkdocs serve --config-file build/mkdocs/mkdocs.yaml ``` -------------------------------- ### Backup Logic Based on Container State Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Implement conditional backup logic based on container names or other state information. This example checks if a container is part of a 'prod' environment. ```bash #!/bin/bash CONTAINER_NAME=$(echo $WT_CONTAINER | jq -r '.name') # Check if this is a production container if [[ $CONTAINER_NAME == *"prod"* ]]; then echo "Production container - extra caution" # Additional safety checks else echo "Non-production container - proceeding" fi ``` -------------------------------- ### Monitor pihole:2023.11 Container Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/overview/index.md This example shows a container running 'pihole/pihole:2023.11', illustrating a date-based tagging scheme. Watchtower will update this container to the latest patch within the '2023.11' period but not to subsequent monthly or yearly releases. ```bash CONTAINER ID IMAGE STATUS PORTS NAMES ghi789jkl012 pihole/pihole:2023.11 Up 10 minutes 0.0.0.0:8080->80/tcp pihole ``` -------------------------------- ### Build Go Binary for Synology Hook Source: https://github.com/nicholas-fedor/watchtower/blob/main/examples/lifecycle-hooks/synology-stop/README.md Build the Go binary for the Synology pre-update hook. Ensure you are in the correct directory and specify the target OS and architecture. ```bash cd examples/lifecycle-hooks/synology-stop GOOS=linux GOARCH=arm64 go build -o synology-stop synology-stop.go ``` -------------------------------- ### Build and Run Hook for Testing Source: https://github.com/nicholas-fedor/watchtower/blob/main/examples/lifecycle-hooks/synology-stop/README.md Build the Go hook binary and make it executable, then run Watchtower in one-off mode to trigger an update for a specified container, testing the lifecycle hook. ```bash go build -o synology-stop synology-stop.go && chmod +x synology-stop docker run --rm nicholas-fedor/watchtower --run-once nginx ``` -------------------------------- ### Signal URL Format - Group Only Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a Signal notification URL format for sending to a specific group. ```plaintext signal://localhost:8080/+1234567890/group.abcdefghijklmnop= ``` -------------------------------- ### Get Stop Signal in Python Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Parses the WT_CONTAINER environment variable as JSON to access the stop signal. ```python import os import json container_info = json.loads(os.environ['WT_CONTAINER']) print(f"Stop signal: {container_info['stop_signal']}") ``` -------------------------------- ### Build Template Preview Script Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Makes the template preview build script executable and then runs it. This script is part of the documentation build process. ```bash chmod +x scripts/build-tplprev.sh ./scripts/build-tplprev.sh ``` -------------------------------- ### Get Image Name in Python Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Parses the WT_CONTAINER environment variable as JSON to access the image name. ```python import os import json container_info = json.loads(os.environ['WT_CONTAINER']) print(f"Image: {container_info['image_name']}") ``` -------------------------------- ### Deploy Version Locally with Mike Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Build and commit documentation to a local Git branch for a specific version. Use --config-file to specify the mkdocs.yaml path. The --push flag is required to push to a remote repository. ```bash mike deploy --config-file build/mkdocs/mkdocs.yaml ``` ```bash mike deploy --config-file build/mkdocs/mkdocs.yaml ``` -------------------------------- ### Get Container ID in Python Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Parses the WT_CONTAINER environment variable as JSON to access the container ID. ```python import os import json container_info = json.loads(os.environ['WT_CONTAINER']) print(f"Container ID: {container_info['id']}") ``` -------------------------------- ### Get Container Name in Python Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Parses the WT_CONTAINER environment variable as JSON to access the container name. ```python import os import json container_info = json.loads(os.environ['WT_CONTAINER']) print(f"Processing container: {container_info['name']}") ``` -------------------------------- ### Get Stop Signal in Bash Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Extracts the stop signal from the WT_CONTAINER environment variable using jq. ```bash #!/bin/bash SIGNAL=$(echo $WT_CONTAINER | jq -r '.stop_signal') echo "Stop signal: $SIGNAL" ``` -------------------------------- ### Build Production Binaries Locally Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Use this command to build Watchtower binaries and archives for local testing in snapshot mode. It utilizes the production GoReleaser configuration. ```bash goreleaser release --config build/goreleaser/prod.yml --snapshot --clean ``` -------------------------------- ### Get Image Name in Bash Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Extracts the image name from the WT_CONTAINER environment variable using jq. ```bash #!/bin/bash IMAGE=$(echo $WT_CONTAINER | jq -r '.image_name') echo "Image: $IMAGE" ``` -------------------------------- ### Get Container ID in Bash Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Extracts the container ID from the WT_CONTAINER environment variable using jq. ```bash #!/bin/bash CONTAINER_ID=$(echo $WT_CONTAINER | jq -r '.id') echo "Container ID: $CONTAINER_ID" ``` -------------------------------- ### Get Container Name in Bash Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Extracts the container name from the WT_CONTAINER environment variable using jq. ```bash #!/bin/bash CONTAINER_NAME=$(echo $WT_CONTAINER | jq -r '.name') echo "Processing container: $CONTAINER_NAME" ``` -------------------------------- ### Default Simple Template Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md This template processes info-level log entries in real-time, formatting key update events. It sends each event immediately, mimicking a step-by-step log. ```go {{- range $i, $e := . -}} {{- if $i}}{{- println -}}{{- end -}} {{- $msg := $e.Message -}} {{- if eq $msg "Found new image" -}} Found new image: {{$e.Data.image}} ({{with $e.Data.new_id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Stopping container" -}} Stopped stale container: {{$e.Data.container}} ({{with $e.Data.id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Started new container" -}} Started new container: {{$e.Data.container}} ({{with $e.Data.new_id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Removing image" -}} Removed stale image: {{with $e.Data.image_id}}{{.}}{{else}}unknown{{end}} {{- else if eq $msg "Detected multiple Watchtower instances - initiating cleanup" -}} Detected {{$e.Data.count}} Watchtower instances - initiating cleanup {{- else if $e.Data -}} {{$msg}} | {{range $k, $v := $e.Data -}}{{$k}}={{$v}} {{- end}} {{- else -}} {{$msg}} {{- end -}} {{- end -}} ``` -------------------------------- ### Build Local Watchtower Docker Image Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Build a Watchtower Docker image from your current local Watchtower files. Ensure you are in the root directory of the project. ```bash docker build . -f build/docker/Dockerfile.self-local -t nickfedor/watchtower # to build an image from local files ``` -------------------------------- ### Sending Signal Notifications with Attachments Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of sending a Signal message with base64-encoded attachments using the shoutrrr CLI. ```bash shoutrrr send "signal://localhost:8080/+1234567890/+0987654321" \ "Message with attachment" \ --attachments "base64data1,base64data2" ``` -------------------------------- ### Simple Template for Template Preview Tool Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/templates/index.md This template is adapted for the Template Preview Tool, matching its data structure by ranging over `.Entries`. It formats log entries similarly to the default simple template. ```go {{- range $i, $e := .Entries -}} {{- if $i}}{{- println -}}{{- end -}} {{- $msg := $e.Message -}} {{- if eq $msg "Found new image" -}} Found new image: {{$e.Data.image}} ({{with $e.Data.new_id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Stopping container" -}} Stopped stale container: {{$e.Data.container}} ({{with $e.Data.id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Started new container" -}} Started new container: {{$e.Data.container}} ({{with $e.Data.new_id}}{{.}}{{else}}unknown{{end}}) {{- else if eq $msg "Removing image" -}} Removed stale image: {{with $e.Data.image_id}}{{.}}{{else}}unknown{{end}} {{- else if eq $msg "Detected multiple Watchtower instances - initiating cleanup" -}} Detected {{$e.Data.count}} Watchtower instances - initiating cleanup {{- else if $e.Data -}} {{$msg}} | {{range $k, $v := $e.Data -}}{{$k}}={{$v}} {{- end}} {{- else -}} {{$msg}} {{- end -}} {{- end -}} ``` -------------------------------- ### Get Stop Signal in Go Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Unmarshals the WT_CONTAINER environment variable into a Go struct to access the stop signal. ```go package main import ( "encoding/json" "fmt" "os" ) func main() { var container struct { StopSignal string `json:"stop_signal"` } if err := json.Unmarshal([]byte(os.Getenv("WT_CONTAINER")), &container); err != nil { panic(err) } fmt.Printf("Stop signal: %s\n", container.StopSignal) } ``` -------------------------------- ### Execute Pre-Update Script via Labels in Python Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Retrieves and executes a backup script from the 'com.centurylinklabs.watchtower.lifecycle.pre-update' label. ```python import os import json container_info = json.loads(os.environ['WT_CONTAINER']) backup_script = container_info['labels'].get('com.centurylinklabs.watchtower.lifecycle.pre-update') if backup_script: print(f"Running backup: {backup_script}") # Execute backup_script ``` -------------------------------- ### Get Image Name in Go Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Unmarshals the WT_CONTAINER environment variable into a Go struct to access the image name. ```go package main import ( "encoding/json" "fmt" "os" ) func main() { var container struct { ImageName string `json:"image_name"` } if err := json.Unmarshal([]byte(os.Getenv("WT_CONTAINER")), &container); err != nil { panic(err) } fmt.Printf("Image: %s\n", container.ImageName) } ``` -------------------------------- ### Generate Mocks Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Generate mock implementations for Watchtower's interfaces using Mockery. Run this from the root directory. ```bash make mocks ``` -------------------------------- ### Get Container ID in Go Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Unmarshals the WT_CONTAINER environment variable into a Go struct to access the container ID. ```go package main import ( "encoding/json" "fmt" "os" ) func main() { var container struct { ID string `json:"id"` } if err := json.Unmarshal([]byte(os.Getenv("WT_CONTAINER")), &container); err != nil { panic(err) } fmt.Printf("Container ID: %s\n", container.ID) } ``` -------------------------------- ### Get Container Name in Go Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Unmarshals the WT_CONTAINER environment variable into a Go struct to access the container name. ```go package main import ( "encoding/json" "fmt" "os" ) func main() { var container struct { Name string `json:"name"` } if err := json.Unmarshal([]byte(os.Getenv("WT_CONTAINER")), &container); err != nil { panic(err) } fmt.Printf("Processing container: %s\n", container.Name) } ``` -------------------------------- ### Run Docker Compose Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/quickstart/index.md Execute this command in the directory containing your docker-compose.yaml file to start Watchtower in detached mode. ```bash docker compose up -d ``` -------------------------------- ### Execute Pre-Update Script via Labels in Bash Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Retrieves and executes a backup script defined in the 'com.centurylinklabs.watchtower.lifecycle.pre-update' label. ```bash #!/bin/bash BACKUP_SCRIPT=$(echo $WT_CONTAINER | jq -r '.labels["com.centurylinklabs.watchtower.lifecycle.pre-update"]') if [ -n "$BACKUP_SCRIPT" ]; then echo "Running backup: $BACKUP_SCRIPT" $BACKUP_SCRIPT fi ``` -------------------------------- ### Signal URL Format - With Authentication Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a Signal notification URL format including basic HTTP authentication credentials. ```plaintext signal://user:password@localhost:8080/+1234567890/+0987654321 ``` -------------------------------- ### Execute Pre-Update Script via Labels in Go Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Retrieves and executes a backup script from the 'com.centurylinklabs.watchtower.lifecycle.pre-update' label by unmarshalling the WT_CONTAINER JSON. ```go package main import ( "encoding/json" "fmt" "os" ) func main() { var container struct { Labels map[string]string `json:"labels"` } if err := json.Unmarshal([]byte(os.Getenv("WT_CONTAINER")), &container); err != nil { panic(err) } if backupScript, exists := container.Labels["com.centurylinklabs.watchtower.lifecycle.pre-update"]; exists { fmt.Printf("Running backup: %s\n", backupScript) // Execute backupScript } } ``` -------------------------------- ### Database Backup and Migration Dockerfile Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/lifecycle-hooks/index.md Configure pre-update backup and post-update migration scripts in a Dockerfile. ```dockerfile FROM postgres:13 # Pre-update: Create backup before stopping LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="/usr/local/bin/backup.sh" LABEL com.centurylinklabs.watchtower.lifecycle.pre-update-timeout="10" # Post-update: Run migrations after starting new version LABEL com.centurylinklabs.watchtower.lifecycle.post-update="/usr/local/bin/migrate.sh" LABEL com.centurylinklabs.watchtower.lifecycle.post-update-timeout="15" COPY backup.sh migrate.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/backup.sh /usr/local/bin/migrate.sh ``` -------------------------------- ### Signal URL Format - Basic Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a basic Signal notification URL format for sending to a single phone number. ```plaintext signal://localhost:8080/+1234567890/+0987654321 ``` -------------------------------- ### Signal URL Format - With API Token Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a Signal notification URL format using an API token for Bearer authentication. ```plaintext signal://localhost:8080/+1234567890/+0987654321?token=YOUR_API_TOKEN ``` -------------------------------- ### Signal URL Format - Multiple Recipients Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a Signal notification URL format for sending to multiple phone numbers and a group. ```plaintext signal://localhost:8080/+1234567890/+0987654321/+1123456789/group.testgroup ``` -------------------------------- ### Docker Commands for ECR Credential Helper Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/private-registries/index.md Commands to create a Docker volume, build the ECR credential helper image, and run it to store the helper binary in the volume. ```bash docker volume create helper ``` ```bash docker build -t aws-ecr-dock-cred-helper . ``` ```bash docker run -d --rm --name aws-cred-helper \ --volume helper:/go/bin aws-ecr-dock-cred-helper ``` -------------------------------- ### Watchtower Container Information Endpoint Response Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/http-api/index.md Example JSON response from the /v1/containers endpoint, detailing watched containers, their images, and digests. ```json { "containers": [ { "name": "nginx", "image": "nginx:latest", "image_id": "sha256:1111...", "digest": "sha256:2222..." } ], "count": 1, "timestamp": "2025-01-20T11:30:45Z", "api_version": "v1" } ``` -------------------------------- ### Format Code Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Format the codebase using the Makefile target. This utilizes Golangci-lint for formatting. ```bash make fmt ``` -------------------------------- ### Mount Docker config.json in Docker Run Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/private-registries/index.md Mount the existing Docker configuration file (`.docker/config.json`) into the Watchtower container when starting it with `docker run`. ```bash docker run [...] -v /.docker/config.json:/config.json nickfedor/watchtower ``` -------------------------------- ### Legacy Docker Linking for Dependencies Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md For legacy Docker setups, Watchtower treats explicit links and `network_mode: service:container` as implicit dependencies. ```docker # Container with explicit link docker run --link database:db nginx ``` ```docker # Container using service network mode docker run --network container:database nginx ``` -------------------------------- ### Run Application Source: https://github.com/nicholas-fedor/watchtower/blob/main/CONTRIBUTING.md Execute the compiled Watchtower application. This is run outside of a container. ```bash ./watchtower ``` -------------------------------- ### Watchtower Debugging Command Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md Enables debug logging for Watchtower to help diagnose dependency detection issues. This command should be run in an environment where Watchtower is already installed. ```bash watchtower --debug ``` -------------------------------- ### Run Watchtower with Automatic CPU Compatibility Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/arguments/index.md Use this command to run Watchtower with automatic CPU compatibility detection, suitable for mixed Docker/Podman environments. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --cpu-copy-mode auto ``` -------------------------------- ### Signal URL Format - Using HTTP Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Example of a Signal notification URL format explicitly disabling TLS for HTTP communication. Use only for local testing. ```plaintext signal://localhost:8080/+1234567890/+0987654321?disabletls=yes ``` -------------------------------- ### Download Docker Compose File (Bash) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/quickstart/index.md Use this Bash command to download the default Docker Compose file for Watchtower on Linux. ```bash curl -L https://raw.githubusercontent.com/nicholas-fedor/watchtower/refs/heads/main/examples/default/docker-compose.yaml -o docker-compose.yaml ``` -------------------------------- ### Email Notification via Docker Compose Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure email notifications within a Docker Compose setup by setting the WATCHTOWER_NOTIFICATION_URL environment variable in the docker-compose.yml file. ```yaml services: watchtower: image: nickfedor/watchtower:latest environment: WATCHTOWER_NOTIFICATION_URL: smtp://user:secret@smtp.example.com:587/?fromaddress=sender@example.com&toaddresses=recipient@example.com volumes: - /var/run/docker.sock:/var/run/docker.sock ``` -------------------------------- ### Docker CLI (Flags) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/notifications/overview/index.md Configure Watchtower to send Signal notifications using command-line flags in Docker. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --notification-url "signal://localhost:8080/+1234567890/+0987654321" ``` -------------------------------- ### Create config.json for Private Registry Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/private-registries/index.md Manually create a `config.json` file with base64 encoded credentials for a private registry. ```json { "auths": { "": { "auth": "XXXXXXX" } } } ``` -------------------------------- ### Strip All CPU Limits for Compatibility Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/arguments/index.md Use this command to strip all CPU limits, which can help avoid compatibility issues if CPU limits are causing problems. ```bash docker run -d \ --name watchtower \ -v /var/run/docker.sock:/var/run/docker.sock \ nickfedor/watchtower \ --cpu-copy-mode none ``` -------------------------------- ### Enable Container Management with Labels (Docker CLI) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/container-selection/index.md Use this snippet to enable Watchtower management for a specific container when using the Docker CLI. ```bash docker run -d --label=com.centurylinklabs.watchtower.enable=true someimage ``` -------------------------------- ### Build WASM Template Preview Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/README.md Build script for compiling Go code to WebAssembly. It outputs tplprev.wasm and wasm_exec.js to the docs/assets/ directory. ```bash scripts/build-tplprev.sh ``` -------------------------------- ### Declare Explicit Dependencies with Label Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md Use the `com.centurylinklabs.watchtower.depends-on` label to explicitly declare dependencies when automatic detection is insufficient. This example shows how to declare dependencies on 'postgres' and 'redis' services. ```dockerfile FROM nginx:latest # Declare dependencies on database and cache services LABEL com.centurylinklabs.watchtower.depends-on="postgres,redis" ``` ```yaml services: web: image: nginx labels: - com.centurylinklabs.watchtower.depends-on=postgres,redis postgres: image: postgres redis: image: redis ``` -------------------------------- ### Download Docker Compose File (PowerShell) Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/quickstart/index.md Use this PowerShell command to download the default Docker Compose file for Watchtower on Windows. ```powershell iwr -Uri https://raw.githubusercontent.com/nicholas-fedor/watchtower/refs/heads/main/examples/default/docker-compose.yaml -OutFile docker-compose.yaml ``` -------------------------------- ### Use Docker Hub Credentials with 2FA Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/getting-started/usage/index.md Mount the host's Docker config file to provide credentials for Docker Hub when 2FA is enabled. This makes your `$HOME/.docker/config.json` available to the Watchtower container. ```bash docker run -d \ --name watchtower \ -v $HOME/.docker/config.json:/config.json \ -v /var/run/docker.sock:/var/run/docker.sock \ --restart unless-stopped \ nickfedor/watchtower container_to_watch --debug ``` -------------------------------- ### Exclude Containers by Name Prefix using Regex Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/container-selection/index.md Use the WATCHTOWER_DISABLE_CONTAINERS environment variable with a regex pattern to exclude containers that start with a specific prefix. This is useful for managing groups of containers. ```bash docker run -d -e WATCHTOWER_DISABLE_CONTAINERS="web-.*" nickfedor/watchtower ``` -------------------------------- ### Configure Server Certificate Extensions Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/secure-connections/index.md Defines Subject Alternative Names (SAN) and extended key usage for the server certificate. Ensure `IP:10.10.10.20` is replaced with your host's actual IP and `$HOST` with the correct hostname. ```bash echo "subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1" > extfile-server.cnf ``` ```bash echo "extendedKeyUsage = serverAuth" >> extfile-server.cnf ``` -------------------------------- ### Programmatic Output (Porcelain) Argument Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/configuration/arguments/index.md The --porcelain argument outputs session results in a machine-readable format, specified by VERSION. This is equivalent to setting several notification-related flags. ```text Argument: --porcelain, -P Environment Variable: WATCHTOWER_PORCELAIN Possible Values: v1 Default: None ``` -------------------------------- ### Explicit Dependency Declaration with Watchtower Label Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md Use the `com.centurylinklabs.watchtower.depends-on` label to explicitly declare dependencies. This label accepts a comma-separated list of container names that must be available before the current container starts. ```dockerfile LABEL com.centurylinklabs.watchtower.depends-on="database,redis" ``` -------------------------------- ### Docker Compose for Network Mode Dependencies Source: https://github.com/nicholas-fedor/watchtower/blob/main/docs/advanced-features/linked-containers/index.md Shows a Docker Compose setup where a sidecar container uses network mode dependent on the main application. Watchtower ensures the main app is updated before the sidecar. ```yaml services: sidecar: image: sidecar network_mode: service:main-app main-app: image: main-app ```