Build Tracking¶
New
Introduced in 0.38.0
Every deploy that flows through Dokku - whether triggered by git push, ps:rebuild, ps:restart, config:set, or git:from-archive / git:from-image / git:sync / git:load-image - is recorded as a structured build record on disk. The builds plugin lets operators inspect what is currently deploying, look up the result of an old deploy, and stream the captured build log without depending on journalctl.
builds:cancel <app> # Cancel a running build for an app
builds:info <app> <build-id> [--format json] # Show details for a single build
builds:list [<app>] [--format json] [--kind ...] [--status ...]
# List builds (running across all apps, or running + history for one)
builds:output <app> [<build-id>|current] # Show build output (tail for live, cat for finished)
builds:prune <app> [--all-apps] # Reap abandoned records and apply retention
builds:report [<app>] [<flag>] # Display a build report
builds:set [--global|<app>] <key> [<value>] # Set or clear a builds property
Build records¶
Every build is identified by a sortable base36 ULID-style id (DOKKU_BUILD_ID) generated at deploy start. For each build, Dokku writes:
$DOKKU_LIB_ROOT/data/builds/<app>/<build-id>.json- the structured record$DOKKU_LIB_ROOT/data/builds/<app>/<build-id>.log- the captured stdout/stderr of the deploy
Output is also tagged into syslog as dokku-<build-id> so journalctl -t dokku-<build-id> continues to work. The on-disk log file is the durable source of truth and is read for builds:output even when journald has rotated old entries away.
Record schema¶
{
"id": "01j8c4xv7bk5w3",
"app": "myapp",
"kind": "build",
"pid": 12345,
"started_at": "2026-04-30T13:50:00Z",
"finished_at": "2026-04-30T13:51:14Z",
"status": "succeeded",
"source": "git-hook",
"exit_code": 0
}
- kind -
buildfor paths that produce a new image (git push,git:*,ps:rebuild);deployfor paths that re-deploy an existing image (ps:restart,ps:start,dokku deploy,config:set). - status - on-disk values are
running | succeeded | failed | canceled.abandonedis a fifth display-only value computed at read time forrunningrecords whose PID is no longer alive; it is never persisted to the record. - source - the user-typed command that originated the deploy (e.g.
git-hook,ps:restart,config-redeploy,git:sync).
Listing builds¶
Without an app argument, builds:list shows currently-running builds across every app on the host:
With an app, builds:list returns running builds plus the most recent finalized records up to the configured retention:
Filter by kind or status:
dokku builds:list myapp --kind build
dokku builds:list myapp --status running
dokku builds:list --format json
Inspecting a single build¶
JSON output includes the same fields plus a computed log_path:
Streaming build output¶
# tail -f the live build, or cat the log for a finished one
dokku builds:output myapp 01j8c4xv7bk5w3
# resolve "current" from the in-flight deploy
dokku builds:output myapp current
If the on-disk log file is missing (for example, a build from before this plugin was installed), builds:output falls back to journalctl -t dokku-<build-id>.
Cancelling a build¶
builds:cancel reads the active .deploy.lock for an app, looks up the matching build record, and sends SIGQUIT to the deploy's process group. The record is finalized as canceled (or failed if the process had already exited without finalizing - in that case Dokku marks the record so it doesn't sit in running forever).
If the record is already finalized when cancel runs, no signal is sent and the record is left untouched.
Retention¶
Build records are pruned by count, not by age. The default retention is 20 records per app. Live in-flight deploys are never pruned regardless of count.
Set a per-app retention:
Set the global default:
Clear an override (falls back to the global value, then the default):
Manual pruning¶
builds:prune invokes the same logic that runs at the end of every deploy - it reaps abandoned records (status=running with a dead PID, finalized as failed) and trims the directory to the configured retention. Useful after lowering retention via builds:set or to clean up after a host reboot:
Reports¶
Available flags:
--build-id,--build-kind,--build-status,--build-pid,--build-source,--build-started-at,--build-finished-at,--build-exit-code: details of the most recent build for the app--builds-retention: per-app retention override (empty if none)--builds-global-retention: global retention override (empty if none)--builds-computed-retention: the resolved retention applied to this app
--build-status returns the display status, so an abandoned in-flight build shows abandoned rather than running. The raw on-disk status is only visible by reading the JSON record directly.