Container Selection
Overview
By default, Watchtower monitors and updates all running containers on the connected Docker daemon. This behavior can be customized through a combination of configuration options and container labels to control exactly which containers are managed and how.
Container selection works through a filter chain: a series of criteria applied in sequence. A container is monitored only if it passes every filter in the chain. The filters are evaluated in the following order:
| # | Filter | Description |
|---|---|---|
| 1 | Old Watchtower container exclusion | Watchtower containers renamed with a watchtower-old- prefix during self-updates are always excluded. |
| 2 | Disabled label check | Containers with the Docker label com.centurylinklabs.watchtower.enable=false are excluded. |
| 3 | Scope filter | Only containers matching the configured scope are included (default: "none"). |
| 4 | Enable label filter | If label enable is set, only containers with the enable label present are included. |
| 5 | Disabled containers by label | Containers matching any disabled label pair are excluded. |
| 6 | Enabled containers by label | If set, only containers matching at least one enabled label pair are included. |
| 7 | Image skip patterns | Containers whose image matches a skip pattern are excluded. |
| 8 | Monitored image name patterns | If set, only containers whose image matches a monitored pattern are included. |
| 9 | Disabled container names | Containers whose name matches a disable pattern are excluded. |
| 10 | Container name arguments | If positional name arguments are provided, only containers matching at least one are included. |
- If an image name pattern is configured, then Watchtower will exclusively manage only the respective container(s).
- If a container name is provided as an argument, then Watchtower will exclusively manage only the specified container(s).
All criteria must be satisfied
A container must pass every filter in the chain to be monitored. If any single filter rejects it, the container is excluded.
Management Modes
Watchtower supports two management modes for containers:
- Full Management (default): Watchtower checks for updates, pulls new images, recreates containers, and runs lifecycle hooks.
- Monitor Only Mode: Watchtower checks for updates, sends notifications, and runs lifecycle hooks, but does not recreate containers.
Container State Filtering
By default, Watchtower only processes containers in the running state.
Two configuration options extend this to include additional states:
| Option | Environment Variable | Effect |
|---|---|---|
| Include Stopped Containers | WATCHTOWER_INCLUDE_STOPPED |
Include created and exited containers |
| Include Restarting Containers | WATCHTOWER_INCLUDE_RESTARTING |
Include restarting containers (Docker only) |
Podman compatibility
The restarting state is not available on Podman and is automatically excluded when Podman is detected.
Enable/Disable Labels
The com.centurylinklabs.watchtower.enable label controls whether Watchtower manages a container.
Default Behavior
When label enable is not set:
- Containers without the label are monitored
- Containers with
enable=trueare monitored - Containers with
enable=falseare excluded
With Label Enable
When label enable is set:
- Containers with
enable=trueare monitored - Containers with
enable=falseare excluded - Containers without the label are excluded
services:
someimage:
labels:
- "com.centurylinklabs.watchtower.enable=true"To exclude a container, set the label to false:
services:
someimage:
labels:
- "com.centurylinklabs.watchtower.enable=false"Monitor-Only Mode
Individual containers can be set to monitor-only mode, where Watchtower checks for updates and sends notifications but does not recreate the container.
Set the com.centurylinklabs.watchtower.monitor-only label to true on the container:
services:
someimage:
labels:
- "com.centurylinklabs.watchtower.monitor-only=true"The per-container label has the same effect as the global monitor-only option, but applies only to that specific container.
When combined with label precedence, the container label overrides the global option. Without label precedence, the container is monitor-only if either the label or the global option is set.
Container Name Filtering
Watchtower can filter containers based on their container name using Go regex pattern matching.
Include Specific Containers
Pass container names as positional arguments to Watchtower. When provided, only containers matching at least one name are monitored.
services:
watchtower:
image: nickfedor/watchtower:latest
command: nginx redis
volumes:
- /var/run/docker.sock:/var/run/docker.sockExclude Specific Containers
Use the disable containers option to exclude containers by name. This supports comma- or space-separated values and regex patterns.
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_DISABLE_CONTAINERS=container1,container2
volumes:
- /var/run/docker.sock:/var/run/docker.sockLabel-Based Container Filtering
Watchtower can include or exclude containers based on arbitrary Docker label key-value pairs.
Enable Containers by Label
Use the enable containers by label option to restrict monitoring to containers that have at least one of the specified label pairs.
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_ENABLE_CONTAINERS_BY_LABEL=env=prod,team=platform
volumes:
- /var/run/docker.sock:/var/run/docker.sockAn empty value (key=) matches any container where the label key exists, regardless of its value.
For example, WATCHTOWER_ENABLE_CONTAINERS_BY_LABEL=env= enables any container with the env label set to any value.
Disable Containers by Label
Use the disable containers by label option to exclude containers that have any of the specified label pairs.
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_DISABLE_CONTAINERS_BY_LABEL=managed-by=external
volumes:
- /var/run/docker.sock:/var/run/docker.sockkey=value pairs separated by commas.key=) performs a presence check: the label must exist on the container with any value. A non-empty value requires an exact match.Image Name Filtering
Watchtower can filter containers based on their image name using Go regex pattern matching.
Image name patterns match against the full image name including its tag (e.g., nginx:latest, docker.io/library/nginx:1.25).
:latest is assumed.Monitor Specific Images
Use the monitor image names configuration option to restrict monitoring to containers whose image matches at least one pattern.
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_MONITOR_IMAGE_NAMES=nginx:.*,redis:7.*
volumes:
- /var/run/docker.sock:/var/run/docker.sockExclude Specific Images
Use the skip image names option to exclude containers whose image matches at least one pattern.
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_SKIP_IMAGE_NAMES=postgres:.*,mcr.microsoft.com/*
volumes:
- /var/run/docker.sock:/var/run/docker.sockMonitoring Scopes
Scopes allow multiple Watchtower instances to run on the same Docker host without interfering with each other. Each instance manages only the containers within its scope.
- Use the scope filter option to define a scope.
- Then, use the
com.centurylinklabs.watchtower.scopelabel on containers to assign them to that scope.
services:
# Scoped Application
app-production:
image: myapp:latest
labels:
- "com.centurylinklabs.watchtower.scope=production"
# Scoped Watchtower watching "production" scope
watchtower-production:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_SCOPE=production
labels:
- "com.centurylinklabs.watchtower.scope=production"
volumes:
- /var/run/docker.sock:/var/run/docker.sock- Without a scope filter, Watchtower defaults to scope
"none"and manages only unscoped containers (those without acom.centurylinklabs.watchtower.scopelabel, or with it set to"none"or""). - Containers with a non-empty scope label (e.g.,
scope=production) are not monitored by an unscoped Watchtower instance. - Set the scope filter to
noneto explicitly manage only unscoped containers (same as the default behavior). - Two instances cannot share the same scope.
- An unscoped instance coexists with scoped instances.
See Running Multiple Instances for a complete guide.
Regex Pattern Matching
Container name and image name filters support regular expressions using Go regex syntax.
Patterns are anchored to match the full name
Patterns are automatically anchored with ^...$, meaning they must match the entire container or image name. Use .* for wildcard matching instead of bare *.
Container Name Patterns
Container names are normalized before matching (the leading / stripped). Both positional arguments and the disable containers option support regex.
| Pattern | Matches |
|---|---|
container.* |
“container1”, “container-abc” |
.*-dev |
“web-dev”, “api-dev”, “db-dev” |
.* |
Any container name |
nginx|redis |
Either “nginx” or “redis” |
db-.*|cache-.* |
Any name starting with “db-” or “cache-” |
Image Name Patterns
Image name patterns match against the full name:tag string. Use .* to match any tag.
| Pattern | Matches |
|---|---|
nginx:latest |
Only nginx:latest |
nginx:.* |
nginx with any tag |
docker\.io/library/.* |
Any official Docker Hub image |
.*\.azurecr\.io/.* |
Any Azure Container Registry image |
Examples
Exclude all containers starting with a prefix:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_DISABLE_CONTAINERS=web-.*
volumes:
- /var/run/docker.sock:/var/run/docker.sockInclude only containers matching specific patterns:
services:
watchtower:
image: nickfedor/watchtower:latest
command: ["nickfedor/watchtower", "db-.*", "cache-.*"]
volumes:
- /var/run/docker.sock:/var/run/docker.sockMonitor only containers using nginx or redis images with any tag:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_MONITOR_IMAGE_NAMES=nginx:.*,redis:.*
volumes:
- /var/run/docker.sock:/var/run/docker.sockLabel Precedence
By default, when a container-level label (e.g., com.centurylinklabs.watchtower.monitor-only) and a global option (e.g., monitor-only) are both set, the container uses the combined effect (either triggers the behavior).
With label precedence, container labels override the global options. This allows per-container control even when global options are set.
| Label Precedence | Container Label | Global Option | Result |
|---|---|---|---|
| false (default) | not set | false | false |
| false (default) | not set | true | true |
| false (default) | true | false | true |
| false (default) | true | true | true |
| true | not set | any | global flag value |
| true | true | false | true |
| true | false | true | false |
This applies to the monitor-only and no-pull configuration options.
Complete Configuration Reference
CLI Flags and Environment Variables
| Flag | Environment Variable | Type | Default | Description |
|---|---|---|---|---|
| (positional args) | N/A | []string | [] | Container names/patterns to include |
--disable-containers / -x |
WATCHTOWER_DISABLE_CONTAINERS |
[]string | [] | Container names/patterns to exclude |
--enable-containers-by-label |
WATCHTOWER_ENABLE_CONTAINERS_BY_LABEL |
[]string | [] | Label key=value pairs to include |
--disable-containers-by-label |
WATCHTOWER_DISABLE_CONTAINERS_BY_LABEL |
[]string | [] | Label key=value pairs to exclude |
--monitor-image-names |
WATCHTOWER_MONITOR_IMAGE_NAMES |
[]string | [] | Image name patterns to monitor |
--skip-image-names |
WATCHTOWER_SKIP_IMAGE_NAMES |
[]string | [] | Image name patterns to exclude |
--label-enable / -e |
WATCHTOWER_LABEL_ENABLE |
bool | false | Require enable label on containers |
--scope |
WATCHTOWER_SCOPE |
string | "" | Monitoring scope |
--include-stopped / -S |
WATCHTOWER_INCLUDE_STOPPED |
bool | false | Include created and exited containers |
--include-restarting |
WATCHTOWER_INCLUDE_RESTARTING |
bool | false | Include restarting containers |
--label-take-precedence |
WATCHTOWER_LABEL_TAKE_PRECEDENCE |
bool | false | Labels override global flags |
Container Labels
| Label | Values | Effect |
|---|---|---|
com.centurylinklabs.watchtower.enable |
true / false | Enable or disable management |
com.centurylinklabs.watchtower.monitor-only |
true / false | Monitor without updating |
com.centurylinklabs.watchtower.no-pull |
true / false | Skip image pulls |
com.centurylinklabs.watchtower.scope |
any string | Assign to a monitoring scope |
com.centurylinklabs.watchtower.depends-on |
comma-separated names | Declare container dependencies |
com.centurylinklabs.watchtower.cooldown-delay |
duration string | Minimum image age before updating |
Common Patterns
Run Multiple Watchtower Instances
Run one instance for production containers and another for development:
services:
watchtower-prod:
image: nickfedor/watchtower:latest
command: --scope production --interval 300
labels:
- "com.centurylinklabs.watchtower.scope=production"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
watchtower-dev:
image: nickfedor/watchtower:latest
command: --scope development --interval 30
labels:
- "com.centurylinklabs.watchtower.scope=development"
volumes:
- /var/run/docker.sock:/var/run/docker.sockExclude System Containers
Exclude Watchtower itself and other infrastructure containers:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_DISABLE_CONTAINERS=watchtower,traefik,portainer
volumes:
- /var/run/docker.sock:/var/run/docker.sockExclude Containers by Label
Exclude containers managed by third-party orchestrators using arbitrary labels:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_DISABLE_CONTAINERS_BY_LABEL=managed-by=external
volumes:
- /var/run/docker.sock:/var/run/docker.sockMonitor Containers by Label
Only monitor containers with specific labels:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_ENABLE_CONTAINERS_BY_LABEL=env=prod,team=platform
volumes:
- /var/run/docker.sock:/var/run/docker.sockMonitor Only Specific Image Registries
Monitor only images from your private registry:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_MONITOR_IMAGE_NAMES=registry.example.com/.*
volumes:
- /var/run/docker.sock:/var/run/docker.sockSelective Monitoring with Enable Label
Use label enable to explicitly opt containers into monitoring:
services:
watchtower:
image: nickfedor/watchtower:latest
environment:
- WATCHTOWER_LABEL_ENABLE=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
myapp:
image: myapp:latest
labels:
- "com.centurylinklabs.watchtower.enable=true"