Skip to main content
Version: Next 🚧

One-Shot Headless Mode (CLI)

WUD ships one Docker image with two entry points. Besides the classic long-running server, the same image can run a one-shot headless scan: watch every container once, optionally notify triggers, print the results as JSON on stdout, then exit.

This mode is designed for CI pipelines, cron jobs, and scripts:

docker run --rm -e WUD_RUN_MODE=oneshot getwud/wud watch

No store file is created, no web server is started, and the process always exits.


🚀 Selecting the Mode​

The mode is selected exclusively with the WUD_RUN_MODE environment variable:

WUD_RUN_MODE
Optionalstringdefault: server

Execution mode for WUD. Set to oneshot to run a single scan and exit, or server (default) to start the long-running web UI, REST API, and background watchers.

Allowed values:`server`, `oneshot`

When WUD_RUN_MODE=oneshot is set, the entry point used is:

node dist/index <command> [options]

In the container, the entrypoint detects the mode automatically:

docker run --rm -e WUD_RUN_MODE=oneshot getwud/wud watch
docker run --rm -e WUD_RUN_MODE=oneshot getwud/wud --help
One image, two entry points

WUD_RUN_MODE does not select a different image: the getwud/wud image contains the full server, the web UI, and the SQLite store. The one-shot mode simply skips starting the server, the store, and the metrics endpoint.


🔧 Commands​

CommandDescription
watchFull scan → compute updates → (optional) triggers → JSON output → exit. Default when no command is given (wud alone = wud watch).
versionPrint the WUD version (e.g. 9.1.0). Useful for CI traceability.
--helpPrint the usage and exit.

watch options​

OptionDescription
--update-availableOutput only the containers that have an update available right now (same filter as the in-memory API filter). The output filter is orthogonal to the exit code.
--format=jsonJSON array of containers (default).
--format=ndjsonOne JSON object per line (NDJSON).
--fail-on-updateExit with code 1 when at least one update is available, so pipelines can gate on updates.
Exit codes
CodeMeaning
0Scan completed, no update available.
1Technical error (Docker socket unreachable, invalid configuration, ...) or, with --fail-on-update, at least one update available.

📦 Output Contract​

The output is byte-compatible with GET /api/containers: the same validated container model, the same undefined → null serialization, and the same deterministic sort order (watcher → name → image.tag.value).

Default output — a JSON array of all containers, including containers in error:

[
{
"id": "f4cbbaa4f918",
"name": "nginx",
"displayName": "nginx",
"displayIcon": "mdi:docker",
"status": "running",
"watcher": "local",
"image": {
"id": "8e4a1e2c7f",
"registry": { "name": "hub.public", "url": "registry-1.docker.io" },
"name": "library/nginx",
"tag": { "value": "latest", "semver": false },
"digest": { "watch": true, "value": "sha256:ed05ca7857c7", "repo": "sha256:ed05ca7857c7" },
"architecture": "amd64",
"os": "linux"
},
"result": { "tag": "latest", "digest": "sha256:2f1b68a9f597" },
"updateAvailable": true,
"updateKind": { "kind": "digest", "localValue": "sha256:ed05ca7857c7", "remoteValue": "sha256:2f1b68a9f597" },
"labels": {},
"isCoolingDown": false,
"isSnoozed": false,
"snoozedVersion": null,
"snoozedUntil": null,
"delay": null
}
]

Stateless fields that do not exist in one-shot mode (snoozedVersion, snoozedUntil, delay, link, ...) are serialized as null — never as missing keys — exactly like the API.

Diagnostics go to stderr

Logs and error messages are written to stderr so stdout stays perfectly clean for the JSON contract:

docker run --rm -e WUD_RUN_MODE=oneshot getwud/wud watch 1>containers.json 2>wud.log

⚙️ Configuration​

One-shot reuses the existing environment variables — no new schema:

VariablesOne-shot behavior
WUD_WATCHER_*Used (unchanged Joi schemas).
WUD_REGISTRY_*Used (unchanged Joi schemas).
WUD_TRIGGER_*Optional — with no trigger variable the run is pure JSON with no side effects; with trigger variables the same engine notifies/acts.
WUD_STORE_*, WUD_AUTH_*, WUD_SERVER_*, WUD_PROMETHEUS_*Ignored in one-shot mode.
No database

One-shot never calls WUD_STORE_*: no SQLite file is created or touched. Consequently, stateful features are not available (documented as N/A):

  • snooze / snoozed version (isSnoozed, snoozedVersion)
  • cooling-down period (isCoolingDown)
  • watch delay (wud.watch.delay)

updateAvailable is the bare "an update is available right now" signal, mirroring the first-scan behavior of the server.


💡 Examples​

# One scan, full JSON
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e WUD_RUN_MODE=oneshot \
getwud/wud watch

# Gate a pipeline on available updates
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e WUD_RUN_MODE=oneshot \
getwud/wud watch --update-available --fail-on-update

# One JSON object per line + logs on stderr
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-e WUD_RUN_MODE=oneshot \
getwud/wud watch --format=ndjson