The DOKKU_PID now never gets overwritten except in the case that DOKKU is executed by the sudo user. If the command ends up executing a deploy, then the pid of the `dokku` owned process - which may have been executed via sudo - will be written to the file lock, allowing future commands to interact with the original process.
Additionally, the new builds plugin can be used to handle killing a build.
Multi-flag inputs (e.g. `--build-arg X=Y --link a --link b`) used to be stored as a single line, which bypassed the per-line filter that drops `--link` and similar flags for dockerfile-based builders. Each `--flag [value]` group is now stored as its own entry, and a `--process` typed after the app name is lifted into the subcommand flag instead of being stored as a docker option.
Bundling these Secrets in the app helm chart caused two bugs in the scheduler-k3s plugin: a chart rollback could delete Secrets that older ReplicaSets still referenced by exact timestamped name (`env-{app}.{ts}` and `ims-{app}.{ts}`), hard-crashing pods until manual intervention; and the strategic-merge `patchMergeKey` on `imagePullSecrets` let stale entries leak into the live Deployment until the list pointed at many nonexistent Secrets. Each Secret now lives in its own helm release with a stable name (`config-{app}` and `pull-secret-{app}`), installed before the app chart on every deploy. The deployment trigger also prunes any leaked `imagePullSecrets` entries from the live Deployment so the next deploy lands on a clean list, and the rename and destroy paths uninstall the new releases (and the previously-leaked TLS release on rename) under the old app name.
Every `:report` subcommand now recognizes `--global` as a scope selector that limits the report to globally-configured properties, including in JSON form via `--global --format json`. Previously this combination was rejected because `--global` was treated as an info flag, conflicting with `--format`. The shared `common.ParseReportArgs` helper now returns a `ReportArgs` struct exposing the parsed scope; each Go and bash report selects a global-only flag map when scope is global, and skips per-app verification.
When ps:rebuild runs against an image-based deploy via git:from-image, the resulting image often shares the same SHA as the previous deployment, so retiring the old container's image would target the live image of the new container. The retirement is now skipped when another running container of the same app still references the image, and the cron retire loop self-heals previously stuck entries the next time it encounters them.
When pre-validating a custom nginx.conf.sigil before the build phase, no app listeners exist yet on first deploys. Templates that emit `proxy_pass http://app-port` while gating the matching upstream block on `DOKKU_APP_WEB_LISTENERS` render an undefined upstream, causing `nginx -t` to fail with "host not found in upstream". Pre-validation now passes a `127.0.0.1:5000` placeholder for `DOKKU_APP_WEB_LISTENERS` so the upstream block emits a static server entry and the template can be validated for syntax without depending on live listeners.
Renders the user-supplied nginx.conf.sigil via sigil into a tmp file and runs `nginx -t` against a wrapped copy as soon as the template is extracted from the source tree, so syntactically invalid templates abort the deploy before the build phase runs. Skipped when `proxy-type` is not `nginx`, when `disable-custom-config=true`, or when no custom template was extracted. Closes#7827.
Adds a `docker-args-process-build` trigger to the resource plugin so
limits set via `dokku resource:limit --process-type build APP` are
applied during the build phase. Only `build.limit.*` properties are
read - defaults do not inherit, since builds typically need more memory
than runtime and a leaked tiny default would cause confusing OOM
failures. Reservations are never applied at build time. Allowed flags
are filtered per builder: herokuish gets cpu, memory, memory-swap, and
nvidia-gpu; dockerfile gets memory and memory-swap; pack, nixpacks,
railpack, lambda, and null emit nothing because their underlying CLIs
do not accept docker run resource flags. The dockerfile builder
whitelists the new memory flags and corrects pre-existing typos where
`--ssh` mapped to `--platform` and `--ulimit` mapped to `--tag`.
Keda 2.17+ rejects ScaledObjects whose spec.fallback is set unless at least one trigger is not a cpu or memory scaler, so unconditionally emitting fallback broke deploys for apps autoscaled on cpu or memory alone. The chart now skips the fallback block when every configured trigger is cpu or memory and keeps the existing behavior otherwise.
The docker-local scheduler now sends `SIGTERM` to old containers immediately after a successful deploy via `docker container kill --signal=SIGTERM`, rather than waiting `wait-to-retire` seconds before signaling. This matches Heroku's graceful-shutdown contract and lets applications begin draining in-flight work as soon as proxy traffic switches. The existing `wait-to-retire` grace period and `stop-timeout-seconds` hard-stop continue to apply unchanged as the authoritative cleanup path.
Adds a `--process` flag (repeatable) to docker-options:add/remove/clear/list and the new docker-options:list subcommand for querying a single process+phase pair. Process scoping is supported only for the deploy phase since build runs once per app and run covers ad-hoc commands and cron tasks where no Procfile process type is available. Storage moves from `$DOKKU_ROOT/$APP/DOCKER_OPTIONS_*` files to property lists under `/var/lib/dokku/config/docker-options/$APP/{processType}.{phase}`, with `_default_` as the sentinel for app-wide options. The install trigger migrates pre-existing DOCKER_OPTIONS_* files into property lists once and renames them to `.migrated`; a global marker makes re-runs strictly no-op. The legacy docker-args-{build,deploy,run} bash triggers are reimplemented in Go alongside a new docker-args-process-deploy trigger that surfaces per-process options to the scheduler. The :report command exposes one dynamic flag per configured `process.deploy` pair (e.g. `--docker-options-deploy.web`) and supports `--format json`. There is no `--global` flag; omitting `--process` keeps the historical default behaviour, since `--global` elsewhere in dokku means "across all apps". Closes#2441.
Fresh apt installs now drop a catch-all server block at `/etc/nginx/conf.d/00-default-vhost.conf` that uses `ssl_reject_handshake on` and `return 444` to drop requests with unknown Host headers. Conflicting upstream nginx default vhosts are renamed to `*.dokku-disabled` rather than deleted, preserving any local edits. The new `dokku/install_default_site` debconf flag opts out of the install. Upgrades leave existing nginx config untouched.
Some helm chart upgrades require side-effects that a plain `helm upgrade` cannot perform, such as deleting deployments whose immutable selectors changed. Charts may now register pre and post upgrade hooks against a target version; applicable hooks fire in ascending semver order, each bracketed around an upgrade to its version, with a final upgrade to the chart's configured version when needed. The new `keda-add-ons-http` 0.12.2 hook deletes the chart-managed deployments before the upgrade so the new selectors take effect cleanly.
Mirrors the JSON output convention already used by scheduler:report, builder:report, network:report, and traefik:report. Both plugins now accept `--format json` to emit a single-line JSON object whose keys are the property names with the plugin prefix stripped. Combining `--format` with an info flag is rejected with an error message that matches the Go-based report helper.
Closes#8499
Adds `git:auth-status HOST [USERNAME] [PASSWORD]` which exits 0 when the
configured `.netrc` entry matches the requested state and 1 otherwise,
allowing external tooling to detect whether `git:auth` would change
anything without reading `$DOKKU_ROOT/.netrc` directly. Both `git:auth`
and `git:auth-status` now also accept the password via `STDIN`.
# History
## 0.37.10
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.10/bootstrap.sh
sudo DOKKU_TAG=v0.37.10 bash bootstrap.sh
```
### Tests
- #8491: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 285 to 287 in /tests/apps/php
- #8478: @josegonzalez chore: label test app dependency updates as type: tests
### Dependencies
- #8486: @dependabot[bot] chore(deps): bump click from 8.3.2 to 8.3.3 in /docs/_build
- #8492: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.29.0 to 1.31.0 in /plugins/scheduler-k3s
- #8489: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.42 to 2.11.43 in /plugins/scheduler-k3s
- #8488: @dependabot[bot] chore(deps): bump timberio/vector from 0.54.0-debian to 0.55.0-debian in /plugins/logs
- #8487: @dependabot[bot] chore(deps): bump traefik from v3.6.13 to v3.6.14 in /plugins/traefik-vhosts
- #8483: @dependabot[bot] chore(deps): update markdown requirement from <3.11,>=3.2.1 to >=3.10.2,<3.11 in /docs/_build
- #8485: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.35.2 to 0.35.4 in /plugins/scheduler-k3s
- #8484: @dependabot[bot] chore(deps): bump k8s.io/client-go from 0.35.2 to 0.35.4 in /plugins/scheduler-k3s
- #8482: @dependabot[bot] chore(deps): bump ruby from 4.0.2 to 4.0.3 in /tests/apps/dockerfile-entrypoint
- #8481: @dependabot[bot] chore(deps): bump psycopg2-binary from 2.9.11 to 2.9.12 in /tests/apps/dockerfile-release
- #8479: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.23.0 to 0.23.1 in /plugins/scheduler-k3s
- #8480: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.35.3 to 1.35.4 in /plugins/scheduler-k3s
- Move proxy-port and proxy-ssl-port properties from ports plugin to
proxy plugin where they conceptually belong
- Generalize proxy:set to handle any property (matching ps:set pattern)
instead of only handling the type property
- Fix apps:set --global flag parsing (pflag treats --global as a flag,
not an argument — must be defined explicitly like ps:set does)
- Add missing property-functions source to scheduler-docker-local
shell scripts (scheduler-enter, scheduler-run, scheduler-deploy,
check-deploy, bin/scheduler-deploy-process-container)
- Update nginx-vhosts property references from ports to proxy plugin
- Update tests to use proxy:set for proxy-port properties
Custom nginx.conf.sigil templates that reference DOKKU_APP_WEB_LISTENERS
may now receive an empty value when rendered for apps without running web
processes. The migration guide documents how to handle this with a
conditional in the template.
When an app has no web listeners (not yet deployed, no web process type,
or web processes not running), generate a minimal nginx config that
returns 502 Bad Gateway instead of having no config at all. This ensures
domains resolve, monitoring tools detect non-200 status codes, and SSL
certificate provisioning tools like letsencrypt can function.
The buildpacks entry in tests/apps/dockerfile/app.json caused
the post-extract trigger to write a .buildpacks file during
Dockerfile-based deploys, breaking builder detection. Remove
the entry and add Go unit tests for getBuildpacks/validBuildpackURL,
a bats integration test for deploying with app.json buildpacks,
and documentation for the new feature.
# History
## 0.37.9
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.9/bootstrap.sh
sudo DOKKU_TAG=v0.37.9 bash bootstrap.sh
```
### Dependencies
- #8473: @dependabot[bot] chore(deps): bump k8s.io/api from 0.35.2 to 0.35.4 in /plugins/scheduler-k3s
- #8474: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.22.5 to 0.23.0 in /plugins/scheduler-k3s
- #8476: @dependabot[bot] chore(deps): bump github.com/go-acme/lego/v4 from 4.25.2 to 4.34.0 in /plugins/scheduler-k3s
- #8475: @dependabot[bot] chore(deps): bump github.com/moby/spdystream from 0.5.0 to 0.5.1 in /plugins/scheduler-k3s
# History
## 0.37.8
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.8/bootstrap.sh
sudo DOKKU_TAG=v0.37.8 bash bootstrap.sh
```
### Bug Fixes
- #8451: @mykolasolodukha Fix client prepending `--app` for non-app commands
### New Features
- #8443: @chemicalkosek Add application/graphql-response+json to nginx gzip_types
### Dependencies
- #8470: @dependabot[bot] chore(deps): bump packaging from 26.0 to 26.1 in /docs/_build
- #8471: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.35.0 to 1.35.3 in /plugins/scheduler-k3s
- #8472: @dependabot[bot] chore(deps): bump k8s.io/apimachinery from 0.35.2 to 0.35.3 in /plugins/scheduler-k3s
- #8413: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.24.0 to 1.28.0 in /plugins/scheduler-k3s
- #8425: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.19.3 to 1.20.0 in /plugins/scheduler-k3s
- #8469: @dependabot[bot] chore(deps): bump zipp from 3.23.0 to 3.23.1 in /docs/_build
- #8450: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.13.0 to 3.13.1 in /plugins/cron
- #8465: @dependabot[bot] chore(deps): bump github.com/joho/godotenv from 1.2.0 to 1.5.1 in /plugins/config
- #8463: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.49.0 to 0.50.0 in /plugins/common
- #8449: @dependabot[bot] chore(deps): bump click from 8.3.1 to 8.3.2 in /docs/_build
- #8464: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.20.1 to 3.20.2 in /plugins/scheduler-k3s
- #8458: @dependabot[bot] chore(deps): bump traefik from v3.6.12 to v3.6.13 in /plugins/traefik-vhosts
- #8457: @dependabot[bot] chore(deps): bump golang from 1.26.1 to 1.26.2 in /tests/apps/zombies-dockerfile-no-tini
- #8456: @dependabot[bot] chore(deps): bump golang from 1.26.1 to 1.26.2 in /tests/apps/go-fail-postdeploy
- #8455: @dependabot[bot] chore(deps): bump golang from 1.26.1 to 1.26.2 in /tests/apps/gogrpc
- #8454: @dependabot[bot] chore(deps): bump golang from 1.26.1 to 1.26.2 in /tests/apps/zombies-dockerfile-tini
- #8453: @dependabot[bot] chore(deps): bump golang from 1.26.1 to 1.26.2 in /tests/apps/go-fail-predeploy
- #8452: @dependabot[bot] chore(deps): bump rack-session from 2.1.1 to 2.1.2 in /tests/apps/ruby
- #8459: @dependabot[bot] chore(deps): bump django from 5.2.12 to 5.2.13 in /tests/apps/dockerfile-release
- #8444: @dependabot[bot] chore(deps): bump rack from 3.2.5 to 3.2.6 in /tests/apps/ruby
- #8445: @dependabot[bot] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 in /plugins/scheduler-k3s
- #8447: @dependabot[bot] chore(deps): bump werkzeug from 3.1.7 to 3.1.8 in /tests/apps/python-flask
- #8440: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.21 to 10.21.2 in /docs/_build
- #8441: @dependabot[bot] chore(deps): bump pygments from 2.19.2 to 2.20.0 in /docs/_build
- #8442: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.79.3 to 1.80.0 in /tests/apps/gogrpc
- #8410: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.48.0 to 0.49.0 in /plugins/common
- #8422: @dependabot[bot] chore(deps): bump github.com/fatih/color from 1.18.0 to 1.19.0 in /plugins/common
- #8434: @dependabot[bot] chore(deps): bump gunicorn from 25.2.0 to 25.3.0 in /tests/apps/python-flask
- #8439: @dependabot[bot] chore(deps): bump brace-expansion from 1.1.12 to 1.1.13 in /tests/apps/multi
- #8438: @dependabot[bot] chore(deps): bump path-to-regexp from 8.2.0 to 8.4.0 in /tests/apps/checks-root
- #8437: @dependabot[bot] chore(deps): bump gunicorn from 25.2.0 to 25.3.0 in /tests/apps/dockerfile-release
- #8436: @dependabot[bot] chore(deps): bump traefik from v3.6.11 to v3.6.12 in /plugins/traefik-vhosts
- #8435: @dependabot[bot] chore(deps): bump gunicorn from 25.2.0 to 25.3.0 in /tests/apps/multi
- #8427: @dependabot[bot] chore(deps): bump werkzeug from 3.1.6 to 3.1.7 in /tests/apps/python-flask
- #8428: @dependabot[bot] chore(deps): bump gunicorn from 25.1.0 to 25.2.0 in /tests/apps/multi
- #8429: @dependabot[bot] chore(deps): bump gunicorn from 25.1.0 to 25.2.0 in /tests/apps/python-flask
- #8430: @dependabot[bot] chore(deps): bump djangorestframework from 3.17.0 to 3.17.1 in /tests/apps/dockerfile-release
- #8431: @dependabot[bot] chore(deps): bump gunicorn from 25.1.0 to 25.2.0 in /tests/apps/dockerfile-release
- #8432: @dependabot[bot] chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /tests/apps/multi
- #8423: @dependabot[bot] chore(deps): bump traefik from v3.6.10 to v3.6.11 in /plugins/traefik-vhosts
- #8420: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.5 to 9.7.6 in /docs/_build
- #8421: @dependabot[bot] chore(deps): bump importlib-metadata from 8.8.0 to 9.0.0 in /docs/_build
- #8424: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.40 to 2.11.41 in /plugins/scheduler-k3s
- #8411: @dependabot[bot] chore(deps): bump lucaslorentz/caddy-docker-proxy from 2.11 to 2.12 in /plugins/caddy-vhosts
- #8412: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.20.0 to 3.20.1 in /plugins/scheduler-k3s
- #8419: @dependabot[bot] chore(deps): bump djangorestframework from 3.16.1 to 3.17.0 in /tests/apps/dockerfile-release
- #8418: @dependabot[bot] chore(deps): bump importlib-metadata from 8.7.1 to 8.8.0 in /docs/_build
- #8417: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.77.0-dev to 1.79.3 in /plugins/scheduler-k3s
- #8416: @dependabot[bot] chore(deps): bump ruby from 4.0.1 to 4.0.2 in /tests/apps/dockerfile-entrypoint
- #8415: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3 in /tests/apps/gogrpc
- #8409: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.22.4 to 0.22.5 in /plugins/scheduler-k3s
- #8408: @dependabot[bot] chore(deps): bump github.com/go-resty/resty/v2 from 2.17.1 to 2.17.2 in /plugins/scheduler-k3s
- #8407: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.4 to 9.7.5 in /docs/_build
- #8406: @dependabot[bot] chore(deps): bump timberio/vector from 0.53.0-debian to 0.54.0-debian in /plugins/logs
### Other
- #8468: @josegonzalez chore: bump dependencies in tests/apps/php
- #8467: @josegonzalez chore: upgrade traefik from v2.11.41 to v2.11.42
- #8466: @josegonzalez chore: bump dependencies in tests/apps/multi