Files
dokku/docs/advanced-usage/builds.md
Jose Diaz-Gonzalez 3bf6c72451 fix: align Go-plugin :report JSON keys with bash-strip convention
Every Go-implemented plugin's `:report --format json` now emits keys without the redundant `<plugin>-` head segment, matching the shape bash plugins have always emitted. The CLI flag names and `:set` semantics are unchanged. For backwards compatibility during the 0.38.x patch series, the legacy `<plugin>-<property>` keys are emitted side-by-side with the new keys, and a future major release will drop the legacy keys. `common.ReportSingleApp` is refactored to accept a `ReportSingleAppInput` struct with a `Validate()` method so the input is checked before any work runs, which also catches the latent `"docker options"` reportType bug at the API boundary.
2026-05-27 07:17:00 -04:00

198 lines
7.8 KiB
Markdown

# Build Tracking
> [!IMPORTANT]
> New as of 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
```json
{
"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** - `build` for paths that produce a new image (`git push`, `git:*`, `ps:rebuild`); `deploy` for paths that re-deploy an existing image (`ps:restart`, `ps:start`, `dokku deploy`, `config:set`).
- **status** - on-disk values are `running | succeeded | failed | canceled`. `abandoned` is a fifth display-only value computed at read time for `running` records 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:
```shell
dokku builds:list
```
```
=====> Currently running builds
App Build ID Kind PID Source Started
myapp 01j8c4xv7bk5w3 build 12345 git-hook 2026-04-30T13:50:00Z
```
With an app, `builds:list` returns running builds plus the most recent finalized records up to the configured retention:
```shell
dokku builds:list myapp
```
Filter by kind or status:
```shell
dokku builds:list myapp --kind build
dokku builds:list myapp --status running
dokku builds:list --format json
```
## Inspecting a single build
```shell
dokku builds:info myapp 01j8c4xv7bk5w3
```
```
=====> Build 01j8c4xv7bk5w3
Build ID: 01j8c4xv7bk5w3
App: myapp
Kind: build
Status: succeeded
PID: 12345
Source: git-hook
Started: 2026-04-30T13:50:00Z
Finished: 2026-04-30T13:51:14Z
Duration: 1m14s
Exit Code: 0
Log: /var/lib/dokku/data/builds/myapp/01j8c4xv7bk5w3.log
```
JSON output includes the same fields plus a computed `log_path`:
```shell
dokku builds:info myapp 01j8c4xv7bk5w3 --format json | jq .
```
## Streaming build output
```shell
# 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).
```shell
dokku builds:cancel myapp
```
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:
```shell
dokku builds:set myapp retention 50
```
Set the global default:
```shell
dokku builds:set --global retention 10
```
Clear an override (falls back to the global value, then the default):
```shell
dokku builds:set myapp retention
```
## 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:
```shell
dokku builds:prune myapp
dokku builds:prune --all-apps
```
## Reports
```shell
dokku builds:report
dokku builds:report myapp
dokku builds:report myapp --build-status
```
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.
## Properties
### Settable properties
> [!NOTE]
> The `Report flags` column lists the CLI argument names accepted by `builds:report`. The JSON keys emitted by `builds:report --format json` are the same names with the leading `--builds-` stripped (e.g. `retention`, `global-retention`, `computed-retention`). Legacy keys with the `builds-` prefix (e.g. `builds-retention`) are also emitted during the 0.38.x deprecation window and will be removed in a future major release. Status keys (`build-id`, `build-status`, etc.) have no plugin prefix and are unaffected.
| Property | Scope | Default | Report flags | Description |
|---|---|---|---|---|
| `retention` | app + global | `20` | `--builds-retention`, `--builds-global-retention`, `--builds-computed-retention` | Number of recent build records kept per app; older finalized records are pruned at the end of each deploy |
### Read-only flags
The following flags surface in `builds:report` but are not managed by `builds:set` - they are derived metadata recorded during the build:
| Flag | Description |
|---|---|
| `--build-id` | Unique identifier of the most recent build for the app |
| `--build-kind` | Whether the record was a `build` or a `deploy` |
| `--build-status` | Display status (`running`, `succeeded`, `failed`, `canceled`, `abandoned`); computed at read time |
| `--build-source` | Trigger that started the build (e.g. `git-hook`, `ps:rebuild`, `ps:restart`) |
| `--build-pid` | PID of the build process |
| `--build-started-at` | UNIX timestamp the build started |
| `--build-finished-at` | UNIX timestamp the build finished |
| `--build-exit-code` | Exit code of the build process |