Skip to main content
Version: 9.x

Docker

The docker trigger automatically restarts or recreates local containers when updated images are available.


⚙️ Configuration Variables​

WUD_TRIGGER_DOCKER_{trigger_name}_DRYRUN
Optionalbooleandefault: false

When enabled, only pulls the new image ahead of time without recreating the container

WUD_TRIGGER_DOCKER_{trigger_name}_PRUNE
Optionalbooleandefault: false

Prune obsolete image versions after a successful upgrade

WUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACK
Optionalbooleandefault: false

Enable the automatic rollback on HEALTHCHECK failure for every container managed by this trigger (see Automatic rollback on healthcheck failure)

WUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKGRACE
Optionalintegerdefault: 10000

Grace period (in milliseconds) the replacement container must stay up when the image defines no HEALTHCHECK before the update is accepted

WUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKINTERVAL
Optionalintegerdefault: 10000

Sampling interval (in milliseconds) between two health observations

WUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKWINDOW
Optionalintegerdefault: 300000

How long (in milliseconds) to wait for the replacement container to report a terminal health status (healthy/unhealthy) when the image defines a HEALTHCHECK

WUD_TRIGGER_DOCKER_{trigger_name}_SELFUPDATE
Optionalbooleandefault: false

Allow WUD to update the container it runs in itself (see Updating WUD itself)

WUD_TRIGGER_DOCKER_{trigger_name}_SELFUPDATETIMEOUT
Optionalintegerdefault: 120000

How long (in milliseconds) to wait for the replacement WUD container to become healthy before rolling back

info

This trigger also supports all common trigger configuration options (such as thresholds, scheduling, and batching).


🔄 Updating WUD itself​

Replacing the container WUD runs in is a special case: the trigger has to stop that container, and stopping it kills the process that still has to remove, recreate and start it. WUD would go down mid-update and stay down, because a deliberate docker stop does not trigger a restart policy.

By default WUD refuses to do it and logs an actionable error instead of leaving you with a stopped container:

Refusing to update the container WUD runs in: stopping it would abort the update
and leave the container down. Enable it with
WUD_TRIGGER_DOCKER_{trigger_name}_SELFUPDATE=true, or exclude WUD from this
trigger with the wud.trigger.exclude label and update it externally.

Opting in​

Set WUD_TRIGGER_DOCKER_{trigger_name}_SELFUPDATE=true. WUD then delegates the swap to a short-lived helper container instead of doing it in-process. The helper runs the image WUD is running right now (not the one being installed), so the code performing the swap is always known to support it, and it:

  1. creates the replacement under a temporary name, before touching anything;
  2. stops the current WUD container;
  3. starts the replacement;
  4. waits for it to become healthy;
  5. on success, removes the old container and renames the replacement;
  6. on failure, removes the replacement and restarts the old container.

The helper mounts the same Docker socket as the watcher and is named wud-self-update. It is deliberately not removed when it finishes: if a self-update fails, WUD is not running to record why, so the helper's logs are the only account of what happened. Check them with docker logs wud-self-update. The next self-update replaces it, so at most one is ever left behind.

warning

Self-update requires the watcher to talk to Docker over a socket. It is not supported for watchers configured with WUD_WATCHER_{watcher_name}_HOST.

Prefer to keep WUD out of it?

Add the wud.trigger.exclude label to the WUD container. WUD keeps reporting its own updates in the UI, and you apply them yourself with docker compose pull wud && docker compose up -d wud.

When WUD cannot tell which container it runs in​

WUD resolves its own container id from /proc/self/mountinfo. If your runtime does not expose it there, declare it explicitly:

WUD_CONTAINER_ID
Optionalstring

Id of the container WUD runs in. Only needed when auto-detection fails


🪝 Pre & Post Update Hooks​

Hooks allow you to run automated tasks before (pre) and after (post) a container is updated.

Quality Gate (Safety First)​

Pre-update hooks act as a Quality Gate:

  • If a pre-hook fails (non-zero exit code or timeout), the update process is aborted immediately.
  • The existing container is never stopped or removed, ensuring service continuity and preventing broken deployments.

Hook Types​

TypeTargetDescription
exec (Type A)target: "self" (default)Runs a shell command inside the container being updated.
exec (Type B)target: "<container_name>"Runs a shell command inside another local container (e.g. running a DB dump before updating a web app).
trigger (Type C)trigger: "<trigger_name>"Declares a chained invocation of another WUD trigger (e.g. sending a Slack notification).

Environment Variables Injected into exec Hooks​

When executing commands inside containers, WUD injects contextual environment variables:

VariableDescriptionExample
WUD_CONTAINER_NAMEName of the target containernextcloud
WUD_CONTAINER_IDDocker ID of the target containera1b2c3d4e5f6
WUD_IMAGE_NAMEName/repository of the container imagelinuxserver/nextcloud
WUD_IMAGE_REGISTRYRegistry of the container imagedocker.io
WUD_IMAGE_OLD_TAGCurrent tag of the container image27.0.1
WUD_IMAGE_NEW_TAGNew tag being deployed27.1.0
WUD_IMAGE_OLDFull old image reference (name:tag or name@digest)linuxserver/nextcloud:27.0.1
WUD_IMAGE_NEWFull new image reference (name:tag or name@digest)linuxserver/nextcloud:27.1.0
WUD_WATCHER_NAMEWatcher that detected the updatelocal
WUD_TRIGGER_NAMETrigger executing the hooklocal
WUD_HOOK_PHASECurrent hook phasepre or post

Configuration via Container Labels​

You can configure hooks directly on your containers using Docker labels. Use numeric indexes (1, 2, ...) to control the execution order:

LabelDescriptionDefault
wud.hook.<index>.phasePhase to execute: pre or postRequired
wud.hook.<index>.typeHook type: exec or triggerRequired
wud.hook.<index>.commandShell command to execute (for exec type)Required for exec
wud.hook.<index>.targetContainer target (self or container name)self
wud.hook.<index>.triggerName of chained trigger (for trigger type)Required for trigger
wud.hook.<index>.timeoutExecution timeout in milliseconds60000 (60s)

Concrete Examples​

Pre-update MySQL database backup (Type B)​

A web service updates its backend after taking a database backup in a separate MySQL container:

labels:
- "wud.hook.1.phase=pre"
- "wud.hook.1.type=exec"
- "wud.hook.1.target=mysql-db"
- "wud.hook.1.command=mysqldump -u root -psecret mydb > /backups/mydb-pre-update.sql"
- "wud.hook.1.timeout=120000"
Pre-update Maintenance Mode and Post-update Slack Notification​
labels:
# Put app in maintenance mode before update
- "wud.hook.1.phase=pre"
- "wud.hook.1.type=exec"
- "wud.hook.1.command=php occ maintenance:mode --on"
# Turn off maintenance mode after update
- "wud.hook.2.phase=post"
- "wud.hook.2.type=exec"
- "wud.hook.2.command=php occ maintenance:mode --off"
# Trigger chained notification
- "wud.hook.3.phase=post"
- "wud.hook.3.type=trigger"
- "wud.hook.3.trigger=slack"

🩺 Automatic rollback on healthcheck failure​

When ROLLBACK is enabled (globally with the env var, or per container with the wud.rollback.enable label), WUD keeps the previous container archived under a temporary name while it validates the replacement. If the replacement does not become healthy, WUD restores the previous container and removes the broken one, so a bad release never leaves a service down.

The same options can be set per container with labels (labels win over the trigger configuration):

LabelEquivalent env varDefault
wud.rollback.enableWUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKfalse
wud.rollback.windowWUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKWINDOW300000
wud.rollback.intervalWUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKINTERVAL10000
wud.rollback.graceWUD_TRIGGER_DOCKER_{trigger_name}_ROLLBACKGRACE10000

HEALTHCHECK vs grace period​

WUD distinguishes two cases when validating the replacement:

  • The image defines a HEALTHCHECK: WUD waits up to ROLLBACKWINDOW ms for the container to report healthy or unhealthy (sampling every ROLLBACKINTERVAL ms). unhealthy, a crash, or a window exhaustion all trigger the rollback.
  • The image defines no HEALTHCHECK: there is no health signal, so WUD falls back to a liveness smoke test: the replacement must stay up for ROLLBACKGRACE ms. It is accepted only if it is still running at the end of the grace period; a crash during the grace period rolls back.

Transient Docker Engine inspection errors are retried and never produce a verdict on their own; only an observed exit or a container that stays uninspectable for the whole window/grace is treated as a crash.

warning

A container started with AutoRemove cannot be archived, so the automatic rollback is skipped for it (WUD logs a warning and proceeds without a rollback safety net).

info

When at least one container is updated through a Docker Compose project, the rollback coordination is handled at the project level — see the Docker Compose trigger.

Example​

services:
wud:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WUD_TRIGGER_DOCKER_LOCAL_ROLLBACK=true
- WUD_TRIGGER_DOCKER_LOCAL_ROLLBACKWINDOW=300000
- WUD_TRIGGER_DOCKER_LOCAL_ROLLBACKGRACE=15000

Label equivalent on a monitored container:

services:
web:
image: my/web:2.0.0
labels:
- wud.rollback.enable=true
- wud.rollback.window=120000
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost/health']
interval: 5s
timeout: 3s
retries: 3

🚀 Examples​

Auto-Update Standalone Containers with Pruning​

services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WUD_TRIGGER_DOCKER_LOCAL_PRUNE=true

Let WUD Update Itself​

services:
whatsupdocker:
image: getwud/wud
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WUD_TRIGGER_DOCKER_LOCAL_PRUNE=true
- WUD_TRIGGER_DOCKER_LOCAL_SELFUPDATE=true