docker.recipes
Operations8 min read

Watchtower: Automatic Container Updates

Set up Watchtower for automatic Docker image updates with notifications, scheduling, and best practices for when to use it.

01What Watchtower Does

Watchtower monitors your running containers and automatically updates them when new images are available. It: • Checks registries for new image versions • Pulls updated images • Restarts containers with the same configuration • Optionally notifies you of updates **When it's great:** • Home labs with many containers • Non-critical services • Keeping security patches current **When to avoid it:** • Production workloads needing stability • Apps requiring tested upgrade paths • Databases and stateful services

Automatic updates can break things. Always have backups and test critical services manually before enabling Watchtower.

02Basic Watchtower Setup

Run Watchtower as a container that monitors other containers. It needs access to the Docker socket to manage containers.
1services:
2 watchtower:
3 image: containrrr/watchtower:latest
4 container_name: watchtower
5 environment:
6 - TZ=Europe/London
7 - WATCHTOWER_CLEANUP=true # Remove old images
8 - WATCHTOWER_INCLUDE_STOPPED=false # Only update running containers
9 - WATCHTOWER_POLL_INTERVAL=86400 # Check every 24 hours (seconds)
10 volumes:
11 - /var/run/docker.sock:/var/run/docker.sock
12 restart: unless-stopped

WATCHTOWER_CLEANUP removes old images after updating. This saves disk space but means you can't quickly roll back.

03Scheduling Updates

Control when Watchtower checks for and applies updates. Use cron expressions for precise scheduling.
1services:
2 watchtower:
3 image: containrrr/watchtower:latest
4 environment:
5 - TZ=Europe/London
6 # Cron schedule (6 fields: second minute hour day month weekday)
7 - WATCHTOWER_SCHEDULE=0 0 4 * * * # Every day at 4 AM
8 # Or use poll interval (simpler)
9 # - WATCHTOWER_POLL_INTERVAL=86400 # Every 24 hours
10 volumes:
11 - /var/run/docker.sock:/var/run/docker.sock
12
13# Common schedules:
14# 0 0 4 * * * - Daily at 4 AM
15# 0 0 4 * * 0 - Weekly on Sunday at 4 AM
16# 0 0 4 1 * * - Monthly on 1st at 4 AM
17# 0 0 */6 * * * - Every 6 hours

04Update Notifications

Get notified when Watchtower updates containers. Supports many notification services.
1services:
2 watchtower:
3 image: containrrr/watchtower:latest
4 environment:
5 - TZ=Europe/London
6 - WATCHTOWER_SCHEDULE=0 0 4 * * *
7 - WATCHTOWER_CLEANUP=true
8 # Email notifications
9 - WATCHTOWER_NOTIFICATIONS=email
10 - WATCHTOWER_NOTIFICATION_EMAIL_FROM=watchtower@example.com
11 - WATCHTOWER_NOTIFICATION_EMAIL_TO=you@example.com
12 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.example.com
13 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587
14 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=smtp-user
15 - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${SMTP_PASSWORD}
16 volumes:
17 - /var/run/docker.sock:/var/run/docker.sock
18
19# Other notification options:
20# - WATCHTOWER_NOTIFICATIONS=slack
21# - WATCHTOWER_NOTIFICATIONS=gotify
22# - WATCHTOWER_NOTIFICATIONS=shoutrrr (supports many services)

05Selective Container Updates

Control which containers Watchtower updates using labels. This lets you auto-update some while protecting others.
1services:
2 watchtower:
3 image: containrrr/watchtower:latest
4 environment:
5 - WATCHTOWER_LABEL_ENABLE=true # Only update labeled containers
6 volumes:
7 - /var/run/docker.sock:/var/run/docker.sock
8
9 # This container WILL be auto-updated
10 plex:
11 image: linuxserver/plex:latest
12 labels:
13 - "com.centurylinklabs.watchtower.enable=true"
14
15 # This container will NOT be updated (no label)
16 database:
17 image: postgres:16
18
19 # Explicitly disable updates
20 critical-app:
21 image: myapp:latest
22 labels:
23 - "com.centurylinklabs.watchtower.enable=false"

Use WATCHTOWER_LABEL_ENABLE=true for opt-in updating. This is safer than updating everything by default.

06Monitor-Only Mode

Run Watchtower in monitor-only mode to get notifications about available updates without automatically applying them.
1services:
2 watchtower:
3 image: containrrr/watchtower:latest
4 environment:
5 - WATCHTOWER_MONITOR_ONLY=true # Don't update, just notify
6 - WATCHTOWER_NOTIFICATIONS=shoutrrr
7 - WATCHTOWER_NOTIFICATION_URL=discord://token@webhookid
8 - WATCHTOWER_SCHEDULE=0 0 8 * * * # Check at 8 AM
9 volumes:
10 - /var/run/docker.sock:/var/run/docker.sock
11
12# Monitor mode is great for:
13# - Seeing what updates are available
14# - Planning maintenance windows
15# - Verifying images before updating

07Alternatives to Watchtower

Watchtower isn't the only option. Consider these alternatives based on your needs: **Diun (Docker Image Update Notifier)** • Notification only, no auto-update • More notification options • Supports image registries directly **Ouroboros** • Similar to Watchtower • Different feature set **Manual updates** • docker compose pull && docker compose up -d • Most control, least automation
1# Diun - notification only
2services:
3 diun:
4 image: crazymax/diun:latest
5 container_name: diun
6 environment:
7 - TZ=Europe/London
8 - DIUN_WATCH_SCHEDULE=0 8 * * *
9 - DIUN_PROVIDERS_DOCKER=true
10 - DIUN_NOTIF_DISCORD_WEBHOOKURL=${DISCORD_WEBHOOK}
11 volumes:
12 - ./diun:/data
13 - /var/run/docker.sock:/var/run/docker.sock:ro
14
15# Manual update script
16# #!/bin/bash
17# cd /path/to/compose
18# docker compose pull
19# docker compose up -d --remove-orphans
20# docker image prune -f

For production, consider Diun for notifications + manual updates. It gives you visibility without risking automatic changes.