Watchers Overview
Watchers are responsible for discovering and scanning containers across your infrastructure, whether on Docker daemons or Kubernetes clusters.
Supported Environmentsβ
WUD provides dedicated watchers tailored for your infrastructure:
| Environment | Documentation | Description |
|---|---|---|
| π³ Docker | Docker Configuration β | Local sockets, Remote TCP daemons, and Docker Compose stacks. |
| π Docker Swarm | Docker Swarm Watcher Guide β | Swarm manager socket/TCP, services, stack namespaces, digests. |
| βΈοΈ Kubernetes | Kubernetes Watcher Guide β | In-cluster RBAC, Deployments, StatefulSets, DaemonSets, CronJobs. |
| π― Nomad | Nomad Watcher Guide β | HashiCorp Nomad jobs (service, batch, system) and task groups. |
Docker Configurationβ
If no watcher is explicitly configured, a default watcher named local is automatically created, monitoring /var/run/docker.sock.
To customize how WUD monitors specific containers or workloads (opt-in/opt-out, tag filtering, semver transforms, custom display names, or trigger routing), see the comprehensive Workload Customization guide.
Configuration Optionsβ
Path to CA certificate PEM file (for TLS connection only)
Path to client certificate PEM file (for TLS connection only)
CRON schedule for automatic checks
Cool-down period before considering an update available for discovered containers
Regex pattern to exclude containers by name or labels (using label: prefix) from being watched. See Container Filtering & Precedence Rules.
Docker daemon hostname or IP address to monitor
Regex pattern to include containers by name or labels (using label: prefix) to be watched. See Container Filtering & Precedence Rules.
Random jitter in milliseconds applied to the CRON schedule to distribute load across registries (primarily Docker Hub)
Path to client private key PEM file (for TLS connection only)
Docker daemon TCP port to connect to
Docker UNIX socket path to monitor
Whether WUD should monitor all containers instead of only running ones
Whether WUD should check for image updates during startup
Whether WUD should monitor all discovered containers by default. See Container Filtering & Precedence Rules.
Whether WUD should watch digest for tags that are not semantic versions, acting as a fallback when not defined in registry config.
Whether WUD should listen for Docker daemon events in real-time
You can configure multiple watchers to monitor both local and remote Docker hosts simultaneously.
- Filtering & Precedence Rules: To learn how
INCLUDE,EXCLUDE, and labels interact, see Container Filtering & Precedence Rules. - Remote & Multi-Host: For remote Docker connections, security proxies, SSH tunnels, mesh networks, and mutual TLS, see Remote Daemons & Multi-Host.
- Rate Limits & Digests: To learn how digest polling works and prevent Docker Hub quota exhaustion, see Digest & Rate Limits.
- Per-Container Rules: To configure tag filtering and routing per container, see Container Labels.
Container Filtering & Precedence Rulesβ
WUD provides a multi-layered filtering engine to determine whether a discovered container should be monitored for image updates. You can filter containers globally at the watcher level using regular expressions on container names or labels, or override decisions locally using container labels.
Evaluation Priority Flowβ
When evaluating each discovered container, WUD processes filtering rules in a strict, descending 4-level hierarchy. The first rule that yields a definitive decision halts further evaluation:
Decision Levels Explainedβ
- Container Label
wud.watch(Absolute Priority):- Evaluated first. If the container defines the
wud.watchlabel with a non-empty value, this value strictly dictates the outcome:wud.watch=true: The container is monitored, even if it matches anEXCLUDEfilter or ifWATCHBYDEFAULT=false.wud.watch=false: The container is ignored, even if it matches anINCLUDEfilter or ifWATCHBYDEFAULT=true.
- Evaluated first. If the container defines the
- Watcher Exclude Filter (
WUD_WATCHER_{name}_EXCLUDE):- If defined, the regex pattern is tested against the container (by name or by labels).
- If the container matches, it is ignored immediately without evaluating include filters or defaults.
- Watcher Include Filter (
WUD_WATCHER_{name}_INCLUDE):- If defined, the regex pattern acts as an explicit allowlist:
- Containers that match the pattern are monitored.
- Containers that do not match are ignored.
-
note
When an
INCLUDEfilter is configured, theWATCHBYDEFAULTsetting is bypassed for non-matching containers.
- If defined, the regex pattern acts as an explicit allowlist:
- Watcher Default Fallback (
WUD_WATCHER_{name}_WATCHBYDEFAULT):- Reached only if no
wud.watchlabel is present, noEXCLUDEfilter matched, and noINCLUDEfilter was defined. - Defaults to
true(all remaining containers are monitored). - If set to
false, remaining containers are ignored (strict opt-in mode).
- Reached only if no
Precedence Rules Matrixβ
The following table summarizes how combinations of container labels and watcher configuration interact:
| Priority | Evaluation Level | Rule / Setting | Match Condition | Outcome | Description |
|---|---|---|---|---|---|
| 1 | Container Label | wud.watch=true | Label set to "true" | β Watched | Explicit opt-in. Overrides all watcher filters (EXCLUDE, INCLUDE, WATCHBYDEFAULT). |
| 1 | Container Label | wud.watch=false | Label set to "false" | β Ignored | Explicit opt-out. Overrides all watcher filters (EXCLUDE, INCLUDE, WATCHBYDEFAULT). |
| 2 | Watcher Filter | EXCLUDE | Container matches regex | β Ignored | Excluded by container name or label regex. Takes precedence over INCLUDE. |
| 3 | Watcher Filter | INCLUDE | Container matches regex | β Watched | Included by container name or label regex. |
| 3 | Watcher Filter | INCLUDE | Container does not match | β Ignored | Excluded because it does not match the active allowlist. WATCHBYDEFAULT is bypassed. |
| 4 | Watcher Default | WATCHBYDEFAULT=true (default) | No INCLUDE filter active | β Watched | Standard behavior: monitors all discovered containers. |
| 4 | Watcher Default | WATCHBYDEFAULT=false | No INCLUDE filter active | β Ignored | Strict opt-in mode: containers ignored unless tagged with wud.watch=true. |
Targeting Syntax: Container Names vs. Labelsβ
Both WUD_WATCHER_{name}_EXCLUDE and WUD_WATCHER_{name}_INCLUDE support standard JavaScript regular expressions (RegExp), with two targeting modes:
1. Container Name Matching (Default)β
Without any prefix, the regex is evaluated directly against the normalized container name (e.g. my-app without leading /):
^prod-.*: Matches any container whose name starts withprod-..*-(dev|test)$: Matches any container whose name ends with-devor-test.^(database|redis|rabbitmq)$: Matches exact container names.
2. Label Matching (label:<regex>)β
When the pattern starts with the label: prefix, WUD inspects the container's Docker metadata labels (container.Labels).
The regular expression following label: is tested against three representations for every label defined on the container:
- Label Key Alone:
key(e.g.,^com\.docker\.compose) - Key-Value with Equals:
key=value(e.g.,^env=production$) - Key-Value with Colon:
key:value(e.g.,^tier:frontend$)
If any label on the container matches any of these three representations, the filter condition is satisfied.
Regex patterns in JavaScript are case-sensitive by default. Remember to escape special regex characters like dots (\.), dashes, or brackets when targeting reverse-DNS label namespaces (e.g. label:^com\.docker\.compose).
Filtering Cookbookβ
Here are production-tested recipes for common container filtering architectures:
Recipe 1: Monitor Docker Compose Stacks Exclusivelyβ
Use Case: You run a host with standalone diagnostic containers, CLI utilities, and core Docker Compose stacks. You want WUD to monitor all Compose-managed containers automatically, without editing individual Compose files.
Why it works: Docker Compose automatically injects labels into every service it deploys (com.docker.compose.project, com.docker.compose.service, com.docker.compose.version). Setting INCLUDE=label:^com\.docker\.compose matches these labels natively.
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_LOCAL_INCLUDE=label:^com\.docker\.compose
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_LOCAL_INCLUDE="label:^com\.docker\.compose" \
getwud/wud
Recipe 2: Exclude Development & Test Containers by Nameβ
Use Case: Ephemeral test containers, staging runners, or CI/CD jobs run on your Docker daemon. You want WUD to watch all production services while skipping any test or dev container.
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_LOCAL_EXCLUDE=^(test|dev|staging)-.*
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_LOCAL_EXCLUDE="^(test|dev|staging)-.*" \
getwud/wud
Recipe 3: Exclude Containers by Custom Labelβ
Use Case: You want to flag specific containers to be ignored by assigning a custom tag such as wud.ignore=true or env=development, without having to rename containers.
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_LOCAL_EXCLUDE=label:^wud\.ignore=true$
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_LOCAL_EXCLUDE="label:^wud\.ignore=true$" \
getwud/wud
Any container bearing that label will be skipped:
services:
backup-job:
image: restic/restic:latest
labels:
- wud.ignore=true
Recipe 4: Allowlist Production Containers by Nameβ
Use Case: In high-density environments, you only want to monitor containers prefixed with prod- or core-. All other existing and future containers are ignored by default.
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_LOCAL_INCLUDE=^(prod|core)-.*
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_LOCAL_INCLUDE="^(prod|core)-.*" \
getwud/wud
Recipe 5: Strict Opt-In Mode per Containerβ
Use Case: In shared or multi-tenant environments, you do not want WUD to automatically discover and monitor every workload. Instead, container owners must explicitly opt in by adding wud.watch=true.
First, configure WUD in opt-in mode by setting WATCHBYDEFAULT=false:
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_LOCAL_WATCHBYDEFAULT=false
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_LOCAL_WATCHBYDEFAULT="false" \
getwud/wud
Next, add the wud.watch=true label to the specific services you want WUD to monitor:
- Docker Compose
- Docker
services:
# Monitored because wud.watch=true
web:
image: nginx:1.27-alpine
labels:
- wud.watch=true
# Ignored because WATCHBYDEFAULT=false
redis:
image: redis:7.2-alpine
# Monitored
docker run -d --name web --label wud.watch=true nginx:1.27-alpine
# Ignored
docker run -d --name redis redis:7.2-alpine
Examplesβ
1. Watch the local Docker host daily at 1:00 AMβ
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_CRON=0 1 * * *
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_CRON="0 1 * * *" \
getwud/wud
2. Watch all containers (including stopped / paused)β
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_WATCHALL=true
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_WATCHALL="true" \
getwud/wud
3. Watch a remote Docker host via TCP (Port 2375)β
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
environment:
- WUD_WATCHER_MYREMOTEHOST_HOST=myremotehost
- WUD_WATCHER_MYREMOTEHOST_PORT=2375
docker run -d \
-e WUD_WATCHER_MYREMOTEHOST_HOST="myremotehost" \
-e WUD_WATCHER_MYREMOTEHOST_PORT="2375" \
getwud/wud
4. Watch a remote Docker host with TLS (Port 2376)β
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
environment:
- WUD_WATCHER_MYREMOTEHOST_HOST=myremotehost
- WUD_WATCHER_MYREMOTEHOST_PORT=2376
- WUD_WATCHER_MYREMOTEHOST_CAFILE=/certs/ca.pem
- WUD_WATCHER_MYREMOTEHOST_CERTFILE=/certs/cert.pem
- WUD_WATCHER_MYREMOTEHOST_KEYFILE=/certs/key.pem
volumes:
- /my-host/my-certs/ca.pem:/certs/ca.pem:ro
- /my-host/my-certs/cert.pem:/certs/cert.pem:ro
- /my-host/my-certs/key.pem:/certs/key.pem:ro
docker run -d \
-e WUD_WATCHER_MYREMOTEHOST_HOST="myremotehost" \
-e WUD_WATCHER_MYREMOTEHOST_PORT="2376" \
-e WUD_WATCHER_MYREMOTEHOST_CAFILE="/certs/ca.pem" \
-e WUD_WATCHER_MYREMOTEHOST_CERTFILE="/certs/cert.pem" \
-e WUD_WATCHER_MYREMOTEHOST_KEYFILE="/certs/key.pem" \
-v /my-host/my-certs/ca.pem:/certs/ca.pem:ro \
-v /my-host/my-certs/cert.pem:/certs/cert.pem:ro \
-v /my-host/my-certs/key.pem:/certs/key.pem:ro \
getwud/wud
5. Watch multiple Docker hosts simultaneouslyβ
- Docker Compose
- Docker
services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- WUD_WATCHER_LOCAL_SOCKET=/var/run/docker.sock
- WUD_WATCHER_PROD_HOST=prod-docker-host
- WUD_WATCHER_STAGING_HOST=staging-docker-host
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-e WUD_WATCHER_LOCAL_SOCKET="/var/run/docker.sock" \
-e WUD_WATCHER_PROD_HOST="prod-docker-host" \
-e WUD_WATCHER_STAGING_HOST="staging-docker-host" \
getwud/wud