Understanding Watchtower Configuration

Watchtower Docker configuration is entirely environment-variable driven — there is no configuration file to edit, no YAML to write, and no CLI flags required (though CLI flags are also supported for most settings). This design philosophy makes Watchtower particularly well-suited for Docker Compose and Kubernetes deployments where environment variables are the standard configuration mechanism.

Environment variables can be passed three ways:

# 1. Inline with docker run
docker run -d \
  -e WATCHTOWER_CLEANUP=true \
  -e WATCHTOWER_POLL_INTERVAL=3600 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower

# 2. Docker Compose environment block
services:
  watchtower:
    image: containrrr/watchtower
    environment:
      - WATCHTOWER_CLEANUP=true
      - WATCHTOWER_POLL_INTERVAL=3600

# 3. Docker Compose env_file
services:
  watchtower:
    image: containrrr/watchtower
    env_file:
      - watchtower.env

The env_file approach keeps secrets (registry credentials, webhook URLs) out of your Compose file and version control.

Update Behavior Variables

These are the core Watchtower Docker environment variables that control how and when updates happen.

VariableDefaultDescription
WATCHTOWER_POLL_INTERVAL86400Seconds between update checks (default: 24 hours). Set to 3600 for hourly checks.
WATCHTOWER_SCHEDULE6-field cron expression (seconds first). Overrides POLL_INTERVAL when set. Example: 0 0 4 * * * = 4 AM daily.
WATCHTOWER_CLEANUPfalseSet to true to delete old images after successful update. Strongly recommended for production.
WATCHTOWER_REMOVE_VOLUMESfalseRemove attached volumes when replacing containers. Use with caution — data loss risk.
WATCHTOWER_INCLUDE_RESTARTINGfalseInclude containers with restarting state in update checks.
WATCHTOWER_INCLUDE_STOPPEDfalseAlso check stopped containers for updates (won't restart them unless new image found).
WATCHTOWER_REVIVE_STOPPEDfalseRestart stopped containers after updating them. Requires WATCHTOWER_INCLUDE_STOPPED=true.
WATCHTOWER_ROLLING_RESTARTfalseUpdate containers one at a time rather than all simultaneously. Recommended for Swarm.
WATCHTOWER_TIMEOUT10sTimeout for stopping a container before forced kill. Accepts duration strings like 30s, 2m.

Scope Control — Which Containers to Watch

These Watchtower Docker config options control which containers Watchtower monitors and updates.

VariableDefaultDescription
WATCHTOWER_LABEL_ENABLEfalseWhen true, only update containers that have com.centurylinklabs.watchtower.enable=true label. Opt-in mode.
WATCHTOWER_MONITOR_ONLYfalseDetect updates and send notifications, but never pull images or restart containers. Read-only mode.
WATCHTOWER_SCOPEInstance scope name. Allows multiple Watchtower instances to manage different container subsets on the same host.
# Opt-in mode — only update explicitly labeled containers
environment:
  - WATCHTOWER_LABEL_ENABLE=true

# Monitor-only — notify but never update
environment:
  - WATCHTOWER_MONITOR_ONLY=true
  - WATCHTOWER_NOTIFICATION_URL=slack://token@channel

Scheduling and Time Configuration

The Watchtower Docker schedule system supports both simple polling intervals and full cron expressions.

# Simple interval (seconds) — check every 6 hours
- WATCHTOWER_POLL_INTERVAL=21600

# Cron schedule — 6-field format (SECONDS MINUTES HOURS DAY MONTH WEEKDAY)
- WATCHTOWER_SCHEDULE=0 0 4 * * *     # 4:00 AM every day
- WATCHTOWER_SCHEDULE=0 0 */6 * * *   # Every 6 hours
- WATCHTOWER_SCHEDULE=0 30 2 * * 0    # 2:30 AM every Sunday
⚠️
Cron format is 6 fields (not 5): Watchtower uses the robfig/cron v3 library, which requires a leading seconds field. Standard 5-field cron expressions will cause a parse error. Always start your WATCHTOWER_SCHEDULE value with a seconds field (0–59).

Timezone Configuration

To ensure your Watchtower Docker timezone is correct for scheduled runs and log timestamps:

services:
  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/localtime:/etc/localtime:ro   # Mount host timezone
    environment:
      - TZ=America/New_York                # Or: Europe/London, Asia/Karachi, etc.
      - WATCHTOWER_SCHEDULE=0 0 3 * * *    # Will fire at 3 AM in the configured TZ

Notification Variables

Full notification configuration reference — these Watchtower Docker variables control how and where update alerts are sent.

VariableDescription
WATCHTOWER_NOTIFICATIONSComma-separated list: slack, email, msteams, gotify. Legacy method.
WATCHTOWER_NOTIFICATION_URLShoutrrr URL string (preferred). Supports all services. Multiple URLs space-separated.
WATCHTOWER_NOTIFICATION_REPORTSet to true to batch notifications per run (one message per update cycle).
WATCHTOWER_NOTIFICATION_TITLE_TAGCustom tag appended to notification titles for multi-host environments.
WATCHTOWER_NOTIFICATION_SKIP_TITLESet to true to omit the title prefix from notifications.
WATCHTOWER_NOTIFICATION_EMAIL_FROMSender email address for SMTP notifications.
WATCHTOWER_NOTIFICATION_EMAIL_TORecipient email address for SMTP notifications.
WATCHTOWER_NOTIFICATION_EMAIL_SERVERSMTP server hostname.
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORTSMTP port (587 for TLS, 465 for SSL, 25 for plaintext).
WATCHTOWER_NOTIFICATION_SLACK_HOOK_URLSlack incoming webhook URL.
WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIERBot name displayed in Slack messages. Default: watchtower.
# Modern Shoutrrr method — single variable covers all services
environment:
  - WATCHTOWER_NOTIFICATION_URL=slack://T00/B00/xxx
  # Telegram: telegram://botToken@telegram?channels=@channelName
  # Discord:  discord://webhookToken@webhookID
  # Ntfy:     ntfy://topic@ntfy.sh
  # Gotify:   gotify://hostname/token

Private Registry Authentication

For Watchtower Docker private registry access, Watchtower reads Docker Hub credentials from the standard Docker config file or environment variables.

# Method 1: Mount Docker config (recommended)
volumes:
  - /root/.docker/config.json:/config.json:ro
  # OR
  - $HOME/.docker/config.json:/config.json:ro

# Method 2: Environment variables for Docker Hub
environment:
  - REPO_USER=myusername
  - REPO_PASS=mypassword

# Method 3: Per-registry credentials (multi-registry)
environment:
  - REPO_USER__registry.example.com=myuser
  - REPO_PASS__registry.example.com=mypassword

For private registries like AWS ECR, GitHub Container Registry (ghcr.io), or GitLab Registry, use the mounted config.json approach — run docker login registry.example.com on the host first, which writes credentials to ~/.docker/config.json.

Docker Connection Variables

Control how Watchtower connects to the Docker daemon — useful for Watchtower Docker socket proxy setups or remote Docker hosts.

VariableDefaultDescription
DOCKER_HOSTunix:///var/run/docker.sockDocker daemon socket or TCP address. Set to tcp://host:2375 for remote.
DOCKER_TLS_VERIFYfalseEnable TLS verification for remote Docker connections.
DOCKER_CERT_PATHPath to TLS certificates directory for secure remote connections.
DOCKER_API_VERSIONauto-detectForce a specific Docker API version. Use when auto-detection fails.
# Socket proxy setup (more secure than raw socket)
environment:
  - DOCKER_HOST=tcp://socket-proxy:2375  # Tecnativa Docker Socket Proxy

# Remote Docker host (with TLS)
environment:
  - DOCKER_HOST=tcp://remote-host:2376
  - DOCKER_TLS_VERIFY=1
  - DOCKER_CERT_PATH=/certs

Rate Limiting and Pull Control

Docker Hub enforces rate limits on image pulls — anonymous users get 100 pulls/6h, authenticated users get 200 pulls/6h, and Docker Pro/Team gets more. With many containers, Watchtower can hit these limits.

environment:
  # Reduce check frequency to stay under rate limits
  - WATCHTOWER_POLL_INTERVAL=86400   # Check once per day

  # Authenticate to get higher rate limits
  - REPO_USER=dockerhubuser
  - REPO_PASS=dockerhubpassword

  # Per-container: disable Watchtower for non-critical containers
  # (add this label to individual containers)
  # com.centurylinklabs.watchtower.enable=false
The WATCHTOWER_POLL_INTERVAL default is 86400 (24 hours) — this is intentionally conservative to respect Docker Hub rate limits. Only decrease the interval if you have authenticated access or your own registry.

HTTP API Variables

Watchtower includes an optional HTTP API for triggering updates programmatically and querying status — useful for CI/CD pipelines.

environment:
  - WATCHTOWER_HTTP_API_UPDATE=true        # Enable POST /v1/update endpoint
  - WATCHTOWER_HTTP_API_METRICS=true       # Enable GET /v1/metrics (Prometheus)
  - WATCHTOWER_HTTP_API_TOKEN=mySecretToken # Bearer token for auth

# Expose the API port
ports:
  - "8080:8080"

# Trigger an update via API:
# curl -H "Authorization: Bearer mySecretToken" http://localhost:8080/v1/update

Logging and Debug Variables

VariableDefaultDescription
WATCHTOWER_DEBUGfalseEnable verbose debug logging. Equivalent to --log-level debug.
WATCHTOWER_TRACEfalseEnable trace-level logging (very verbose — includes API responses).
NO_COLORfalseDisable ANSI color codes in log output (useful for log aggregation).
# Full debug configuration for troubleshooting
environment:
  - WATCHTOWER_DEBUG=true
  # Then check logs:
  # docker logs watchtower --follow

Complete Production Example

A production-ready Docker Compose configuration combining the most important Watchtower Docker environment variables:

services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /etc/localtime:/etc/localtime:ro
      - /root/.docker/config.json:/config.json:ro
    environment:
      # Scheduling
      - WATCHTOWER_SCHEDULE=0 0 4 * * *      # 4 AM daily
      - TZ=America/New_York

      # Update behavior
      - WATCHTOWER_CLEANUP=true              # Remove old images
      - WATCHTOWER_ROLLING_RESTART=true      # One at a time
      - WATCHTOWER_TIMEOUT=30s               # 30s stop timeout

      # Scope
      - WATCHTOWER_LABEL_ENABLE=false        # Update all containers

      # Notifications (Slack via Shoutrrr)
      - WATCHTOWER_NOTIFICATION_URL=slack://T00/B00/secret

      # HTTP API
      - WATCHTOWER_HTTP_API_UPDATE=true
      - WATCHTOWER_HTTP_API_TOKEN=yourSecretToken

Frequently Asked Questions

What is the WATCHTOWER_CLEANUP environment variable?

WATCHTOWER_CLEANUP=true tells Watchtower to automatically remove the old image after successfully updating a container to a newer version. Without this setting, old images accumulate on disk indefinitely. Setting WATCHTOWER_CLEANUP=true is recommended for all production deployments to reclaim disk space.

How do I set a timezone for Watchtower Docker?

Set TZ=America/New_York (or your timezone) as an environment variable, and mount /etc/localtime:/etc/localtime:ro. This ensures log timestamps and scheduled run times (via WATCHTOWER_SCHEDULE) reflect your local time zone. Use IANA timezone names like Europe/London, Asia/Karachi, Australia/Sydney.

What does WATCHTOWER_MONITOR_ONLY do?

WATCHTOWER_MONITOR_ONLY=true puts Watchtower into a passive mode — it detects when new image versions are available and sends notifications, but never actually pulls new images or restarts containers. This is ideal for production environments where you want visibility into available updates without automatic restarts.

How do I configure Watchtower to update only specific containers?

Set WATCHTOWER_LABEL_ENABLE=true globally, then add the label com.centurylinklabs.watchtower.enable=true only to containers you want Watchtower to manage. All other containers will be ignored. Alternatively, use com.centurylinklabs.watchtower.enable=false on specific containers you want to exclude while updating all others by default.

What is the difference between WATCHTOWER_POLL_INTERVAL and WATCHTOWER_SCHEDULE?

WATCHTOWER_POLL_INTERVAL is a simple repeat interval in seconds — e.g., 3600 means check every hour. WATCHTOWER_SCHEDULE is a 6-field cron expression that lets you specify exact times, like "only at 4 AM on weekdays." When WATCHTOWER_SCHEDULE is set, it takes precedence over WATCHTOWER_POLL_INTERVAL. Use POLL_INTERVAL for simple recurring checks and SCHEDULE for time-specific runs.

AC
Alex Chen
Docker Infrastructure Engineer · containrrr contributor
Alex has contributed documentation and test coverage to the containrrr/watchtower project and maintains the most complete public reference for Watchtower environment variables. All variable descriptions are verified against containrrr/watchtower v1.7.x source code on GitHub.