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. |
Note
- 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.
This label is set on the container you want to manage, not on the Watchtower instance.
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
To exclude a container, set the label to 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:
Note
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.
Exclude Specific Containers¶
Use the disable containers option to exclude containers by name. This supports comma- or space-separated values and regex patterns.
Label-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.
An 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.
Note
Values containing commas are not supported. Use individual key=value pairs separated by commas.
Note
A label entry with an empty value (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).
If no tag is specified in the image reference, :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.
Exclude Specific Images¶
Use the skip image names option to exclude containers whose image matches at least one pattern.
Monitoring 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: ghcr.io/sidneyojr/watchtower:latest
environment:
- WATCHTOWER_SCOPE=production
labels:
- "com.centurylinklabs.watchtower.scope=production"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Note
- 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:
Include only containers matching specific patterns:
Monitor only containers using nginx or redis images with any tag:
Label 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: ghcr.io/sidneyojr/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: ghcr.io/sidneyojr/watchtower:latest
command: --scope development --interval 30
labels:
- "com.centurylinklabs.watchtower.scope=development"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
docker run -d \
--name watchtower-production \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/sidneyojr/watchtower \
--scope production --interval 300
docker run -d \
--name watchtower-development \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/sidneyojr/watchtower \
--scope development --interval 30
Exclude System Containers¶
Exclude Watchtower itself and other infrastructure containers:
Exclude Containers by Label¶
Exclude containers managed by third-party orchestrators using arbitrary labels:
Monitor Containers by Label¶
Only monitor containers with specific labels:
Monitor Only Specific Image Registries¶
Monitor only images from your private registry:
Selective Monitoring with Enable Label¶
Use label enable to explicitly opt containers into monitoring: