Cron containers were never reaped once they exceeded their active deadline, so a hung cron task ran indefinitely instead of being retired after 24 hours as documented. `cron:run` now also accepts a `--ttl-seconds` argument, matching the one `dokku run` already takes.
# History
## 0.38.27
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.27/bootstrap.sh
sudo DOKKU_TAG=v0.38.27 bash bootstrap.sh
```
### Bug Fixes
- #8933: @josegonzalez Do not require a local image for k3s deploys
- #8930: @josegonzalez Do not import an already-migrated ENV file
- #8919: @josegonzalez Regenerate vector config on app lifecycle changes
- #8917: @josegonzalez Apply app-label-alias to shipped events
### New Features
- #8934: @josegonzalez Report traefik dns-provider env vars as global keys
- #8920: @josegonzalez Add storage directory mode and removal flags
- #8914: @josegonzalez Add vector-cron-sink for scheduled cron task output
### Tests
- #8931: @dependabot[bot] chore(deps): bump djangorestframework from 3.17.2 to 3.18.0 in /tests/apps/dockerfile-release
- #8927: @dependabot[bot] chore(deps): bump djangorestframework from 3.17.1 to 3.17.2 in /tests/apps/dockerfile-release
- #8923: @dependabot[bot] chore(deps): bump python from 3.15.0b4-bookworm to 3.15.0rc1-bookworm in /tests/apps/dockerfile-release
### Dependencies
- #8926: @dependabot[bot] chore(deps): bump github.com/gliderlabs/sigil from 0.12.0 to 0.12.1 in /plugins/nginx-vhosts
- #8925: @dependabot[bot] chore(deps): bump packaging from 26.2 to 26.3 in /docs/_build
- #8921: @dokku-bot chore: bump pack to 0.40.9
- #8924: @dependabot[bot] chore(deps): bump soupsieve from 2.9.1 to 2.9.2 in /docs/_build
- #8922: @dependabot[bot] chore(deps): bump python from 3.15.0b4-alpine to 3.15.0rc1-alpine in /docs/_build
- #8915: @dokku-bot chore: bump herokuish to 0.11.15
The dynamic `dns-provider-*` properties were reported as `--traefik-dns-provider-<env_var>`, outside the `global`/`computed` namespace every other traefik property uses, so a consumer reading the json report could not tell which of the two a key represented. They are now reported as `--traefik-global-dns-provider-<env_var>`. The `basic-auth-password` property is a credential as well and is now masked in the default report output on the same terms as the dns provider values, meaning the raw value is returned only for `--format json` or when the flag is queried by name.
Kubernetes pulls the app image itself, so a k3s host is free to reap its local copy while the workload keeps running, which the `registry` plugin already does on its own. Deploys, restarts, `dokku run`, and in-cluster cron no longer assert that the image is present locally, falling back to the metadata recorded in the app's current Helm release. A `ps:restart` naming a single process type now rolls only that process type's pods rather than silently redeploying every one. Apps with an `app.json` postdeploy task still require the image locally, as that task runs on the Dokku host.
The preserved copy holds everything the legacy file was not allowed to import, which includes keys that had been `config:unset` on purpose, so a revoked secret can outlive its revocation in a file `dokku config:*` no longer reads. Nothing said the copy was the operator's to remove once reviewed.
Releases 0.38.0 through 0.38.25 recorded the ENV file migration and deliberately left the file at the old path, so 0.38.26 treating a leftover file as a hand-edit replayed the environment as it stood at that upgrade over every `config:set` and `config:unset` made since, reinstating variables and secrets that had been deliberately unset. A file found at the old path once its migration is on record is no longer imported: it is removed when it agrees with the current config, and is otherwise moved aside to `ENV.migrated` with the keys it disagrees on named in a warning. That warning now reaches the operator during an upgrade rather than being swallowed, which is why the overwrite went unreported.
`storage:set` now takes `<name> <property> [<value>]` like every other `:set` command, where omitting the value unsets the property. Previously it took flags and could not distinguish an empty value from an omitted one, so nothing it set could ever be cleared. The flag form keeps working and emits a deprecation warning.
Annotations and labels move to `storage:annotations:set`, `storage:annotations:report`, `storage:labels:set`, and `storage:labels:report`, matching the `scheduler-k3s` equivalents. These operate on a single key, so clearing one leaves the rest in place rather than replacing the whole map as the `--annotation` and `--label` flags do.
`storage:create` and `storage:set` accept a `--mode` flag that sets the octal permissions of a docker-local host directory, and `storage:destroy` accepts a `--destroy-host-dir` flag that removes the directory along with its contents. A docker-local entry also honors `--reclaim-policy Delete` at destroy time now, matching how that policy governs a k3s PersistentVolume. Both are limited to the default `/var/lib/dokku/data/storage/<name>` location, the same restriction `--chown` already carries. `storage:set` applies `--chown` and `--mode` to the directory rather than only recording them.
The generated vector config is a snapshot of the app list and their sink properties, but it was only ever written by `logs:set` and `logs:vector-start`. Renaming an app left a source filtering on a label no container carries and gave the new name no source at all, so the app kept a sink with nothing feeding it. Cloning produced the same result for the clone, and destroying an app left its source and sink behind, the latter still pointing at an endpoint decommissioned along with the app. The global relabel transform embeds app names directly in generated VRL, so a rename also left behind a branch naming an app that no longer existed. Every case was silent, and the only repair was an operator running `logs:vector-start`. The `post-app-clone-setup`, `post-app-rename-setup` and `post-delete` triggers now rewrite the config, warning rather than failing so that a config write cannot abort the app operation whose state it is derived from.
Closes#8918.
The alias was only ever used to build the `include_labels` filter on the generated vector source, while dokku labels containers with `com.dokku.app-name` unconditionally. Setting the property therefore pointed the source at a label no container carries, and log collection stopped without any error. The source now always filters the label dokku applies, and a generated remap renames the field on its way to the sink, which is what the property was documented to do. An app whose own alias differs from the global one gets a branch in the global pipeline, so a per-app value is honored even when the app ships through the global sink.
Closes#8916.
The `app-label-alias` test left the global property set, so every later test in the file generated a vector source filtering on a label that dokku never applies to a container, silently collecting nothing. Clearing it in teardown restores log collection for the rest of the file. The cron routing test now asserts against console sinks rather than files, since the sink an event reached is identifiable from vector's own output without depending on a writable host mount, and its task sleeps either side of its output because a cron container that exits immediately is removed before vector can attach to it.
# History
## 0.38.26
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.26/bootstrap.sh
sudo DOKKU_TAG=v0.38.26 bash bootstrap.sh
```
### Bug Fixes
- #8906: @josegonzalez Match docker options by shell word when removing
### New Features
- #8911: @josegonzalez Route wildcard domains through traefik on k3s
- #8909: @josegonzalez Support manually managed cert issuers on k3s
- #8903: @josegonzalez Support kernel sysctls on the k3s scheduler
- #8856: @youdie006 Add pre-parsed port_mappings to ports:report json
### Refactors
- #8863: @josegonzalez Move host-crontab generation into cron plugin
### Documentation
- #8908: @josegonzalez Document --global on scheduler-k3s report and set
- #8858: @bakatz Added instructions for restoring backups on different CPU architectures.
### Tests
- #8893: @dependabot[bot] chore(deps): bump django from 5.2.16 to 5.2.17 in /tests/apps/dockerfile-release
- #8891: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 293 to 294 in /tests/apps/php
- #8877: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0 in /tests/apps/gogrpc
- #8874: @dependabot[bot] chore(deps): bump sass from 1.101.7 to 1.102.0 in /tests/apps/multi
- #8870: @dependabot[bot] chore(deps): bump sass from 1.101.6 to 1.101.7 in /tests/apps/multi
- #8866: @dependabot[bot] chore(deps): bump sass from 1.101.3 to 1.101.6 in /tests/apps/multi
- #8860: @dependabot[bot] chore(deps): bump setuptools from 78.1.1 to 83.0.0 in /tests/apps/dockerfile-release
- #8859: @dependabot[bot] chore(deps): bump immutable from 5.1.5 to 5.1.9 in /tests/apps/multi
- #8855: @dependabot[bot] chore(deps): bump sass from 1.101.0 to 1.101.3 in /tests/apps/multi
- #8857: @dependabot[bot] chore(deps): bump body-parser from 2.2.1 to 2.3.0 in /tests/apps/checks-root
- #8853: @dependabot[bot] chore(deps): bump python from 3.15.0b3-bookworm to 3.15.0b4-bookworm in /tests/apps/dockerfile-release
### Dependencies
- #8905: @dependabot[bot] chore(deps): bump oras.land/oras-go/v2 from 2.6.1 to 2.6.2 in /plugins/scheduler-k3s
- #8869: @dependabot[bot] chore(deps): bump github.com/mattn/go-isatty from 0.0.23 to 0.0.24 in /plugins/app-json
- #8887: @dependabot[bot] chore(deps): bump github.com/kedacore/keda/v2 from 2.20.1 to 2.20.2 in /plugins/scheduler-k3s
- #8883: @dokku-bot chore: bump docker-container-healthchecker to 0.16.0
- #8886: @dependabot[bot] chore(deps): update markdown requirement from <3.11,>=3.10.2 to >=3.10.3,<3.11 in /docs/_build
- #8892: @dependabot[bot] chore(deps): bump traefik from v3.7.9 to v3.7.10 in /plugins/traefik-vhosts
- #8885: @dokku-bot chore: bump dokku-update to 0.10.0
- #8884: @dokku-bot chore: bump procfile-util to 0.20.8
- #8882: @dokku-bot chore: bump docker-image-labeler to 0.10.0
- #8888: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.53 to 2.11.54 in /plugins/scheduler-k3s
- #8900: @dokku-bot chore: bump gliderlabs-sigil to 0.12.1
- #8899: @dokku-bot chore: bump herokuish to 0.11.14
- #8898: @dokku-bot chore: bump netrc to 0.11.1
- #8897: @dokku-bot chore: bump dokku-event-listener to 0.20.1
- #8896: @dokku-bot chore: bump sshcommand to 0.20.2
- #8895: @dokku-bot chore: bump lambda-builder to 0.9.4
- #8894: @dokku-bot chore: bump plugn to 0.17.1
- #8876: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.21.0 to 1.21.1 in /plugins/scheduler-k3s
- #8873: @dependabot[bot] chore(deps): bump traefik from v3.7.8 to v3.7.9 in /plugins/traefik-vhosts
- #8872: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.52 to 2.11.53 in /plugins/scheduler-k3s
- #8871: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.36.2 to 1.36.3 in /plugins/scheduler-k3s
- #8868: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.36.2 to 0.36.3 in /plugins/scheduler-k3s
- #8867: @dependabot[bot] chore(deps): bump k8s.io/client-go from 0.36.2 to 0.36.3 in /plugins/scheduler-k3s
- #8865: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.38.0 to 1.39.0 in /plugins/scheduler-k3s
- #8864: @dependabot[bot] chore(deps): bump soupsieve from 2.9 to 2.9.1 in /docs/_build
- #8854: @dependabot[bot] chore(deps): bump python from 3.15.0b3-alpine to 3.15.0b4-alpine in /docs/_build
- #8852: @dependabot[bot] chore(deps): bump soupsieve from 2.8.4 to 2.9 in /docs/_build
- #8851: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.6 to 9.7.7 in /docs/_build
- #8850: @dependabot[bot] chore(deps): bump actions/setup-python from 6 to 7
### Other
- #8907: @josegonzalez fix: migrate env files before reading deprecated vars
- #8881: @josegonzalez Ignore minor and patch updates for github actions
Scheduled cron task output previously reached only the `dokku` user's cron mail, and could not be redirected because `app.json` rejects bare shell operators in a cron `command`. Setting `vector-cron-sink` on an app or globally routes that output to a dedicated sink instead, on both the `docker-local` and `k3s` schedulers, which keeps log destinations under operator control rather than in a deployed repository. Cron events carry `dokku_app` and `dokku_cron_id` fields so a sink can give each task its own destination. This also fixes a `k3s` bug where configuring a global `vector-sink` silently removed the vector prometheus exporter sink.
Traefik matches hosts exactly, so an app serving a wildcard domain under the `traefik` ingress class had a valid certificate but silently 404d on every request. Wildcard domains now render as a `HostRegexp` rule that matches a single label, the same semantics as a Kubernetes wildcard host, so both ingress classes behave the same. Those routes carry an explicit low priority so an exact domain on any app still wins over another app's wildcard, mirroring ingress-nginx.
The `cert-issuer-name` and `cert-issuer-kind` properties point an app's generated `Certificate` at a cert-manager issuer created outside of Dokku, allowing certificates to be issued through solvers the built-in letsencrypt integration cannot use, such as `dns01` for wildcard certificates. Setting an issuer enables https on its own, as a manually managed issuer has no email for Dokku to configure. An imported certificate still takes precedence, and `letsencrypt-server false` remains the single off switch. Dokku warns before a build starts when the referenced issuer is absent from the cluster, without blocking the deploy. Wildcard domains no longer collide with their apex domain when generating ingress names, and `letsencrypt-server` values are now validated when set rather than at deploy time.
The usage strings for `scheduler-k3s:report` and `scheduler-k3s:set` omitted the `--global` option, which is the only way to reach the scheduler-wide report since a bare `scheduler-k3s:report` iterates every app, and `:report` also omitted `--format stdout|json`. The command listing in the k3s documentation is resynced with the help output, which additionally restores flags that had been dropped from `scheduler-k3s:cluster:add`, `scheduler-k3s:cluster:list`, and `scheduler-k3s:initialize`.
The hand-written marker file was created as root, which the config-migrate-env
trigger could not overwrite when it ran under a different user. Draining once up
front records the migration through the same code path the assertion exercises.
Install steps run in alphabetical order of the enabled plugin directory, so `apps`, `builder`, and `checks` read an app's environment before the `config` plugin had moved the `ENV` file to its new location. The read came back empty, so their deprecated `DOKKU_*` variables were never migrated to the matching plugin property and were never unset, with nothing reported either way: `dokku config:show` kept listing the variable while the plugin behaved as though it were unset. The relocation now runs before any deprecated variable is read, whatever the install order, and each old file is removed as soon as it has been drained rather than on a later install, which also covers the global file that was never removed at all. A file that reappears at the old path can only have been written by hand, so it is merged in with a warning naming its keys instead of being discarded.
Options drained out of the pre-0.38.0 `DOCKER_OPTIONS_<PHASE>` files were copied verbatim rather than re-serialized the way `docker-options:add` stores them, so `docker-options:remove` compared the canonical string it builds against a stored value that could never match it and exited successfully without removing anything. Removal now matches stored options by shell word, and stored options are rewritten into the canonical form once on upgrade, which additionally splits an entry that carried several flags on a single line into one entry per flag so a single flag can be removed and so the readers that match on a flag prefix see one value per entry. The leftover `.migrated` sentinel drain is restored to running ahead of the global short-circuit that had made it unreachable, and the plugin's Go tests are added to the test target that had never run them.
Sysctls the kernel does not namespace, such as `vm.max_map_count`, cannot be set from a pod spec and previously had no answer beyond editing `/etc/sysctl.d` on each host by hand. `scheduler-k3s:node-sysctls:set` now applies them through a privileged daemonset, which reaches nodes joined later and reapplies after a reboot. Sysctls may be scoped to a node profile, with a profile scope inheriting the global values and overriding them on conflict so that every node is covered by exactly one daemonset. Clearing a sysctl stops dokku managing it but does not restore the previous value, which persists until the node reboots.
The `docker-local` scheduler supports `--sysctl` for free because docker options are passed verbatim to `docker run`, but the k3s scheduler silently dropped it. Namespaced sysctls now render into the pod's `securityContext.sysctls` for deployments, cron jobs, and one-off runs. A sysctl the kernel does not namespace fails the deploy instead of being dropped, since it cannot take effect within a pod regardless of what was requested.
Node profiles controlled how a node joined the cluster but left no trace on the node afterwards, so a profile could not be selected against with `kubectl`, a `nodeSelector`, or a node affinity rule. Nodes joined without a profile are left unlabeled, and the server node created by `scheduler-k3s:initialize` never carries the label since it does not pass through `scheduler-k3s:cluster:add`.
The server node created by `scheduler-k3s:initialize` had no way to receive kubelet arguments, unlike nodes joined through `scheduler-k3s:cluster:add` or configured via `scheduler-k3s:profiles:add`. This meant settings such as `allowed-unsafe-sysctls` were unreachable on a single-node install.
Host-crontab generation for `app.json` cron tasks now lives in the `cron` plugin, gated by a new `scheduler-uses-host-cron` trigger that the `docker-local` scheduler answers true while self-managed schedulers such as `k3s` answer false. This lets any host-cron scheduler participate in normal `app.json` cron without coupling to `scheduler-docker-local` or duplicating the crontab writer, while the `k3s` scheduler continues to manage its own in-cluster cron jobs.
Closes#8862.
The `issuer.yaml` chart template dereferenced `.Values.global.issuer.enabled` without guarding against the value being absent, which yaml serialization omitted for apps without a per-app email, causing a nil-pointer render error that broke every k3s web deploy.
The `letsencrypt-email-prod` and `letsencrypt-email-stag` properties can now be set per app in addition to globally, resolving app-level before the global value for the app's selected `letsencrypt-server`. An app that sets its own email renders a namespaced cert-manager `Issuer` using that email, while apps without an override continue to use the shared `ClusterIssuer` with the global email.
Values supplied through docker options, `--ttl-seconds`, and `-e` flowed into a Bash `eval` during build, deploy, and run, letting a low-privileged user execute arbitrary commands on the host as the dokku user. These arguments are now tokenized and passed through to the container verbatim, without shell expansion. A one-time migration repairs stored labels whose backticks were saved with a stray backslash so Traefik-style rules stay valid on the next deploy.
# History
## 0.38.24
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.24/bootstrap.sh
sudo DOKKU_TAG=v0.38.24 bash bootstrap.sh
```
### Documentation
- #8836: @josegonzalez Link herokuish buildpack references to buildpack management page
### Tests
- #8841: @dependabot[bot] chore(deps): bump ruby from 4.0.5 to 4.0.6 in /tests/apps/dockerfile-entrypoint
- #8843: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.82.0 to 1.82.1 in /tests/apps/gogrpc
### Dependencies
- #8845: @dependabot[bot] chore(deps): bump github.com/mattn/go-isatty from 0.0.22 to 0.0.23 in /plugins/app-json
- #8844: @dependabot[bot] chore(deps): bump github.com/melbahja/goph from 1.5.1 to 1.5.2 in /plugins/common
- #8842: @dependabot[bot] chore(deps): bump timberio/vector from 0.56.0-debian to 0.57.0-debian in /plugins/logs
- #8838: @dokku-bot chore: bump pack to 0.40.8
- #8846: @dependabot[bot] chore(deps): bump traefik from v3.7.7 to v3.7.8 in /plugins/traefik-vhosts
- #8839: @dependabot[bot] chore(deps): bump actions/setup-node from 6 to 7
- #8834: @dokku-bot chore: bump dokku-event-listener to 0.20.0
The Herokuish Buildpacks doc linked buildpack topics to anchors on the process management page that do not exist, so those links resolved to the wrong page. Point them at the corresponding sections of the buildpack management page and add that page to the sidebar so it is reachable.
# History
## 0.38.23
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.23/bootstrap.sh
sudo DOKKU_TAG=v0.38.23 bash bootstrap.sh
```
### Bug Fixes
- #8833: @josegonzalez Parse cert CN and subject on OpenSSL 3.x
### Tests
- #8825: @dependabot[bot] chore(deps): bump golang from 1.26.4 to 1.26.5 in /tests/apps/zombies-dockerfile-no-tini
- #8823: @dependabot[bot] chore(deps): bump golang from 1.26.4 to 1.26.5 in /tests/apps/zombies-dockerfile-tini
- #8820: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 292 to 293 in /tests/apps/php
- #8821: @dependabot[bot] chore(deps): bump golang from 1.26.4 to 1.26.5 in /tests/apps/go-fail-predeploy
- #8822: @dependabot[bot] chore(deps): bump golang from 1.26.4 to 1.26.5 in /tests/apps/gogrpc
- #8824: @dependabot[bot] chore(deps): bump golang from 1.26.4 to 1.26.5 in /tests/apps/go-fail-postdeploy
### Dependencies
- #8831: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.21.2 to 3.21.3 in /plugins/scheduler-k3s
- #8830: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.37.0 to 1.38.0 in /plugins/scheduler-k3s
- #8826: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.53.0 to 0.54.0 in /plugins/common
- #8827: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.20.3 to 1.21.0 in /plugins/scheduler-k3s
- #8828: @dependabot[bot] chore(deps): bump traefik from v3.7.6 to v3.7.7 in /plugins/traefik-vhosts
- #8829: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.24.0 to 1.0.0 in /plugins/scheduler-k3s
The `certs` plugin extracted a certificate's Common Name and formatted its subject using string assumptions that only held for pre-3.x OpenSSL output, so a certificate with only a Common Name and no Subject Alternative Name reported no hostnames from `certs:report` and was not recognized during nginx config generation, while the subject report retained the `subject=` prefix and used the wrong separators. Normalizing the subject with `-nameopt` before parsing makes the extraction version independent across OpenSSL and LibreSSL.
# History
## 0.38.22
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.22/bootstrap.sh
sudo DOKKU_TAG=v0.38.22 bash bootstrap.sh
```
### New Features
- #8805: @RichardDorian Allow custom values for chown
- #8810: @josegonzalez Expose whether a network was created by dokku
- #8807: @josegonzalez Allow replacing buildpack list atomically
- #8808: @josegonzalez Expose docker-options as structured lists in JSON report
- #8806: @josegonzalez Expose scheduler-k3s autoscaling-auth state for read-back
- #8801: @josegonzalez Add --format json support to plugin:list
### Refactors
- #8804: @josegonzalez Port bash :report subcommands to golang
### Documentation
- #8809: @josegonzalez Document nginx validate-config load_module override
### Tests
- #8803: @dependabot[bot] chore(deps): bump django from 5.2.15 to 5.2.16 in /tests/apps/dockerfile-release
### Dependencies
- #8816: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.21.0 to 0.22.0 in /plugins/common
- #8818: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.51 to 2.11.52 in /plugins/scheduler-k3s
- #8817: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.21.0 to 0.22.0 in /plugins/scheduler-docker-local
- #8819: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.21.0 to 0.22.0 in /plugins/scheduler-k3s
`network:list` and `network:info` now expose a `DokkuManaged` boolean derived from the `com.dokku.network-name` label that `network:create` applies, and `network:list` gains a `--dokku-managed` flag to restrict output to dokku-created networks. This lets tooling distinguish networks dokku created from Docker built-ins and networks created by other tooling such as compose.
The nginx deploy-time pre-validation runs `nginx -t` against a minimal wrapper that omits the global `load_module` directives, so a custom `nginx.conf.sigil` using a directive from a dynamically loaded module fails validation even though it is valid against the running server. Document overriding the `validate-config` template through the `nginx-app-template-source` trigger as the supported workaround.
Pin DOKKU_SYSTEM_USER and DOKKU_SYSTEM_GROUP to the current process user in test setup so PropertyListWrite succeeds in CI Docker where the dokku group does not exist.
Add parallel -list keys to docker-options:report --format json so export
tools can round-trip options without splitting space-joined strings.
Closes#8799
Add buildpacks:set --replace so callers can replace an app's complete ordered buildpack list in one command while preserving existing single-buildpack and --index behavior.
Closes#8802
Align autoscaling-auth:report with annotations and labels reporting so export tools can recover configured trigger auth via flat JSON keys and info flags, while stdout stays secret-safe unless --include-metadata is used.
Closes#8800
With every bash :report subcommand now ported to golang, the shared fn-report-parse-args, fn-report-emit-json, fn-report-filter-global and fn-report-validate-format helpers are no longer referenced and are removed.
The bash :report implementation for the nginx-vhosts plugin is replaced with a compiled golang binary that reuses the plugin's existing golang property getters, so every raw, global and computed key is unchanged while collection runs in parallel and json is marshalled directly. The global report keeps its existing behaviour of surfacing only the global keys.
The bash :report implementation for the scheduler-docker-local plugin is replaced with a compiled golang binary. The plugin already shipped golang code, so the report subcommand is added alongside its existing triggers binary, and the init-process and parallel-schedule-count helpers remain in bash for the deploy pipeline.
The bash :report implementation for the git plugin is replaced with a compiled golang binary. Property, computed and global keys are collected in parallel, while the sha and last-updated-at keys still shell out to git and stat the deploy branch ref so their values are unchanged. The non-report git helpers such as fn-git-cmd and the computed deploy-branch and keep-git-dir getters remain in place for the build pipeline.
The bash :report implementation for the certs plugin is replaced with a compiled golang binary. The certificate inspection getters run openssl and reproduce the existing field extraction, so the ssl report keys are unchanged, while collection now happens in parallel and json is marshalled directly. The now-unused fn-ssl-* display helpers are dropped, and fn-certs-set and fn-certs-remove remain for certs:add and certs:remove.
The bash :report implementations for the checks and domains plugins are replaced with a compiled golang binary that collects report keys in parallel and marshals json directly. The domains global report header now matches the shared renderer used by every other golang report, and its bats assertion is updated accordingly.
The bash :report implementations for the caddy, haproxy, openresty, and traefik proxy plugins are replaced with a compiled golang binary that collects report keys in parallel and marshals json directly. The traefik dns-provider values keep their masking behaviour, remaining hidden in the default stdout report while surfacing for --format json or an explicit flag query. These four plugins previously had no unit tests, so a bats suite covering the report matrix is added for each.
The bash :report implementations for the dockerfile, herokuish, lambda, nixpacks, pack, and railpack builders are replaced with a compiled golang binary that collects report keys in parallel and marshals json directly, avoiding the per-key subshell and jq forks that made the bash reports slow. The subcommands/report and root report trigger become symlinks to the compiled binary, while the non-report bash helpers each plugin still relies on are left in place.
Adds a `--format json` flag to `plugin:list` whose output includes each plugin's install source - for git-based third-party plugins, the git remote URL, the checked-out commit, and the followed branch - so the set of installed plugins can be reconstructed elsewhere.
Closes#8798.
# History
## 0.38.21
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.21/bootstrap.sh
sudo DOKKU_TAG=v0.38.21 bash bootstrap.sh
```
### New Features
- #8795: @josegonzalez Add --format json support to apps:list
### Tests
- #8788: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.81.1 to 1.82.0 in /tests/apps/gogrpc
- #8787: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.51.0 to 0.55.0 in /tests/apps/gogrpc
### Dependencies
- #8781: @dependabot[bot] chore(deps): bump lucaslorentz/caddy-docker-proxy from 2.12 to 2.13 in /plugins/caddy-vhosts
- #8794: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.36.0 to 1.37.0 in /plugins/scheduler-k3s
- #8789: @dependabot[bot] chore(deps): bump pymdown-extensions from 11.0 to 11.0.1 in /docs/_build
- #8782: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.23.2 to 0.24.0 in /plugins/scheduler-k3s
- #8785: @dependabot[bot] chore(deps): bump traefik from v3.7.5 to v3.7.6 in /plugins/traefik-vhosts
- #8786: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.31.0 to 1.36.0 in /plugins/scheduler-k3s
- #8783: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.50 to 2.11.51 in /plugins/scheduler-k3s
- #8780: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.20.2 to 1.20.3 in /plugins/scheduler-k3s
- #8779: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.23.1 to 0.23.2 in /plugins/scheduler-k3s
### Other
- #8796: @josegonzalez Add --format json support to ps:scale
The `ps:scale` command now accepts a `--format` flag that defaults to `stdout` and can be set to `json` to emit the current formation as a JSON array of process type and quantity objects, matching the JSON output the `:report` subcommands already provide. The flag only applies when displaying the current formation; it is ignored when process types are supplied for scaling. When no scale has been set for the app, the JSON output is an empty array.
The `apps:list` command now accepts a `--format` flag that defaults to `stdout` and can be set to `json` to emit the app names as a JSON array, matching the JSON output the `:report` subcommands already provide. When no apps exist, the JSON output is an empty array.
# History
## 0.38.20
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.20/bootstrap.sh
sudo DOKKU_TAG=v0.38.20 bash bootstrap.sh
```
### Tests
- #8773: @dependabot[bot] chore(deps): bump python from 3.15.0b2-bookworm to 3.15.0b3-bookworm in /tests/apps/dockerfile-release
- #8756: @dependabot[bot] chore(deps): bump sass from 1.100.0 to 1.101.0 in /tests/apps/multi
- #8753: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 291 to 292 in /tests/apps/php
### Dependencies
- #8766: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.21.1 to 3.21.2 in /plugins/scheduler-k3s
- #8777: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.41.0 to 1.42.1 in /plugins/common
- #8778: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 6.1.0 to 6.1.1 in /plugins/haproxy-vhosts
- #8748: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.52.0 to 0.53.0 in /plugins/common
- #8745: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.20.0 to 0.21.0 in /plugins/common
- #8774: @dependabot[bot] chore(deps): bump python from 3.15.0b2-alpine to 3.15.0b3-alpine in /docs/_build
- #8769: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.21.3 to 11.0 in /docs/_build
- #8775: @dependabot[bot] chore(deps): bump click from 8.4.1 to 8.4.2 in /docs/_build
- #8776: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 6.0.1 to 6.1.0 in /plugins/haproxy-vhosts
- #8772: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.42.0 to 1.42.1 in /plugins/buildpacks
- #8770: @dokku-bot chore: bump pack to 0.40.7
- #8767: @dependabot[bot] chore(deps): bump github.com/containerd/containerd from 1.7.32 to 1.7.33 in /plugins/scheduler-k3s
- #8765: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.41.0 to 1.42.0 in /plugins/scheduler-k3s
- #8764: @dependabot[bot] chore(deps): bump actions/checkout from 6 to 7
- #8762: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.36.1 to 1.36.2 in /plugins/scheduler-k3s
- #8758: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.41.0 to 1.42.0 in /plugins/buildpacks
- #8760: @dependabot[bot] chore(deps): bump k8s.io/apimachinery from 0.36.1 to 0.36.2 in /plugins/scheduler-k3s
- #8757: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.21.0 to 3.21.1 in /plugins/scheduler-k3s
- #8755: @dependabot[bot] chore(deps): bump traefik from v3.7.4 to v3.7.5 in /plugins/traefik-vhosts
- #8754: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.49 to 2.11.50 in /plugins/scheduler-k3s
- #8749: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.47 to 2.11.49 in /plugins/scheduler-k3s
- #8743: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.14.3 to 4.15.0 in /docs/_build
- #8744: @dependabot[bot] chore(deps): bump traefik from v3.7.3 to v3.7.4 in /plugins/traefik-vhosts
- #8747: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.20.0 to 0.21.0 in /plugins/scheduler-k3s
- #8746: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.20.0 to 0.21.0 in /plugins/scheduler-docker-local
The `helm.sh/helm/v3` v3.21.2 bump pulled `client-go` up to `v0.36.2`, which is incompatible with the pinned `controller-runtime v0.22.4`. Moving `controller-runtime` to `v0.24.1` (the first release targeting `client-go v0.36`) requires KEDA `v2.20.1`, allowing the old version pin to be removed.
# History
## 0.38.18
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.18/bootstrap.sh
sudo DOKKU_TAG=v0.38.18 bash bootstrap.sh
```
### Tests
- #8734: @dependabot[bot] chore(deps): bump golang from 1.26.3 to 1.26.4 in /tests/apps/gogrpc
- #8731: @dependabot[bot] chore(deps): bump golang from 1.26.3 to 1.26.4 in /tests/apps/go-fail-predeploy
- #8733: @dependabot[bot] chore(deps): bump golang from 1.26.3 to 1.26.4 in /tests/apps/zombies-dockerfile-tini
- #8735: @dependabot[bot] chore(deps): bump golang from 1.26.3 to 1.26.4 in /tests/apps/go-fail-postdeploy
- #8736: @dependabot[bot] chore(deps): bump golang from 1.26.3 to 1.26.4 in /tests/apps/zombies-dockerfile-no-tini
- #8738: @dependabot[bot] chore(deps): bump python from 3.15.0b1-bookworm to 3.15.0b2-bookworm in /tests/apps/dockerfile-release
- #8730: @dependabot[bot] chore(deps): bump django from 5.2.14 to 5.2.15 in /tests/apps/dockerfile-release
### Dependencies
- #8727: @dependabot[bot] chore(deps): bump github.com/melbahja/goph from 1.5.0 to 1.5.1 in /plugins/common
- #8739: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.46 to 2.11.47 in /plugins/scheduler-k3s
- #8737: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.12.0 to 0.12.1 in /plugins/openresty-vhosts
- #8732: @dependabot[bot] chore(deps): bump python from 3.15.0b1-alpine to 3.15.0b2-alpine in /docs/_build
- #8740: @dependabot[bot] chore(deps): bump timberio/vector from 0.55.0-debian to 0.56.0-debian in /plugins/logs
- #8741: @dependabot[bot] chore(deps): bump traefik from v3.7.1 to v3.7.3 in /plugins/traefik-vhosts
For an undeployed app, the additive diff covers every chart resource, so
the literal 'has been added' header appears once per resource - six times
in the python test app's chart. `assert_output_contains` defaults to
exact-count 1, which fails. Pass -1 (at least 1) to match the actual
semantics of the test.
`common.GetDeployingAppImageName` runs `VerifyImage` and errors out when
no image has been built for the app. A freshly-created app has no image
yet, so the preview could never render for never-deployed apps. Add an
`AllowMissingImage` flag to `BuildOptions` that lets BuildAppChart
substitute a placeholder image string in that case; CommandPreview sets
it. The deploy path still passes `BuildOptions{}`, so missing-image
remains a hard error there.
Without this, the preview build invented a fresh timestamp for
`Values.global.deployment_id` and the resulting diff showed every
Deployment changing its `app.kubernetes.io/version` annotation - even when
nothing semantically changed. CommandPreview now reads the deployment id
out of `release.Chart.Metadata.Version` and passes it through a new
`BuildOptions.OverrideDeploymentID` parameter so the previewed manifests
carry the same version label as the live release. The deploy path still
generates a fresh timestamp.
The previous commit added the dispatcher case but missed appending
`subcommands/preview` to the plugin's `SUBCOMMANDS` list, so no symlink
was created at install time and dokku reported the command as unknown.
Users can override the default 3-line surrounding context per change. Pass
`--context -1` to render the full resource around every change, matching
upstream `helm diff upgrade` behavior.
Adds a `scheduler-k3s:preview <app>` command that renders a unified diff
between the manifests currently stored in the live Helm release for an app
and the manifests that the next deploy would roll out. The diff is produced
entirely via the Helm Go SDK that scheduler-k3s already uses, with no
external `helm` binary or `helm-diff` plugin install required. The
underlying diff and parse logic is vendored from `databus23/helm-diff`
(Apache 2.0) into a new internal package, trimmed of three-way-merge,
release-ownership tracking, and the non-default output formatters.
The chart-construction half of `TriggerSchedulerDeploy` has been extracted
into a reusable `BuildAppChart` helper so deploy and preview share the
same chart materialization without duplicating template logic. Secret
values are redacted by default in preview output; `--show-secrets` and
`--show-secrets-decoded` flags match the upstream `helm diff` UX. Only the
main app helm release is compared in this iteration; auxiliary releases
for config vars, image-pull secrets, and TLS certificates are out of scope
and documented as such.
`common.TouchFile` opened files with `O_TRUNC`, so the call from `common.SshTask.Execute` against `~/.ssh/known_hosts` emptied the dokku user's previously trusted host keys before `goph.DefaultKnownHosts()` read them. Running `scheduler-k3s:cluster:add` without `--insecure-allow-unknown-hosts` then failed with `knownhosts: key is unknown` and left a zero-byte `known_hosts`. The function now matches `touch(1)` semantics: create the file if missing, otherwise leave its contents intact.
Kubernetes 1.20 deprecated the node-role.kubernetes.io/master label and replaced it with node-role.kubernetes.io/control-plane, and 1.24 dropped the legacy label entirely. The scheduler-k3s:cluster:add join path still filtered control-plane nodes with master=true, so on any k3s release built from Kubernetes 1.24+ the lookup matched zero nodes and aborted with "no nodes found in the cluster" before the worker could join.
Annotation and label values containing a newline previously round-tripped
as two adjacent `key: value` lines, and the second line then failed the
`SplitN(line, ": ", 2)` parse on read. Move the per-`(processType,
resourceType)` files to `PropertyMap*` storage so `\n` in values and `/`
in keys are preserved verbatim. An idempotent `TriggerInstall` migration
walks `--global` and every app, converting any legacy line-formatted file
in place by probing `PropertyMapGet` first and rewriting via
`PropertyListGet` only when the probe fails. Property names are
unchanged, so the annotations/labels report scanner and the
`reservedAnnotationPrefixes` filter keep working without modification.
Closes#8719.
PropertyMap tests went through SetPermissions, which looks up the `dokku` user/group; the fresh `golang:1.26.2` container used by `go-test-plugin-in-docker` has neither, so the chown failed with `unknown group dokku`. Override `DOKKU_SYSTEM_USER` and `DOKKU_SYSTEM_GROUP` to `root` in the property and chart-migration test setups so the chown targets an identity that exists everywhere. The config tests also called `plugn trigger post-config-update` without `PLUGIN_CORE_AVAILABLE_PATH` set, so the hook tried to source `/common/functions` and logged a noisy warning on every test; point the env var at the canonical `/var/lib/dokku/core-plugins/available` location.
Chart property names containing `/` failed because per-key flat-file storage interpreted the slash as a filesystem path separator, and any move to line-based storage would silently truncate multi-line values. A new `PropertyMap*` helper family in `common` persists each map as a single JSON file so both `/` in keys and `\n` in values round-trip losslessly. Chart overrides move to `chart-overrides.<chart>` and an idempotent `TriggerInstall` migration rewrites any legacy `chart.<chart>.<key>` files into the new layout. The deprecated `scheduler-k3s:set --global chart.*` form is rerouted through the same map storage so it does not silently orphan writes. Closes#8717.
The scheduler-k3s plugin exposes `annotations:set` and `labels:set` but no matching report subcommands, so scripts could not inspect the configured state for idempotent management without reading the property files directly. The new `scheduler-k3s:annotations:report` and `scheduler-k3s:labels:report` surface the configured entries with stdout, JSON, single-flag query, and `--process-type` / `--resource-type` filtering, mirroring the recently added `scheduler-k3s:charts:report`. The literal `GlobalProcessType` value `--global` is rendered as `global` in report keys to avoid leading dashes. The `scheduler-k3s:autoscaling-auth:report` command is updated alongside to loop over every app when no app and no `--global` flag is provided, matching the convention used by `scheduler-k3s:report`.
Helm chart overrides on the scheduler-k3s plugin were previously set
through the generic `scheduler-k3s:set --global chart.<chart>.<property>`
interface, which mixed chart-level configuration into the same command
that manages scheduler properties and offered no focused way to inspect
which overrides were configured. A dedicated `scheduler-k3s:charts:set`
sets and clears chart-specific helm values, and a complementary
`scheduler-k3s:charts:report` surfaces configured overrides per chart
with optional JSON output and single-field flag queries. The legacy form
on `scheduler-k3s:set` continues to work but now emits a deprecation
warning pointing users at the new subcommand.
storage:report gains a flat dotted key per attachment field (entry-name, host-path, container-path, phases, process-type, subpath, readonly, volume-options, volume-chown) under the --storage-attachment.<index>.<field> shape. Both stdout and JSON pick the keys up through the existing common.ReportSingleApp pipeline. Attachments that reference a missing storage entry emit a warning and are skipped, so the rest of the report still renders. Closes#8710.
Re-running `storage:mount <app> <entry> --container-dir <path>` against an existing `(entry, container_dir, process_type)` tuple now updates the attachment's mount-time fields in place instead of erroring with `already mounted`. Declarative tooling that wants to change `--volume-options`, `--volume-chown`, `--phase`, `--volume-subpath`, or `--volume-readonly` on an existing mount no longer has to unmount-then-remount, which briefly dropped the volume from `storage:report` and raced against any deploy that fired in the window. The legacy `host:container[:opts]` form keeps its strict `Mount path already exists.` failure.
The `storage:list <app> --format json` payload conflated the
attachment's `Readonly` flag and its `VolumeOptions` field into a
single derived `volume_options` string that rendered as `ro`,
`<options>`, or `ro,<options>` depending on which fields were set on
the underlying attachment. That shape is fine for the legacy
`host:container[:options]` text view but it leaves drift-detection
tooling unable to tell whether a `ro` token came from
`Attachment.Readonly == true` or from the operator setting
`Attachment.VolumeOptions = "ro"` directly. The JSON now exposes
`readonly` (boolean) and `volume_options` (string) as separate
omitempty keys populated straight from the attachment, and
`formatStorageListEntry` combines them at format time for the colon-
form text view. `ParseMountPath` was extended in lockstep so callers
of the legacy `host:container:opts` form no longer have to special-
case the `ro` token themselves.
The named-entry form of `storage:mount` had no way to set the attachment's `volume_options`, even though the legacy `host:container:opts` colon form parses options into the same field and every downstream consumer (the docker-args trigger and the storage:list/storage:report display path) already renders them. Tooling that declaratively re-applies attachments silently dropped options on every re-apply.
The apps plugin accepted `apps:set --global deploy-source` and
`apps:set --global deploy-source-metadata` even though nothing reads
those properties globally, accepted `apps:set <app> disable-autocreation`
even though only the global form is consulted by `maybeCreateApp`, and
never emitted `disable-autocreation` in `apps:report` for either scope.
Drop the global `deploy-source*` writes from `GlobalProperties`, reject
per-app `disable-autocreation` writes at the plugin level, and surface
`--app-global-disable-autocreation` in both the per-app and `--global`
reports so the property the runtime actually reads is round-trippable.
storage:create --chown invoked chown-storage-dir with the full host path, but the helper validates a basename and prepends the storage root itself, so every call failed with `Directory can only contain the following set of characters`. Pass the entry name and reject the combination of --chown with a non-default host path, since the helper only manages the default storage location.
# History
## 0.38.10
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.10/bootstrap.sh
sudo DOKKU_TAG=v0.38.10 bash bootstrap.sh
```
### New Features
- #8702: @josegonzalez Prompt for confirmation on storage:destroy
### Tests
- #8698: @dependabot[bot] chore(deps-dev): bump org.apache.maven.plugins:maven-dependency-plugin from 3.10.0 to 3.11.0 in /tests/apps/java
`storage:destroy` now prompts for confirmation before removing a named storage entry, matching the behavior of other destructive commands such as `apps:destroy` and `network:destroy`. The prompt can be skipped with the `--force` flag or the global `dokku --force` flag for non-interactive callers.
Emitting the restart policy as a `--restart` argument from a `docker-args-process-deploy` trigger exposed a latent gluing bug: proxy and builder triggers concatenated `$STDIN$output` with no separator, and the scheduler and builders appended `docker-args-process-*` output directly onto the older `docker-args-*` output, so adjacent arguments could merge into values like `--restart=on-failure:10--label`. A space is now inserted at both the trigger echo and the concatenation so arguments always stay separated.
`dokku ps:set <app> restart-policy` with no value erroneously returned `Invalid restart-policy specified` instead of unsetting the property like every other ps property. The restart policy is now managed as a normal app and global property surfaced through the `--ps-restart-policy`, `--ps-global-restart-policy`, and `--ps-computed-restart-policy` report flags, with the effective value applied at deploy time and existing values migrated on install. Because it is no longer stored as a Docker option it no longer appears in `docker-options:report`, and `--ps-restart-policy` now reports the raw value with the `on-failure:10` default available via `--ps-computed-restart-policy`.
Exposes raw, global, and computed report flags for every openresty per-app property and allows those properties to be set with `--global`, so external tooling can distinguish a property that was never set from one left at its built-in default. The computed value resolves the per-app value first, then the global value, then the default. Also corrects `client-header-timeout` which read the `client-body-timeout` key and sets the computed `client-max-body-size` default to `1m`.
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.
`dokku network:set --global bind-all-interfaces` (no value) wrote the literal string `false` to the property file instead of unsetting it, so external tooling could not distinguish "explicitly set to default" from "not set". Drop the empty-to-`false` coercion in `CommandSet` so the empty-value path reaches `PropertyDelete` like every other property, and remove the unconditional `TriggerPostCreate` write so new apps consult the global value before falling back to the `"false"` computed default.
Adds the missing raw/global/computed report keys for ten settable properties across the ps, builder, scheduler, proxy, openresty, nginx, and scheduler-k3s plugins so external tooling can verify drift through `:report --format json`. The scheduler-k3s `token` is masked as `*******` in default stdout output and only unmasked when the report is requested via `--format json` or when the flag is queried explicitly by name; the same explicit-query unmasking rule is extended to the existing traefik `dns-provider-<env_var>` keys.
The registry plugin accepted `registry:set <app> image-repo-template <value>` and persisted the per-app file, but only ever read the global value when rendering the image repository, so per-app overrides were silently dropped. The property now follows the same per-app to global to default fallback chain used by `push-on-release` and `server`, and `registry:report` exposes the raw per-app value alongside the existing global and computed flags. The `push-extra-tags` report flags were extended for the same reason: the runtime already honored per-app and global values, but the report only surfaced the raw per-app entry.
# History
## 0.38.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.7/bootstrap.sh
sudo DOKKU_TAG=v0.38.7 bash bootstrap.sh
```
### Security
- #8672: @josegonzalez Prevent host shell injection from app.json cron commands
### Bug Fixes
- #8669: @josegonzalez Recover deployed image from registry on local miss
- #8679: @josegonzalez Align ps/cron :report --global keys with plugin convention
- #8678: @josegonzalez Split openresty report keys into global and computed pairs
- #8676: @immanuwell Use SYSTEM for shfmt Darwin detection
### New Features
- #8677: @josegonzalez Warn on deprecated listen http2 in custom nginx templates
### Tests
- #8683: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 290 to 291 in /tests/apps/php
- #8671: @josegonzalez Qualify scheduler-k3s ingressroute kubectl lookups
### Dependencies
- #8682: @dependabot[bot] chore(deps): bump k8s.io/apimachinery from 0.36.0 to 0.36.1 in /plugins/scheduler-k3s
- #8681: @dependabot[bot] chore(deps): bump soupsieve from 2.8.3 to 2.8.4 in /docs/_build
### Other
- #8680: @josegonzalez Split more report global keys into raw and computed
The longest `ps:report` flag is now `--ps-computed-stop-timeout-seconds` (34 chars), which pushes the per-plugin stdout column width past the 31-char floor used by `common.ReportSingleApp`. The `(report) report` test's literal-string assertion for `Deployed:` needs three extra spaces to match the new alignment.
The `ps` and `cron` plugins emitted `:report --format json` keys that
skipped the `<plugin>-` prefix or `-global-` infix used by every other
plugin, forcing external consumers to special-case those names. Rename
the affected report flags so they match the `<plugin>-global-<property>`
and `<plugin>-computed-<property>` convention introduced in 0.38.0, and
add the previously missing `computed-` siblings to both the per-app and
`--global` reports so the shape lines up with caddy, haproxy, and
traefik.
Reverts the earlier triggerRestart change. Forwarding the numeric tag forces
release_and_deploy to look up `dokku/<app>:N` (the bare local name), which
was never tagged when image-repo overrides the default. `fn-verify-app-image`
then retag-after-pulls and the underlying image ID ends up with two tags,
which prevents scheduler-docker-local's image retire path from removing the
old numeric tag (it uses unforced `docker image remove`).
When `image-repo` is overridden, the registry plugin pushes under that name and
the bare local `dokku/<app>:N` tag is never created. `fn-verify-app-image` now
queries the `deployed-app-image-repo` trigger and pulls `${REMOTE_REPO}${DEPLOYED_REPO}:${TAG}`,
retagging it as the local bare reference so subsequent inspects resolve. Also
aligns the `storage:ensure-directory` deprecation test assertion with the
standardized `Deprecated:` prefix.
Adds an app-aware `fn-verify-app-image` helper that pulls the deployed image
from the configured registry when it is missing locally, gated on
push-on-release being enabled, honoring per-app `registry:login` credentials.
Every in-tree `verify_image` caller migrates to the wrapper and the bare
helper is marked deprecated. `config:set` now forwards the deployed image tag
to `release-and-deploy` so the release path no longer pins recovery on the
unrecoverable `:latest` tag.
Three plugins still leaked the built-in default through `<plugin>-global-<property>` after the broader raw/computed split in #8640. External tooling reading `:report --format json` for drift detection could not distinguish "set to default" from "never set" - after a `:set --global` followed by an unset, the JSON still reported the default value. The `<plugin>-global-<property>` keys now hold the raw stored value (empty when nothing has been set) and `<plugin>-computed-<property>` keys hold the effective value with per-app, global, and built-in default fallback. Every global property now has a computed sibling for shape consistency, including those whose default is empty. Internal callers in `scheduler-k3s` that previously read the default-applied global helpers now consume new `getComputed*` helpers, keeping deploy-time behavior unchanged.
The `openresty:report --format json` payload emitted bare property names for the four global-only properties (`image`, `letsencrypt-email`, `letsencrypt-server`, `allowed-letsencrypt-domains-func-base64`), while `hsts` already used the `global-`/`computed-` convention adopted by the other proxy plugins. External tooling consuming the report had to maintain a per-property naming map within a single plugin. The global flag map now emits `--openresty-global-<X>` (raw stored value, empty when unset) and `--openresty-computed-<X>` (effective value with the built-in default applied) for those four properties plus `hsts`, and the per-app map gains the same pair for the global-only properties. The compose template and the two non-report callers consume the `computed-` accessors so the runtime behavior is unchanged.
nginx 1.25.1 deprecated the `listen ... http2` parameter in favor of a standalone `http2 on;` directive. Apps that ship a custom `nginx.conf.sigil` forked from an old default still hardcode `listen ... ssl http2;` and trigger `nginx: [warn]` lines from `nginx -t`. Surface a deprecation warning during `nginx_build_config` whenever the active template is app- or plugin-supplied and still contains the deprecated parameter, matching the existing warnings for `DOKKU_APP_LISTENERS`, `NGINX_SSL_PORT`, and `NGINX_PORT`, and point users at the `HTTP2_DIRECTIVE_SUPPORTED` variable already used by the default template.
The docker-local scheduler wrote each app.json cron command verbatim into the dokku user's crontab, where cron's `bash -c` interpreted any shell metacharacters in the command on the host as the dokku user rather than inside the container. The crontab line is now `dokku cron:run <app> <cron-id>`, and the command is resolved from app.json and exec'd inside the container at run time. Commands containing shell operators are also rejected when app.json is validated at deploy time.
The Traefik 26.0.0 chart registers CRDs under both `traefik.containo.us` and `traefik.io`, so a bare `kubectl get ingressroute` resolves against the legacy group where no resources exist and returns NotFound. Querying `ingressroutes.traefik.io` targets the group Dokku's chart actually writes to.
# History
## 0.38.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.6/bootstrap.sh
sudo DOKKU_TAG=v0.38.6 bash bootstrap.sh
```
### Bug Fixes
- #8633: @Mordred Correctly redirect http traffic to https when using scheduler-k3s
- #8665: @josegonzalez Clarify byte-preserving behavior of config:set --encoded
- #8666: @josegonzalez Depend on cron | cron-daemon to allow alternatives
- #8638: @josegonzalez Support --global on cron:set
### Refactors
- #8668: @josegonzalez Hash scheduler-k3s cron-id label to fit Kubernetes' 63-byte cap
- #8664: @josegonzalez Convert filesystem migration markers to plugin properties
### Documentation
- #8645: @zenspider Removed outdated warning about dokku-update not being able to upgrade to specific versions.
### Tests
- #8667: @josegonzalez Rename logs:report vector key test and guard old keys
- #8662: @dependabot[bot] chore(deps): bump qs from 6.15.0 to 6.15.2 in /tests/apps/checks-root
- #8661: @dependabot[bot] chore(deps): bump sass from 1.99.0 to 1.100.0 in /tests/apps/multi
- #8658: @dependabot[bot] chore(deps-dev): bump heroku/heroku-buildpack-php from 288 to 290 in /tests/apps/php
- #8657: @dependabot[bot] chore(deps): bump slim/slim from 4.15.1 to 4.15.2 in /tests/apps/php
- #8654: @dependabot[bot] chore(deps): bump ruby from 4.0.4 to 4.0.5 in /tests/apps/dockerfile-entrypoint
- #8642: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.81.0 to 1.81.1 in /tests/apps/gogrpc
### Dependencies
- #8652: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.40.0 to 1.41.0 in /plugins/common
- #8663: @dokku-bot chore: bump herokuish to 0.11.13
- #8646: @dokku-bot chore: bump pack to 0.40.6
- #8659: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.51.0 to 0.52.0 in /plugins/common
- #8660: @dependabot[bot] chore(deps): bump click from 8.4.0 to 8.4.1 in /docs/_build
- #8655: @dependabot[bot] chore(deps): bump github.com/containerd/containerd from 1.7.30 to 1.7.32 in /plugins/scheduler-k3s
- #8651: @dependabot[bot] chore(deps): bump click from 8.3.3 to 8.4.0 in /docs/_build
- #8649: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.40.0 to 1.41.0 in /plugins/buildpacks
- #8650: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.40.0 to 1.41.0 in /plugins/config
- #8648: @dependabot[bot] chore(deps): bump zipp from 3.23.1 to 4.1.0 in /docs/_build
- #8644: @dokku-bot chore: bump pack to 0.40.5
- #8641: @dependabot[bot] chore(deps): bump traefik from v3.7.0 to v3.7.1 in /plugins/traefik-vhosts
- #8634: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.21.2 to 10.21.3 in /docs/_build
### Other
- #8640: @josegonzalez Split report global keys into raw and computed
The `dokku.com/cron-id` label could exceed Kubernetes' 63-byte cap because the cron ID is `base36(appName === command === schedule)`, which expands roughly 1.5x per byte. The label is now keyed `dokku.com/cron-hash` and holds the `sha1` hex digest of the cron-id, a fixed 40-character value that always fits the cap. The same hex digest is mirrored into the `dokku.com/cron-hash` annotation, and the original base36 cron-id stays in the `dokku.com/cron-id` annotation that `cron:list` reads when surfacing user-facing IDs. Per-task lookups stay server-side via label selectors, so `cron:set --maintenance` and the forbid/replace concurrency checks on `dokku run --cron-id` keep working without any in-memory filtering.
Adds four Go template tests for ingress-route.yaml covering the imported-cert secret name, multiple domains per IngressRoute, the non-traefik ingress_class guard, and the https port_map dedup when an http port_map already covers the same container port. Also adds a bats integration test that deploys a TLS-enabled app under traefik and asserts both IngressRoute manifests and live http-to-https redirect plus https serving.
The canonical encode pipeline `echo "value" | base64` silently appends `\n` to the value, which round-trips through base64 and ends up stored in the env. Document that decoded values are stored byte-for-byte, recommend `printf '%s'` or `echo -n` for short inline values, and show `cat | base64 -w 0` for files. Adds a bats test asserting all four encoding patterns produce the expected stored bytes.
Closes#8647.
The asymmetric --logs-vector-global-image and --logs-vector-global-networks flags were renamed to --logs-global-vector-image and --logs-global-vector-networks in #8640 so they match the standard `--<plugin>-global-<property>` shape used by every other report. The bats description string at tests/unit/logs.bats:533 was still pinned to the old asymmetric phrasing, and there was no assertion that the deprecated JSON keys had actually been removed. Updates the test description to match its assertions and adds a regression guard that fails if logs-vector-global-image or logs-vector-global-networks ever reappear in the --global JSON report. Closes#8632.
The bare `cron` dependency caused `apt` to remove `dokku` whenever a user installed an alternative cron daemon such as `systemd-cron`. Listing the virtual `cron-daemon` package as an alternative keeps the default install behaviour (fresh installs still pull in `cron`) while letting any provider of `cron-daemon` satisfy the dependency, so swapping cron daemons no longer takes `dokku` with it.
The docker-options DOCKER_OPTIONS_<PHASE>.migrated sentinels and the storage data/storage-registry/migrations/<app> flag files are now stored as per-app properties (`migrated-<phase>` and `legacy-mounts-migrated` respectively), so they survive a property-store backup/restore and align with the existing `migrated-from-files`, `env-migrated`, and `nginx-conf-sigil-migrated` patterns. The new markers are written only when a non-empty legacy source was actually migrated, distinguishing apps that never had legacy state from apps that did and were drained. A one-cycle upgrade-cycle conversion drains any leftover filesystem sentinels into the new properties and removes the files; for docker-options the conversion deliberately runs before the global `migrated-from-files` short-circuit so installs upgrading from the previous release still get their `.migrated` files converted.
Renames the existing `## Internal properties` umbrella section to `## Properties` across all plugin docs and adds a new `### Settable properties` subsection enumerating every property accepted by each plugin's `:set` command. Each row lists scope, default, the actual `:report` flag shapes that surface the value, and a one-line description. The buildpacks plugin is included even though it uses `:set-property`, with a note in the subsection clarifying the legacy command name. Property lists, scopes, and report flags were verified against plugin source and the live dokku binary.
After the report rename made --logs-global-vector-image return the raw
stored value (empty when unset) and split --logs-computed-vector-image
out as the default-resolved key, the (logs:report)
vector-global-image and vector-global-networks raw test still pinned
assert_output_exists on the raw key in the unset state. The raw key is
correctly empty after dokku logs:set --global vector-image runs, and
the bundled vector image default is exposed via the computed key now.
The internal-properties tables on builds.md (8 --build-* flags),
ssl.md (8 --ssl-* flags), and process-management.md (4 ps flags) each
crammed all the flags into a single comma-separated table row with one
umbrella description. Splits each into a row per flag with a specific
description and the actual code-path source (the build record write
path, the openssl x509 parse target, the ps inspection helper).
The previous commit renamed --logs-vector-global-image and
--logs-vector-global-networks to --logs-global-vector-image and
--logs-global-vector-networks, and added --logs-computed-vector-image,
--logs-computed-vector-networks, and --logs-computed-vector-sink. The
logs.bats per-app Invalid-flag listing was still pinned to the old
10-flag set and the vector-global JSON keys and CLI flags still used
the old names, so the (logs) logs:report app, (logs:report)
vector-global-image and vector-global-networks raw, and (logs)
logs:set --global vector-networks tests failed - the latter cascaded
because the failing assertion ran before its vector-image cleanup.
Updates the per-app Invalid-flag string to the 13-flag sorted listing,
renames every stale jq key and CLI flag reference, adds a parallel
(logs) logs:report --global invalid flag test covering the 10-flag
global-scope listing, and adds dokku logs:set --global vector-image
to teardown so a future failing test doesn't leak the property.
Addresses review feedback on #8640. fn-archive-max-size,
fn-archive-max-files, fn-git-deploy-branch, and fn-git-keep-git-dir are
renamed with `computed` in the function name so the names match the
resolved-with-default semantic they implement, and every caller is
updated in lockstep. logs:report renames the misordered
--logs-vector-global-image and --logs-vector-global-networks to
--logs-global-vector-image and --logs-global-vector-networks, makes the
global getters return the raw stored value, and adds
--logs-computed-vector-image, --logs-computed-vector-networks, and
--logs-computed-vector-sink. network:report --global gains the
computed-* keys for attach-post-create, attach-post-deploy,
initial-network, and tld so external tooling can read the resolved
value at global scope. The --quiet flag is dropped from every
:report --format json | jq invocation across the PR's bats files; the
report's --format json output is the only stdout and the flag is
redundant.
The nginx-property binary's globalValue() switch returned ComputedX for
client-body-timeout, client-header-timeout, keepalive-timeout, and
lingering-timeout, leaking the per-app value into nginx:report's
global-<prop> key. Other properties in the same switch already call
GlobalX. Aligns the four with the rest. Also tightens
tests/unit/nginx-vhosts_properties.bats so the helper preserves values
containing whitespace or literal \$ across the inner /bin/bash -c, and
switches proxy-keepalive to integer values since the set subcommand
validates it via is_number.
Fixes CI failures from the prior commit's bats additions.
storage report mounts are prefixed with `-v `, logs.bats setup does not
auto-create the test app, the nginx-vhosts shell report emits JSON keys
without the `nginx-` plugin prefix, registry computed-image-repo falls
back to the default `dokku/<app>` repo name when no template is set,
cron computed-maintenance follows OR-not-override semantics so a per-app
`false` does not override a global `true`, the scheduler subcommand
help string is `Manage scheduler settings`, and bringing ps procfile-path
into the #8640 raw convention required updating the pre-existing
`(ps:set) procfile` assertion. Also extends fn-git-keep-git-dir to fall
back through the global property before the built-in default so global
keep-git-dir actually takes effect at deploy time.
The bats coverage for plugin :report keys has been uneven since the raw/global/computed split landed in PR #8640. This commit adds a single combined triplet test per settable property across app-json, builder, builder-dockerfile, builder-herokuish, builder-lambda, builder-nixpacks, builder-pack, builder-railpack, buildpacks, cron (maintenance), git (keep-git-dir, rev-env-var, source-image), logs (vector-sink, vector-global-image, vector-global-networks), network (attach-post-create, attach-post-deploy, initial-network), proxy (per-app type), ps (stop-timeout-seconds), registry (image-repo, push-on-release, push-extra-tags), storage (build/deploy/run mounts), and adds a new tests/unit/scheduler.bats and tests/unit/nginx-vhosts_properties.bats. Brings ps `procfile-path` and `stop-timeout-seconds` global getters in line with the #8640 convention (raw global, default resolved in computed). Documents the read-only and internal properties that surface in `:report` (or are written by Dokku) but cannot be managed by `:set` in a new `## Internal properties` section appended to each affected plugin's docs page.
The caddy and haproxy bats suites referenced `refute_output`, which is not provided by the in-tree test_helper, so the steps failed with `command not found`. The traefik `api-entry-point property` test and the logs `logs:set global` test still queried the removed bare `--traefik-api-entry-point` flag and the pre-split `--logs-global-max-size` default respectively. The assertions now use `assert_output_exists`, the `--traefik-computed-` flag, and the raw/computed key pair for `logs:set --global max-size`.
The `<plugin>-global-<property>` keys in `:report` output returned the resolved value with the built-in default substituted in, so external tooling could not distinguish a property that had been set globally to the default from one that had never been set. The bare keys for caddy, haproxy, and traefik global-only properties had the same shape. The `global-<property>` keys now hold the raw stored value and are empty when nothing has been set, and a new `computed-<property>` key holds the effective value used at runtime, falling back through the per-app value (where one exists), the global value, and the built-in default. The bare global-only keys for the three proxy plugins are removed in favor of the raw/computed pair. Closes#8631.
`cron:set --global` wrote the property but emitted `unknown flag: --global` because the post-set `scheduler-cron-write` trigger received `--global` as the appName arg, which pflag rejected before reaching the trigger body.
The trigger args now omit appName for global writes, and the `scheduler-k3s` cron-write trigger short-circuits when called without an app since per-app reconciliation requires a real app name. The docker-local trigger already regenerates the global crontab from all apps so global `mailfrom`/`mailto` are picked up without any further changes.
The Docker daemon refuses any endpoint settings on the default bridge network and `docker compose` unconditionally attaches the service name as an alias on every joined network, so combining bridge with user-defined networks via compose's `networks:` block is impossible. When `vector-networks` is set, the compose template now joins only the configured networks; outbound to external sinks still works through user-defined network NAT. Additionally, `vector-image` and `vector-networks` are both global-only but `common.CommandPropertySet` silently accepts them at app level by merging global-only keys into the valid-property set, so both now reject explicitly in `validateSetValue`.
The dokku entrypoint already exports DOKKU_ROOT, PLUGIN_PATH, PLUGIN_AVAILABLE_PATH, PLUGIN_ENABLED_PATH, PLUGIN_CORE_AVAILABLE_PATH and DOKKU_LIB_ROOT before invoking plugn. Delegating to `dokku plugin:trigger` keeps the helper at env-var parity with the production trigger path without enumerating every var the helper must forward.
Triggers that call verify_app_name or otherwise reference $DOKKU_ROOT fail under bats because the helper did not forward DOKKU_ROOT to the plugn subshell. The production dokku entrypoint exports DOKKU_ROOT before invoking plugn, so bring the helper to env-var parity.
Adds a new global `vector-networks` property on the logs plugin that takes a comma-separated list of Docker networks. When set, the rendered compose file declares each network plus `bridge` as external and joins them on the vector service, so `docker compose up` reconciles attachments on every `logs:vector-start`. When unset, the existing `network_mode: bridge` template is preserved unchanged. The value is validated against `docker network inspect` at set time, rejects the reserved `bridge` entry, and is surfaced in `dokku logs:report` via `--logs-vector-global-networks`.
The dokku entrypoint exports both vars before invoking plugn, so triggers that source `$PLUGIN_AVAILABLE_PATH/...` work in production. The helper only forwarded PLUGIN_PATH / PLUGIN_CORE_AVAILABLE_PATH / DOKKU_LIB_ROOT, so triggers that follow the same pattern fail under bats.
The new certs-set / certs-remove tests called plugn directly via /bin/bash -c, which exits with 'PLUGIN_PATH is not set in environment' under the bats runner. Route the calls through the existing run_plugn_trigger helper so the required PLUGIN_PATH / PLUGIN_CORE_AVAILABLE_PATH / DOKKU_LIB_ROOT vars are set.
The ports plugin's `post-certs-update` trigger was rewriting every `https:443:*` mapping from the app's `http:80:*` mappings, silently overwriting any user-defined mapping such as `https:443:443` used by apps that terminate TLS inside the container. The trigger now skips the rewrite when an `https:443:*` mapping already exists, keeping the default behavior only when the app has no explicit HTTPS mapping configured.
Closes#8619.
The bare `tls-internal` key previously returned the computed value, so external tooling could not tell whether the property had been set on the app or was merely defaulting to `false`. The property is now also configurable with `--global`, the report exposes `computed-tls-internal` and `global-tls-internal` keys alongside the bare raw key, and the deploy path honors the per-app value with a fallback to the global value before the built-in default. Closes#8625.
Adds `certs-set` and `certs-remove` plugin triggers so other plugins can install or remove an app's SSL cert/key pair without shelling out to the `dokku certs:add` / `dokku certs:remove` subcommands. Shared implementations live as `fn-certs-set` and `fn-certs-remove` in `plugins/certs/internal-functions`, with the subcommands and the new triggers calling `verify_app_name` before delegating.
# History
## 0.38.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.4/bootstrap.sh
sudo DOKKU_TAG=v0.38.4 bash bootstrap.sh
```
### Bug Fixes
- #8615: @josegonzalez Reject per-app sets for openresty global-only properties
- #8613: @josegonzalez Expose raw deploy-branch and keep-git-dir in git:report
- #8549: @josegonzalez Route CNB images through launcher on scheduler-k3s
### New Features
- #8614: @josegonzalez Split scheduler-docker-local report into raw, computed, and global
### Documentation
- #8603: @cheif Add `dokku-http-oauth` to community plugins
### Tests
- #8618: @josegonzalez Isolate scheduler-k3s registry tags per bats file
- #8616: @josegonzalez Migrate from junit_files to files in EnricoMi/publish-unit-test-result-action
- #8617: @josegonzalez Upgrade actions in shared build-image compose action
- #8609: @josegonzalez Skip packer lint job on dependabot PRs
- #8604: @dependabot[bot] chore(deps): bump python from 3.14.3-bookworm to 3.15.0b1-bookworm in /tests/apps/dockerfile-release
### Dependencies
- #8606: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.50.0 to 0.51.0 in /plugins/common
- #8608: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.45 to 2.11.46 in /plugins/scheduler-k3s
- #8607: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.10.0 to 0.11.0 in /plugins/openresty-vhosts
- #8605: @dependabot[bot] chore(deps): bump python from 3.14.3-alpine to 3.15.0b1-alpine in /docs/_build
Parallel `unit.scheduler-k3s-*` matrix jobs all pushed to the same `savant/rdmtestapp:1` tag on Docker Hub, so a herokuish run pod could pull a CNB or dockerfile image that another job had just overwritten and fail with `exec: "/exec": stat /exec: no such file or directory`. The image-repo-template now embeds the bats file basename so each job owns its own tag namespace.
`openresty:set <app>` previously accepted per-app writes for properties whose readers only consult the global store, so `:set myapp image foo` printed a success message while `:report myapp` kept showing the global default. The per-app form is now rejected with `The key '<key>' can only be set globally`, matching the behavior introduced for `caddy`, `haproxy`, and `traefik` in #8602.
The bare `init-process` and `parallel-schedule-count` keys previously returned the computed value, so external tooling could not tell whether a property had been set on the app or was merely defaulting. Both properties are now also configurable with `--global`, the report exposes `computed-*` and `global-*` keys alongside the bare raw keys, and the deploy path honors the global value before falling back to the linuxserver.io vendor heuristic.
The bare `deploy-branch` and `keep-git-dir` keys in `git:report` returned the computed (effective) value rather than the raw per-app value, with no separate `computed-*` key to distinguish "set per-app" from "falling back to global or default". This left external tooling unable to detect a per-app unset without out-of-band state. The bare keys now hold the raw per-app value (empty when unset) and new `computed-deploy-branch` and `computed-keep-git-dir` keys hold the effective value, matching the convention used by `nginx-vhosts`, `network`, and `builder`. Closes#8610.
Dependabot PRs don't receive `secrets.DIGITALOCEAN_TOKEN`, so the `packer validate` step fails on every dependency bump. Guarding the job by PR author skips it cleanly while keeping it active for human PRs and pushes to `master`.
The cron-id label could exceed Kubernetes' 63-byte cap when commands or
schedules were long, and an all-digit job-suffix or cron-id rendered as
an unquoted YAML scalar caused the API server to reject manifests. Run
pods built from dockerfiles also occasionally hit the 10s startup wait
on a cold image pull, even though the pod was scheduled correctly.
The cron-id is now stored as an annotation and a shorter hash is used as
the selector label. Every interpolated annotation and label value in the
cron-job and deployment templates is now quoted to prevent numeric
coercion, and the run-pod wait timeout is raised to 30 seconds.
Extends bats coverage for the scheduler-k3s scheduler so that
herokuish and dockerfile builders match the cnb test surface for
`dokku run`, `dokku run:detached`, `dokku cron:run`, deployment
manifests, cronjob manifests, and Procfile-key resolution. Adds
the corresponding `app-cron-procfile.json` fixture for the python
app and `app-cron.json` / `app-cron-procfile.json` fixtures for
the dockerfile-procfile app.
After streaming logs from a run pod on scheduler-k3s, the apiserver may still report `PodRunning` for a short window due to kubelet status propagation lag, causing `dokku run` to fail with `Unable to attach as the pod is in an unknown state: Running`. Wait briefly for the pod to reach a terminal phase before classifying the outcome.
For short-lived commands the run pod can transition Running to Succeeded
between the running-pod check and the kubectl exec SPDY upgrade, leaving
the upgrade to fail with `container not found`. When stdout is not a TTY
(and DOKKU_FORCE_TTY is not set) the exec attach is only being used to
capture stdout, so stream the run pod logs in follow mode instead. The
pod's `TTLSecondsAfterFinished` of 60s keeps the kubelet's log file
readable for the duration of the call, eliminating the race.
Drop the assertion that the web deployment has no command since the python buildpack auto-emits a web Procfile entry, which correctly routes through launcher just like docker-local. Shorten the cron command fixture so the base36-encoded cron-id stays under the 63-byte kubernetes label limit, and relax the `dokku run` and `dokku cron:run` output assertions to `assert_output_contains` so they tolerate the leading blank line emitted on k3s.
Mirror the docker-local fix in #8525 for the k3s scheduler. CNB images default to a `/cnb/process/web` entrypoint that ignores incoming args, so non-web deployments, scheduled cron jobs, and ad-hoc `dokku run` / `cron:run` commands all need an explicit `launcher` entrypoint. The deployment and cron-job helm templates now set `command: [launcher]` when `image.type` is `pack`, and `TriggerSchedulerRun` sets the entrypoint to `launcher` for pack images while finishing the previously stubbed Procfile lookup branch so the resolved command is actually scheduled.
Pre-seeds the `dokku/install_default_site` debconf answer to `true` so the dokku postinst installs `/etc/nginx/conf.d/00-default-vhost.conf` during image build. Without this, debconf returned an empty value in non-interactive docker builds, the postinst's `setup-default-site` short-circuited, and nginx had no listener on port 80 - which left the readiness sentinel untouched and the container stuck unhealthy.
`caddy:set`, `haproxy:set`, and `traefik:set` previously accepted per-app writes for properties that only have a single host-wide reader, so `:set myapp image foo:bar` printed a success message while `:report myapp` kept showing the global default. The per-app form is now rejected with `The key '<key>' can only be set globally`, matching the existing rejection used for haproxy `refresh-conf` and traefik `challenge-mode`. Caddy `tls-internal` remains the only legitimate per-app property in this family.
The property name set via `app-json:set` is `appjson-path`, but the matching read-back flags on `app-json:report` were named `--app-json-selected`, `--app-json-global-selected`, and `--app-json-computed-selected`. The mismatch meant `dokku app-json:report <app> --app-json-appjson-path` (the form already documented in deployment-tasks.md) was rejected as an invalid flag, and the `--format json` output advertised keys that did not correspond to any settable property. The flags and JSON keys are renamed to `--app-json-appjson-path`, `--app-json-global-appjson-path`, and `--app-json-computed-appjson-path` so that the property name round-trips through set and report.
The `value_exists` variable in the report info-flag loop is no longer read after the `not deployed` failure was removed, and was already unused in domains, haproxy-vhosts, traefik-vhosts, caddy-vhosts, and openresty-vhosts. Drop the declaration and the trailing assignment so the loop reads cleanly across all plugins.
Several plugin `:report` subcommands erroneously failed with `not deployed` when an info-flag matched a property that was empty. Empty values are legitimate for configuration properties pre-deploy and the `--format json` path already returns them without error. Remove the `value_exists` check across nginx, checks, git, certs, scheduler-docker-local, and the builder-* plugins so the info-flag form behaves consistently with the JSON form.
Adds a bats lint test that guards the static wiring (nginx conf, dokku-restore finish-script ordering, my_init sentinel reset, and the Dockerfile HEALTHCHECK line) plus a docker smoke test that boots the built image, waits for the health flip, exercises the loopback endpoint, asserts the port is not published to the host, and verifies the negative path. The smoke test is invoked via a new `make test-image-healthcheck` target and runs automatically in the build-image action after `docker buildx --load`.
The official dokku/dokku image gains a HEALTHCHECK directive backed by a loopback-only HTTP endpoint at `127.0.0.1:18080/_dokku/health`. The endpoint reports 200 once first-boot bootstrap finishes, sshd and nginx are accepting connections, and `dokku ps:restore` completes; otherwise it returns 503. Changes are scoped to the Docker overlay and Dockerfile so debian-package installs are unaffected.
The shipped catch-all default site uses `ssl_reject_handshake`, which is unsupported on nginx older than 1.19.4 and causes nginx to fail to start on Debian Bullseye. The postinst now detects the installed nginx version and installs an HTTP-only variant of the catch-all on older systems.
The security fix that quoted `$APP` inside the pre-receive hook heredoc changed the literal hook contents from `dokku git-hook foo` to `dokku git-hook "foo"`, so the existing substring assertions no longer match.
The bash and go validators previously each kept their own copy of the regex, which had to be updated in lockstep. Both bash wrappers now invoke the existing common binary via the same pattern as `verify_app_name`, leaving go as the single source of truth. The legacy `IsValidAppNameOld` rule is also widened to allow underscores again so apps created under the old naming rules can still be looked up through `VerifyAppName`'s either-rule fallback.
The previous app name validation regex permitted shell metacharacters such as `;`, `$`, backticks, `|`, and `&`. These names were embedded unquoted into the generated git pre-receive hook script, allowing an authenticated user to execute arbitrary commands as the dokku user simply by pushing to a remote with a crafted app name. App names are now restricted to lowercase alphanumerics, dots, and hyphens, and the hook script also quotes the app variable as a defense-in-depth measure.
Bats runs tests under `set -eo pipefail`, so when `grep -F -o` finds nothing inside the count pipe it exits 1, the whole pipe fails, errexit fires, and the function aborts before reaching the count comparison. Wrap grep in `{ ... || true; }` so the pipe stays zero when the pattern is absent and the helper falls through to the flunk message.
Replaces the `DOKKU_ARCHIVE_MAX_SIZE` and `DOKKU_ARCHIVE_MAX_FILES` environment variables with global git properties (`archive-max-size` and `archive-max-files`), configurable via `dokku git:set --global` and surfaced through `dokku git:report --global`. Defaults remain `1073741824` bytes and `10000` entries.
Archives passed to git:from-archive and certs:add were extracted without symlink or path validation, allowing a crafted archive to write arbitrary files anywhere writable by the dokku user via symlink traversal. Extraction now pre-scans entries for absolute paths, parent traversal, and unsafe symlinks, applies the GNU tar `--no-unsafe-links` flag when available, and validates symlinks after extraction.
The previous use of `touch` before `netrc set` allowed the file to inherit the umask and be world-readable, exposing stored git credentials to local users. The set and unset paths now explicitly chmod 0600 and chown to the dokku user, and the plugin install hook repairs permissions on already-affected installations.
Add defense-in-depth sanitization for OpenResty include files to prevent
OS command injection via malicious filenames that break shell quoting in eval.
- Add filename validation in core-post-extract using regex [^a-zA-Z0-9_.-]
- Validate both http-includes and location-includes paths
- Abort deploy via dokku_log_fail on unsafe filenames
- Skip non-regular files (symlinks, directories) during extraction
- Add security regression test with unsafe filename containing space
- Keep existing guards in docker-args-process-deploy as belt-and-suspenders
- Update documentation to clarify allowed filename characters
Addresses CVSS 9.9 vulnerability where filenames like poc'$(cmd)'x.conf
could escape shell quoting and execute arbitrary commands during deploy.
Replace the bash pattern-substitution loop with grep -F -o piped to wc -l so the helper counts literal substring occurrences instead of treating the expected value as a glob pattern. The old implementation interpreted `[`, `]`, `*`, `?`, and `\` as pattern syntax, which made `assert_output_contains "['task.py', 'test']"` report 17 matches against an output that contained the string exactly once - the inner characters were being matched as a character class. assert_output_not_contains delegates to assert_output_contains and is fixed transitively.
The previous form set `trap "rm -rf '$TMP_DIR'" RETURN` inside the test, but bats propagates `RETURN` traps to nested function calls, so the trap fired on the first `assert_success` and removed the work directory before the trigger script ran. Switching to bats's per-test `BATS_TEST_TMPDIR` removes the trap entirely and lets bats handle cleanup.
Both helpers wrap `run /bin/bash -c "..."` with the env vars dokku plugin scripts and `plugn` need, replacing the long inline boilerplate that was duplicated across `tests/unit/resource_3.bats` and the new `core-post-extract` regression tests in the builder bats files.
The builder-dockerfile, builder-lambda, builder-nixpacks, builder-pack and builder-railpack `core-post-extract` triggers assigned `$2` to a local `SOURCECODE_WORK_DIR` but called `pushd "$TMP_WORK_DIR"`, which was unset. Bash 5.2 silently accepted `pushd ""`, so the bug stayed dormant. Bash 5.3 (shipped with Ubuntu 26.04) makes it a hard error and `set -e` aborts the trigger, causing every `git push` to fail with `pushd: null directory`.
The release_and_deploy function and several proxy plugin scripts call fn-plugin-property-* helpers without sourcing `plugins/common/property-functions`, producing `command not found` errors during deploys. Source the helpers from `plugins/common/functions` and from each proxy plugin entry point that consumes them.
The ppa:cncf-buildpacks/pack-cli launchpad source is currently down, breaking the runtime image build and any bats run that calls install_pack. Pack is now tracked in contrib/dependencies.json and pulled from the buildpacks/pack GitHub release tarball, matching how other binary deps are managed. update-deb-dependencies gains hyphen-aware word-boundary matching so single-word names like pack cannot accidentally rewrite unrelated debian/control lines, keeping pack out of the package's hard requirements.
`SaveEntry` and `touchMigrationFlag` wrote files via `os.WriteFile` and `os.Create` and never chowned them, so the install-time legacy-mount migration produced root-owned `legacy-*.json` files in `/var/lib/dokku/data/storage-registry/entries/`. The dokku user that runs `ps:rebuild` could not read them and every rebuild on a 0.37.x to 0.38.0 upgrade failed with permission denied. The companion `repairRegistryOwnership` pass in `TriggerInstall` rewrites ownership across the whole registry tree so installs that already ran the buggy code are fixed on the next package upgrade, since the per-app migration flag would otherwise cause `MigrateLegacyMounts` to skip the broken files forever.
The previous regression case selected `--openresty-global-hsts`, but `hsts` is rejected by `openresty:set --global` because it is not in the plugin's GLOBAL_KEYS list. Switch to `--openresty-letsencrypt-server`, which the bats setup already pins to a known staging URL, so the test exercises the same `--global --<info-flag>` parsing path without needing a separate set step.
The argument-handling block in each plugin's report command overwrote APP with --global before checking whether $1 actually held an info flag, so `dokku <plugin>:report --global --<plugin>-foo` always emitted the full report instead of the requested value. Reorder the conditionals across the sixteen plugins that share the pattern so the info-flag check runs first, and add a regression bats case for each one.
The byjg/easy-haproxy image polls Docker for label changes every 10
seconds by default, which races with the haproxy bats suite and
intermittently produces curl exit 7. Expose `refresh-conf` as a
global-only haproxy property that maps to `EASYHAPROXY_REFRESH_CONF`,
lower it to 2 seconds in the bats setup, and wrap the localhost HTTP
assertions in a retry loop so checks wait for haproxy to converge
rather than failing on the first attempt.
The 0.38.0 migration documents `proxy:set <app> type <value>` as the canonical way to set the proxy implementation, but several user-facing examples still taught the legacy implicit form. Switch every example over to the explicit property syntax so the docs match the migration guide and other property-based plugin commands.
Per-plugin management docs now describe the properties introduced by the env-var-to-property migration in PR #8498, and stale prose and command-output examples that still referenced the old `DOKKU_*` names have been refreshed. The deprecated env vars table moves out of `environment-variables.md` and into the 0.38.0 migration guide, where it functions as a one-time pointer for upgrading users rather than ongoing reference material.
The default nginx template rendered four near-identical server blocks per app, so the same listen, access_log, error_log, ssl_*, error_page, and proxy chain had to be maintained across http, https, grpc, and grpcs branches. Merging http and https into a single branch keyed on an `is_ssl` boolean, and likewise grpc and grpcs, removes the duplicate proxy_set_header chain and error-page locations and brings the structure in line with the openresty proxy template. Output is preserved up to whitespace and the existing `cat -s` pass already squashes the leftover blank lines. Adds plugins/nginx-vhosts/template_test.go exercising the rendered output via sigil as a Go library across HTTP-only, HTTPS, HTTP-to-HTTPS redirect, no-listeners 502 fallback, gRPC, gRPCs, gRPC-without-listeners skip, IPv4 bind, upstream blocks with and without keepalive, the access_log `off` short-circuit, the X-Forwarded-Ssl toggle, the http2 listen-parameter vs directive split, http2_push_preload conditional emission, and the nginx.conf.d/*.conf include in every code path; and tests/unit/nginx-vhosts_16.bats covering deploy plus `nginx -t` end-to-end for both HTTP and HTTPS apps.
# History
## 0.38.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.38.0/bootstrap.sh
sudo DOKKU_TAG=v0.38.0 bash bootstrap.sh
```
See the [0.38.0 migration guide](/docs/appendices/0.38.0-migration-guide.md) for more information on migrating to 0.38.0.
### Bug Fixes
- #8533: @josegonzalez Split env config and image pull secret into separate helm releases
- #8530: @josegonzalez Split multi-flag input in docker-options
- #8528: @josegonzalez Skip retiring images still in use by app containers
- #8525: @josegonzalez Add launcher entrypoint for CNB images on dokku run and cron:run
- #8522: @josegonzalez Only emit keda fallback when a non-cpu/memory trigger exists
- #8515: @josegonzalez Fix vector mount directory config
- #8508: @josegonzalez Preserve all domains when renaming an app
- #8507: @josegonzalez Retire orphaned containers when scaling down
### New Features
- #8538: @josegonzalez Add scheduler-aware named storage entries
- #8527: @josegonzalez Accept --global on :report subcommands
- #8524: @josegonzalez Pre-validate custom nginx.conf.sigil during core-post-extract
- #8523: @josegonzalez Support resource limits on the build container
- #8517: @josegonzalez Send SIGTERM to old containers immediately on deploy
- #8516: @josegonzalez Scope docker-options to specific procfile processes
- #8509: @josegonzalez Ship default catch-all site on fresh apt install
- #8506: @josegonzalez Add --format json to git:report and nginx:report
- #8505: @josegonzalez Add git:auth-status to check netrc match
- #8493: @josegonzalez Generate 502 config for apps without web listeners
- #8404: @josegonzalez Upgrade vector chart from 0.42.0 to 0.52.0
- #8403: @josegonzalez Upgrade ingress-nginx chart from 4.10.0 to 4.15.1
- #8402: @josegonzalez Upgrade keda to 2.19.0 and keda-add-ons-http to 0.12.2
- #8259: @josegonzalez Add post-create support for env key in app.json
- #8157: @josegonzalez Add support for specifying buildpacks via app.json
- #8154: @josegonzalez Enable live-restore by default when installing Dokku
- #3697: @josegonzalez Migrate builds plugin to go and track per-build records
### Refactors
- #8514: @josegonzalez Migrate docker-options subcommands to go
- #6716: @josegonzalez Move app and global ENV files to consolidated config path
### Dependencies
- #8541: @dependabot[bot] chore(deps): bump traefik from v3.6.14 to v3.6.15 in /plugins/traefik-vhosts
- #8537: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.43 to 2.11.44 in /plugins/scheduler-k3s
- #8535: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.39.1 to 1.40.0 in /plugins/common
- #8529: @josegonzalez chore: bump dokku/netrc to v0.11.0
- #8520: @dependabot[bot] chore(deps): bump packaging from 26.1 to 26.2 in /docs/_build
- #8510: @dependabot[bot] chore(deps): bump packaging from 26.1 to 26.2 in /docs/_build
- #8503: @josegonzalez Bump dependency versions and add daily updater workflow
- #8502: @josegonzalez Bump go version to 1.26.2
- #8495: @dependabot[bot] chore(deps): bump k8s.io/apimachinery from 0.35.4 to 0.36.0 in /plugins/scheduler-k3s
- #8494: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.9.3 to 0.10.0 in /plugins/openresty-vhosts
- #8490: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.35.4 to 1.36.0 in /plugins/scheduler-k3s
### Other
- #8498: @josegonzalez Migrate environment variables to plugin properties
Adds plugins/storage/migrate_test.go exercising migrateApp and MigrateLegacyMounts: single deploy phase, cross-phase grouping into one attachment, :ro and free-form volume options preserved on the attachment, idempotency on a second pass, the per-app flag-file fast path that skips already-migrated apps, and the name-collision refusal that aborts before draining. tests/unit/storage.bats gains an end-to-end case that stages a -v line via docker-options:add, runs storage:migrate, and asserts the synthesized colon form shows up in storage:list, the legacy-<hash> entry shows up in storage:list-entries, and the original -v line is gone from docker-options:report on both phases. To make that test (and operators with restored backups) practical, storage gains a storage:migrate <app>|--all subcommand backed by a new MigrateApp helper that skips the per-app flag file so a re-run actually re-scans.
Adds typed JSON build records under data/builds/<app>/<build-id>.{json,log} keyed on a stable base36 ULID-style DOKKU_BUILD_ID generated for every deploy. The new commands surface that history (builds:list, builds:info, builds:prune) and an operator-configurable retention via builds:set retention. The existing builds:cancel and builds:output now key on the build-id (with safe handling for already-finalized and abandoned records), and the per-build log file replaces journalctl as the durable source of truth for builds:output.
CallExecCommand wraps non-zero exit codes as errors with the code populated on the response, so storage:exec was returning the wrapped error and being collapsed to exit 1 by LogFailWithError before the os.Exit branch ran. Both storage's CommandExec and scheduler-docker-local's TriggerSchedulerStorageExec now check ExitCode before err so the underlying tool's status flows through verbatim. Separately, the legacy host:container colon form of storage:mount used to write straight into docker-options, but storage:list now reads only attachments, so newly mounted legacy-form storage was invisible. CommandMount and CommandUnmount route the colon form through LegacyMountToEntry plus AddAttachment / RemoveAttachment, making storage:list show every mount regardless of form while preserving the existing "Mount path already exists." / "Mount path does not exist." error wording.
The install trigger created /var/lib/dokku/data/storage-registry and its entries / migrations subdirectories as root with mode 0755, so the dokku user that runs storage:create couldn't write entry JSON files or migration flag files into them. Mirrors what PropertySetup does for config/storage by calling SetPermissions on each registry path. This unblocks the bats coverage that was failing at the first storage:create call.
Moves the actual exec out of the storage plugin and into a new scheduler-storage-exec plugn trigger. scheduler-docker-local does docker run with TTY-aware -it/-i selection and --user derived from entry.Chown; scheduler-k3s creates a throwaway Pod via the kubernetes API, waits for it to reach Running with structured error reporting (ImagePullBackOff and friends are surfaced from the container status verbatim, no kubectl involvement), execs the user command via the existing SPDY plumbing in k8s.go, and deletes the Pod on the way out. (Entry).Validate now accepts either an absolute path or a docker named-volume token for docker-local entries so the migration synthesizer's named-volume legacy entries work cleanly. storage:exec gains --as-user for one-off uid overrides, propagates the underlying tool's exit code via os.Exit, and detects TTY/interactive mode from os.Stdin so non-interactive scripted use no longer trips over docker's input-device-is-not-a-tty error.
storage:list was calling the storage-list plugn trigger which read -v lines from docker-options. After the install-time migration drains those lines into the attachment store, that source is empty for every migrated app and for any app that only ever used storage:create + storage:mount. The fix moves CommandList to call a new in-process ListAppMountEntries helper that reads attachments directly, surfaces the entry name in JSON output via a new entry_name field, and falls back to the entry name as the host token for k3s entries with no host path so the colon form remains well-formed. The storage-list plugn trigger is kept for back-compat with external callers but emits a deprecation warning and now reads from the same attachment-driven source.
The previous condition used a bash regex `git-*` that matched git-receive-pack and git-upload-pack, interposing a tee chain on the binary git wire protocol and producing `fatal: protocol error: bad line length character: !` on every push. Restrict the redirect to the pre-receive hook, where tee passthrough is safe because git-receive-pack forwards hook output via the protocol sideband.
Switches the storage plugin's post-delete and post-app-rename-setup triggers from rewriting the attachment list as empty to removing the per-app property folder outright via PropertyDestroy. This matches the convention other plugins use on app deletion and avoids leaving an empty mounts file behind for an app that no longer exists.
apps:destroy was failing in CI because the post-delete trigger called PropertyListWrite, which tried to mkdir /var/lib/dokku/config/storage/<app> as the dokku user but the parent directory had been created by the install trigger as root. The install trigger now calls PropertySetup("storage") so the per-plugin config root has the correct ownership, and post-delete / post-app-clone / post-app-rename short-circuit when the app has no attachments to begin with so they can't fail on a never-touched property tree. The entry registry and migration flag directories also moved out of config/storage (where they would have collided with the property-store path config/storage/<appName>) into a dedicated data/storage-registry tree.
Updates persistent-storage.md to lead with the named storage entry workflow while keeping the legacy colon-form documentation intact, adds a Persistent storage section to the k3s scheduler doc, documents the storage-app-mounts, storage-create, storage-destroy, and storage-status triggers in plugin-triggers, and adds an entry to the 0.38.0 migration guide explaining the install-time migration of legacy mounts and the new DNS-1123 name validation. Bats coverage in tests/unit/storage.bats now exercises storage:create / list-entries / destroy, name validation rejections, multi-entry attachment, the destroy-while-mounted error, and the ensure-directory deprecation warning.
storage:set is the in-place editor for an existing entry; size grows are passed through to a helm upgrade and Kubernetes-incompatible swaps (access-mode, storage-class) are rejected up front. storage:exec spawns a throwaway container that mounts the entry: docker run on docker-local entries, kubectl run with a Pod-spec override on k3s, falling back to bash then sh when no command is supplied. storage:wait blocks until a k3s entry's PVC reports Bound via the storage-status trigger, with a docker-local fast path that just checks the host directory. storage:report --global enumerates every registered entry and the apps that mount it, in text or JSON form.
Adds a per-entry storage helm chart that owns the PVC and (when host_path is set) the PV, and three triggers for the storage plugin to drive: storage-create installs/upgrades the chart with storage-class existence validation, storage-destroy uninstalls it, storage-status reports the PVC phase. App deployment and cron-job charts now consume storage-app-mounts and reference each PVC by name; the // todo: implement volumes blocks are gone. ProcessVolume gained sub_path, read_only, and persistent_claim fields and the deployment/cron-job templates render them.
storage:mount and storage:unmount now accept the named-entry form (--container-dir, --phase, --process-type, --volume-subpath, --volume-readonly, --volume-chown), persisting attachments via the property list. The legacy host:container colon form is preserved for back-compat. Storage now emits its own docker-args-deploy and docker-args-run triggers so docker-local apps continue to receive bind mounts even after their data moves out of docker-options. The install trigger walks every app once per upgrade and converts legacy -v lines into legacy-<hash> entries plus attachments, draining the originals from docker-options last so a partial run leaves the old behavior intact. Lifecycle triggers post-delete, post-app-clone-setup, and post-app-rename-setup keep the attachment store in sync with app state.
Wires the new entry-management commands on top of the Entry type. storage:create accepts both docker-local entries (with idempotent host-directory creation) and k3s entries (which delegate PVC provisioning to a forthcoming scheduler-side storage-create trigger). storage:destroy refuses to remove an entry that any app still mounts. storage:ensure-directory now emits a deprecation warning. storage:mount and storage:unmount keep the existing colon-form behavior so this commit is non-breaking; the named-entry mount form follows in a later commit.
Introduces the Entry and Attachment types that the storage plugin will use as the source of truth for named storage volumes, replacing the colon-delimited mount strings stored under docker-options. Entries persist as JSON under config/storage/entries and validate against scheduler-specific rules; attachments persist via the property list and capture how an app uses an entry. The legacy migration name synthesizer is also added so existing colon-form mounts can converge on a deterministic legacy- entry name. Existing storage commands are unchanged in this commit.
This still needs tightening to ensure we don't trigger this for normal git plugin commands - as well as anything that triggers a deploy - but works in a pinch.
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.
The new config and pull secret helm releases need to honor user-set annotations and labels for `--resource-type secret` so existing scheduler-k3s annotation tests keep passing. The dedicated charts now render `.Values.global.annotations` and `.Values.global.labels` onto their Secret manifest, and the deploy trigger plumbs `SecretAnnotations` and `SecretLabels` from the global annotation/label config. The rollback regression bats test now uses `dokku ps:rebuild` for its second deploy because git push of an unchanged ref is rejected by the dokku remote.
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.
The previous assertion piped grep -c through `|| echo 0`, which printed an extra `0` when the file existed without matches because grep -c emits the count of `0` and exits 1, triggering the fallback.
The `git:auth` test in `tests/unit/git_3.bats` verifies the written entry with `netrc get --netrc-file ${DOKKU_ROOT}/.netrc github.com`, but the `--netrc-file` flag was added in netrc v0.11.0 and CI was still pinned to v0.10.3, so the assertion ran against root's `~/.netrc` and exited 1.
The trigger output started with `--entrypoint` and relied on the caller
to provide a trailing space. `scheduler-deploy-process-container` does
that, but `scheduler-run` does not when `DOKKU_TRACE` is unset, so the
flag concatenated onto the previous arg as `--env=KEY--entrypoint`,
leaving `launcher` as the image positional argument and causing
`docker container create` to fail with `Unable to find image 'launcher:latest'`.
Match the leading-space convention used by the other docker-args triggers
(`config/docker-args-run`, `builder-herokuish/docker-args-run`).
The scheduler-run script classified CNB-based images as `herokuish` because
`is_image_herokuish_based` returns true for them, which caused the
`docker-args-process-run` trigger for builder-pack to skip injecting
`--entrypoint launcher`. Without that flag the container fell back to the
image entrypoint (`/cnb/process/web`) and dropped the user-supplied
arguments. Mirror the deploy-side detection so CNB images set
`IMAGE_SOURCE_TYPE=pack`, allowing the launcher entrypoint to be added.
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`.
The bats test for migration idempotency invoked the install binary directly via sudo, which kept hitting fresh missing env vars on each iteration (DOKKU_LIB_ROOT, then PLUGIN_PATH, etc). The dokku launcher script exports a chain of vars that the install path reads via common.MustGetEnv, and mirroring that chain in a bats test is fragile. Migration is pure file IO plus a property marker - perfect for a Go unit test that isolates itself with t.TempDir and t.Setenv. The new test covers parsing comments and blank lines, the marker-based no-op on re-run, and the rule that a manually re-created legacy file is left untouched after the marker is set.
The ps plugin auto-adds --restart=on-failure:10 to the default deploy scope on app create, so docker-options:list --phase deploy is never empty for a freshly-created app. Switch the default-scope assertions from exact-match to contains/not-contains so the auto-injected restart line stops causing false failures. The migration test invoked the install binary directly via sudo, but DOKKU_LIB_ROOT is normally exported by the dokku launcher script and isn't set in that subprocess; pass it (and DOKKU_ROOT) explicitly.
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 :list subcommand had `SetInterspersed(false)` which forced flags to come before positional arguments; in practice users invoke it as `docker-options:list <app> --process X --phase Y`. Drop the non-interspersed setting so flags can appear after the app name. Two existing buildpacks/dockerfile tests appended directly to the legacy `DOCKER_OPTIONS_DEPLOY` file - that path is no longer the source of truth, so switch them to `docker-options:add`. The new migration test invoked `dokku plugin:trigger install` which fans out to every plugin and trips on unrelated permission errors; call the docker-options install binary directly instead. Tighten the report and JSON assertions to match the actual output format (`.` becomes a space in the display key, and JSON values may concatenate options).
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.
The single-udp network test was calling `docker-options:add $TEST_APP -p 1194:1194` without a phase argument. The bash subcommand silently no-op'd because `-p` is not a recognized phase, so the test happened to pass even though it was not actually setting the option. The go port surfaces the validation error correctly, so the test now needs the proper `deploy` phase to keep working.
Re-enabling vhost on an app that was previously deployed with no global VHOST left the auto-assigned random high port behind in the ports plugin's `map-detected` property, so nginx kept listening on that port and the new catch-all default vhost rejected requests for the app's own domain on port 80.
Re-enabling vhost (via `proxy:enable`, `domains:enable`, or `domains:add` with no global VHOST) was leaving the app pinned to the random high port and the empty VHOST file from the previous disabled state, so the new catch-all vhost intercepted requests for the app's domain. The `domains-enable` trigger now restores default vhosts via `domains_enable`, and `pre-enable-vhost` clears any stored proxy ports so they can be recomputed to 80/443. Also fixes the netrc lookup in the `git:auth` test to read dokku's netrc file directly.
Renaming `/etc/nginx/sites-enabled/default` to `.dokku-disabled` left a broken symlink that nginx's `include /etc/nginx/sites-enabled/*;` glob still picked up, breaking config validation. Files inside `sites-enabled/` are now removed; the real config in `sites-available/default` is still preserved via rename.
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.
Reloads the nginx server config after validating it with `nginx -t`. Useful for picking up changes to globally managed nginx configs without restarting the running process.
Ports the user-facing CLI subcommands and lifecycle triggers from bash to go, mirroring the layout used by the ports plugin. The on-disk format (`DOCKER_OPTIONS_BUILD/DEPLOY/RUN` files), the `docker-args-build/deploy/run` triggers, and every exported helper consumed by other plugins are unchanged. Reserves the `--process` and `--global` flags on add, remove, and clear so usage today exits with a not-yet-implemented error and the surface is locked in ahead of the process-scoping work tracked in #2441.
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.
The intermediate container count check raced with the existing
zero-downtime retire of the previous container, so docker ps still
saw the renamed-but-pending container until wait-to-retire elapsed.
When scaling a process type to a smaller count, the indices above the
new count had their `CONTAINER.<proctype>.<idx>` state files deleted but
the underlying Docker containers were never registered for retirement,
so they remained running indefinitely. The cleanup block now reads each
orphaned state file and registers its container id with the existing
`scheduler-register-retired` trigger before the file is removed.
The `post-app-rename-setup` trigger redirected `sed` output to the new
app's VHOST file inside a loop over global vhosts, so each iteration
clobbered the previous one and only the last global subdomain was
rewritten. When no global vhost was set, the loop never ran and the
new app's VHOST file was never written, leaving the renamed app with
no domains.
Copy the old app's VHOST file once as a baseline, then apply `sed -i`
in place for each global vhost so substitutions accumulate. Guard
against a missing global VHOST file and skip blank lines.
- config_test.go: create app dir at DOKKU_ROOT for VerifyAppName and
ensure global config parent directory exists
- migrateGlobalEnv: set dokku:dokku ownership on global ENV file after
writing so deploy processes running as dokku can read it
The post-create trigger only created the property directory at
DOKKU_LIB_ROOT/config/config/{app}/, but getAppFile() writes the
ENV file to DOKKU_LIB_ROOT/config/{app}/ENV. Add setupAppConfigDir
to create and permission the ENV directory in both post-create and
install triggers, and clean it up on post-delete.
- Move migrateGlobalEnv() before UnfilteredDokkuApps() so the global
config directory is created even on fresh installs with no apps
- Add DOKKU_LIB_ROOT to Go test env vars in tests.mk
- Use DOKKU_LIB_ROOT instead of DOKKU_ROOT in getGlobalFile() to match
the intended new config path layout
- Add missing comma in filepath.Join for old app ENV migration path
- Revert common_test.go app dirs to DOKKU_ROOT since app detection
still uses AppRoot()
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`.
Pre-set LOCAL_DOMAIN in the tini test so mastodon's required env var
resolves, and replace unsupported `generator: "echo 5"` with `value: "5"`
in the nodejs-express and dockerfile fixtures so WEB_CONCURRENCY no
longer aborts deploys via the new app.json env processor.
Switches the dependency-updates workflow to use HOMEBREW_GITHUB_API_TOKEN
(the same PAT used to bump the homebrew formula on release) and sets
the committer/author to Dokku Bot <no-reply@dokku.com>.
Bumps every entry in contrib/dependencies.json to its latest upstream
release. Adds a scheduled GitHub Actions workflow that checks each
dependency once a day and opens one PR per outdated entry.
- Mount `/vector-data-dir` from host (`/var/lib/vector` via `hostPath`, `DirectoryOrCreate`) so `kubernetes_logs` checkpoints survive pod restarts; resolves conflict with the chart's read-only `/var/lib` default volume
- Enable Vector API on `:8686` and wire HTTP `/health` liveness and readiness probes; add `internal_metrics` source and `prometheus_exporter` sink on `:9090` so the `prom-exporter` service port is actually backed by an exporter
- Set explicit `targetPort` on the `prom-exporter` port to avoid inference mismatches
- Remove the `.message = .message` no-op
- Add `node-role.kubernetes.io/control-plane` toleration alongside the legacy `master` key so the DaemonSet schedules on control-plane nodes regardless of cluster age
# 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
proxy:set <app> <proxy-type> continues to work as before by detecting
when the first argument is not a known property name and treating it
as the type value. Also preserves the port mapping detection error
for inputs containing colons.
- 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
- Add apps:set subcommand for managing apps properties (mirrors
ps:set, scheduler:set, builder:set pattern)
- Update nginx-vhosts functions/pre-disable-vhost/pre-enable-vhost
to read proxy port from properties instead of config vars
- Fix test commands to use correct property-setting approaches:
prop binary for ports properties, apps:set for apps properties
The apps:clone --skip-deploy test expected 404 for the cloned app's
domain. With the new empty nginx config, undeployed apps now correctly
return 502 Bad Gateway instead of falling through to nginx's default.
The config:show and config:export tests now include DOKKU_PROXY_PORT
in expected output since ports-configure runs at app creation time.
Add sleep before HTTP assertion in nginx-vhosts_13 test to allow
nginx async reload to complete.
When nginx is stopped (e.g. during traefik/caddy tests), the
post-create trigger should not attempt to build and reload the
nginx config as the service is not running.
The post-create trigger was not executable so plugn skipped it.
Also skip generating the 502 config when PROXY_PORT_MAP is empty
(e.g. after ports:clear) to avoid a sigil template index error.
Merge the deployed and empty-listeners branches into a single flow
that shares the SIGIL_PARAMS array, temp dir setup, sigil rendering,
and nginx reload. Branch only for deployed-specific logic: image
verification, custom template lookup, per-process listeners, and HSTS.
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.
Move dependabot entries for /tests/apps/ directories from the
"type: dependencies" label to "type: tests" so they appear under
the Tests section in the changelog instead of Dependencies.
When deploying via git:from-image, the source image may contain an
app.json with buildpacks entries that are not relevant. Check for
the source-image property and skip app.json buildpacks when set.
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
Add `domains:clear-global`, `logs:vector-*`, and `scheduler-k3s`
cluster, profile, and system commands that take resource names
instead of app names as their first argument.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The dokku client auto-detects the app name from the git remote
and prepends `--app <name>` to all SSH commands not explicitly
excluded. Network commands like `network:create` take a network
name (not an app name) as their first argument, so the injected
app name was being used as the network name instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GraphQL servers like Yoga v5 and Apollo Server 4 use the application/graphql-response+json content type per the GraphQL-over-HTTP spec (IANA registered). Without this in gzip_types, nginx silently skips compression for all GraphQL responses, sending megabytes of uncompressed JSON over the wire.
# History
## 0.37.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.7/bootstrap.sh
sudo DOKKU_TAG=v0.37.7 bash bootstrap.sh
```
### Bug Fixes
- #8379: @josegonzalez Call correct function for limiting letsencrypt to certain domains
### New Features
- #8405: @josegonzalez Add Debian 13 versions of docker plugin packages
- #8261: @josegonzalez Configure Traefik readiness healthchecks based on app.json config
- #8378: @farmdawgnation Support custom entrypoint for api and dashboard
### Dependencies
- #8395: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.12.0 to 3.13.0 in /plugins/cron
- #8401: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.38 to 2.11.40 in /plugins/scheduler-k3s
- #8400: @dependabot[bot] chore(deps): bump github.com/melbahja/goph from 1.4.0 to 1.5.0 in /plugins/common
- #8394: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.47.0 to 0.48.0 in /plugins/common
- #8396: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.19.0 to 0.20.0 in /plugins/common
- #8399: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.19.0 to 0.20.0 in /plugins/scheduler-k3s
- #8398: @dependabot[bot] chore(deps): bump traefik from 3.6.9 to v3.6.10 in /plugins/traefik-vhosts
- #8397: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.19.0 to 0.20.0 in /plugins/scheduler-docker-local
- #8314: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.39.0 to 1.39.1 in /plugins/common
- #8380: @dependabot[bot] chore(deps): bump lucaslorentz/caddy-docker-proxy from 2.10 to 2.11 in /plugins/caddy-vhosts
- #8381: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.35.0 to 0.35.2 in /plugins/scheduler-k3s
- #8382: @dependabot[bot] chore(deps): bump docker/login-action from 3 to 4
- #8383: @dependabot[bot] chore(deps): bump docker/setup-qemu-action from 3 to 4
- #8384: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.3 to 9.7.4 in /docs/_build
- #8385: @dependabot[bot] chore(deps): bump django from 5.2.11 to 5.2.12 in /tests/apps/dockerfile-release
- #8387: @dependabot[bot] chore(deps): bump docker/setup-buildx-action from 3 to 4
- #8388: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.79.1 to 1.79.2 in /tests/apps/gogrpc
- #8389: @dependabot[bot] chore(deps): bump golang from 1.26.0 to 1.26.1 in /tests/apps/go-fail-postdeploy
- #8390: @dependabot[bot] chore(deps): bump golang from 1.26.0 to 1.26.1 in /tests/apps/gogrpc
- #8391: @dependabot[bot] chore(deps): bump golang from 1.26.0 to 1.26.1 in /tests/apps/go-fail-predeploy
- #8392: @dependabot[bot] chore(deps): bump golang from 1.26.0 to 1.26.1 in /tests/apps/zombies-dockerfile-tini
- #8393: @dependabot[bot] chore(deps): bump golang from 1.26.0 to 1.26.1 in /tests/apps/zombies-dockerfile-no-tini
- #8354: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.78.0 to 1.79.1 in /tests/apps/gogrpc
- #8340: @dependabot[bot] chore(deps): bump python from 3.14.2-alpine to 3.14.3-alpine in /docs/_build
- #8353: @dependabot[bot] chore(deps): bump gunicorn from 25.0.2 to 25.1.0 in /tests/apps/multi
- #8357: @dependabot[bot] chore(deps): bump qs from 6.14.1 to 6.14.2 in /tests/apps/checks-root
- #8361: @dependabot[bot] chore(deps): bump flask from 3.1.2 to 3.1.3 in /tests/apps/multi
- #8360: @dependabot[bot] chore(deps): bump rack from 3.2.4 to 3.2.5 in /tests/apps/ruby
- #8332: @dependabot[bot] chore(deps-dev): bump org.apache.maven.plugins:maven-dependency-plugin from 3.9.0 to 3.10.0 in /tests/apps/java
- #8336: @dependabot[bot] chore(deps): bump python from 3.14.2-bookworm to 3.14.3-bookworm in /tests/apps/dockerfile-release
- #8355: @dependabot[bot] chore(deps): bump gunicorn from 25.0.2 to 25.1.0 in /tests/apps/python-flask
- #8356: @dependabot[bot] chore(deps): bump gunicorn from 25.0.2 to 25.1.0 in /tests/apps/dockerfile-release
- #8358: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.20.1 to 10.21 in /docs/_build
- #8371: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 5.0.0 to 6.0.1 in /plugins/haproxy-vhosts
- #8362: @dependabot[bot] chore(deps): bump flask from 3.1.2 to 3.1.3 in /tests/apps/python-flask
- #8374: @dependabot[bot] chore(deps): bump actions/download-artifact from 7 to 8
- #8375: @dependabot[bot] chore(deps): bump actions/upload-artifact from 6 to 7
- #8376: @dependabot[bot] chore(deps): bump phusion/baseimage from noble-1.0.2 to noble-1.0.3
- #8377: @dependabot[bot] chore(deps): bump whitenoise from 6.11.0 to 6.12.0 in /tests/apps/dockerfile-release
- #8365: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.36 to 2.11.37 in /plugins/scheduler-k3s
- #8367: @dependabot[bot] chore(deps): bump werkzeug from 3.1.5 to 3.1.6 in /tests/apps/python-flask
- #8368: @dependabot[bot] chore(deps): bump dj-database-url from 3.1.0 to 3.1.2 in /tests/apps/dockerfile-release
- #8372: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.1 to 9.7.3 in /docs/_build
- #8373: @dependabot[bot] chore(deps): bump traefik from 3.6.7 to 3.6.9 in /plugins/traefik-vhosts
- #8351: @dependabot[bot] chore(deps): bump golang from 1.25.6 to 1.26.0 in /tests/apps/zombies-dockerfile-tini
- #8350: @dependabot[bot] chore(deps): bump golang from 1.25.6 to 1.26.0 in /tests/apps/zombies-dockerfile-no-tini
- #8349: @dependabot[bot] chore(deps): bump golang from 1.25.6 to 1.26.0 in /tests/apps/go-fail-postdeploy
- #8348: @dependabot[bot] chore(deps): bump golang from 1.25.6 to 1.26.0 in /tests/apps/gogrpc
- #8347: @dependabot[bot] chore(deps): bump golang from 1.25.6 to 1.26.0 in /tests/apps/go-fail-predeploy
- #8344: @dependabot[bot] chore(deps): bump sigs.k8s.io/kustomize/api from 0.21.0 to 0.21.1 in /plugins/scheduler-k3s
- #8329: @dependabot[bot] chore(deps): bump gunicorn from 25.0.1 to 25.0.2 in /tests/apps/multi
- #8330: @dependabot[bot] chore(deps): bump gunicorn from 25.0.1 to 25.0.2 in /tests/apps/python-flask
- #8331: @dependabot[bot] chore(deps): bump gunicorn from 25.0.1 to 25.0.2 in /tests/apps/dockerfile-release
- #8320: @dependabot[bot] chore(deps): bump django from 5.2.10 to 5.2.11 in /tests/apps/dockerfile-release
- #8321: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.35 to 2.11.36 in /plugins/scheduler-k3s
- #8319: @dependabot[bot] chore(deps): bump gunicorn from 24.1.1 to 25.0.1 in /tests/apps/dockerfile-release
- #8318: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.19.2 to 1.19.3 in /plugins/scheduler-k3s
- #8317: @dependabot[bot] chore(deps): bump gunicorn from 24.1.1 to 25.0.1 in /tests/apps/multi
- #8316: @dependabot[bot] chore(deps): bump gunicorn from 24.1.1 to 25.0.1 in /tests/apps/python-flask
Add two new global-only properties to configure a dedicated Traefik entrypoint
for the API and dashboard, enabling network isolation on private interfaces.
Includes comprehensive test coverage for property management and compose config.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
# History
## 0.37.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.6/bootstrap.sh
sudo DOKKU_TAG=v0.37.6 bash bootstrap.sh
```
### Bug Fixes
- #8306: @josegonzalez Ensure we can call storage:report properly
### Documentation
- #8289: @josegonzalez Add an architecture document for dokku
- #8288: @josegonzalez Add a readme for the docs folder
### Dependencies
- #8312: @dependabot[bot] chore(deps): bump timberio/vector from 0.52.0-debian to 0.53.0-debian in /plugins/logs
- #8311: @dependabot[bot] chore(deps): bump gunicorn from 24.0.0 to 24.1.1 in /tests/apps/dockerfile-release
- #8308: @dependabot[bot] chore(deps): bump gunicorn from 24.0.0 to 24.1.1 in /tests/apps/multi
- #8309: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.20 to 10.20.1 in /docs/_build
- #8307: @dependabot[bot] chore(deps): bump gunicorn from 24.0.0 to 24.1.1 in /tests/apps/python-flask
- #8301: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.19.5 to 3.20.0 in /plugins/scheduler-k3s
- #8299: @dependabot[bot] chore(deps): bump ruby from 4.0.0 to 4.0.1 in /tests/apps/dockerfile-entrypoint
- #8293: @dependabot[bot] chore(deps): bump golang from 1.25.5 to 1.25.6 in /tests/apps/zombies-dockerfile-no-tini
- #8296: @dependabot[bot] chore(deps): bump soupsieve from 2.8.1 to 2.8.3 in /docs/_build
- #8295: @dependabot[bot] chore(deps): bump golang from 1.25.5 to 1.25.6 in /tests/apps/go-fail-postdeploy
- #8294: @dependabot[bot] chore(deps): bump golang from 1.25.5 to 1.25.6 in /tests/apps/gogrpc
- #8291: @dependabot[bot] chore(deps): bump golang from 1.25.5 to 1.25.6 in /tests/apps/zombies-dockerfile-tini
- #8292: @dependabot[bot] chore(deps): bump golang from 1.25.5 to 1.25.6 in /tests/apps/go-fail-predeploy
- #8277: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.34 to 2.11.35 in /plugins/scheduler-k3s
- #8297: @dependabot[bot] chore(deps): bump pyparsing from 3.3.1 to 3.3.2 in /docs/_build
- #8298: @dependabot[bot] chore(deps): bump lodash from 4.17.21 to 4.17.23 in /tests/apps/multi
- #8300: @dependabot[bot] chore(deps): bump packaging from 25.0 to 26.0 in /docs/_build
- #8303: @dependabot[bot] chore(deps): bump gunicorn from 23.0.0 to 24.0.0 in /tests/apps/python-flask
- #8305: @dependabot[bot] chore(deps): bump gunicorn from 23.0.0 to 24.0.0 in /tests/apps/dockerfile-release
- #8304: @dependabot[bot] chore(deps): bump gunicorn from 23.0.0 to 24.0.0 in /tests/apps/multi
- #8280: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.19.4 to 3.19.5 in /plugins/scheduler-k3s
- #8279: @dependabot[bot] chore(deps): bump traefik from 3.6.6 to 3.6.7 in /plugins/traefik-vhosts
# History
## 0.37.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.5/bootstrap.sh
sudo DOKKU_TAG=v0.37.5 bash bootstrap.sh
```
### Bug Fixes
- #8274: @josegonzalez Delete the tls app chart when the app is deleted
- #8273: @josegonzalez Ensure the destination directory exists when extracting files from a repository
- #8263: @josegonzalez Set correct version for builder-railpack plugin
### New Features
- #8268: @josegonzalez Add the ability to log into a registry on a per-app basis
- #8258: @josegonzalez Add support for dns-01 challenge mode when using traefik
- #8262: @josegonzalez Use certificates imported by certs plugin when deploying via scheduler-k3s
- #8266: @josegonzalez Add a method to force build when re-using an image with git:from-image
- #8265: @josegonzalez Add the ability to skip setting the deploy-branch when running git:sync
### Refactors
- #8264: @josegonzalez Rewrite the storage plugin in golang
### Dependencies
- #8270: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.38.3 to 1.39.0 in /plugins/common
- #8267: @dependabot[bot] chore(deps): bump werkzeug from 3.1.4 to 3.1.5 in /tests/apps/python-flask
- #8260: @dependabot[bot] chore(deps): bump django from 5.2.9 to 5.2.10 in /tests/apps/dockerfile-release
- #8256: @dependabot[bot] chore(deps): bump luizm/action-sh-checker from 0.9.0 to 0.10.0
- #8257: @dependabot[bot] chore(deps): bump dj-database-url from 3.0.1 to 3.1.0 in /tests/apps/dockerfile-release
# History
## 0.37.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.4/bootstrap.sh
sudo DOKKU_TAG=v0.37.4 bash bootstrap.sh
```
### Bug Fixes
- #8168: @josegonzalez Install logrotate in the container
### Tests
- #8254: @josegonzalez Add a test to prove cron:run commands work as expected
- #8255: @josegonzalez Update test ruby app
### Dependencies
- #8252: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.19.1 to 10.20 in /docs/_build
- #8253: @dependabot[bot] chore(deps): bump qs from 6.14.0 to 6.14.1 in /tests/apps/checks-root
- #8249: @dependabot[bot] chore(deps): bump traefik from 3.6.5 to 3.6.6 in /plugins/traefik-vhosts
- #8250: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.33 to 2.11.34 in /plugins/scheduler-k3s
- #8247: @dependabot[bot] chore(deps): bump ruby from 3.4.8 to 4.0.0 in /tests/apps/dockerfile-entrypoint
### Other
- #8248: @osbre Add `proxy-keepalive` to Nginx properties
# History
## 0.37.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.3/bootstrap.sh
sudo DOKKU_TAG=v0.37.3 bash bootstrap.sh
```
### Bug Fixes
- #8199: @josegonzalez Pass global build args as array when building nixpacks apps
- #8236: @josegonzalez Ensure the /etc/docker exists when interacting with it via postinst
### Documentation
- #8229: @kleutzinger Fix command syntax for removing docker options
- #8219: @deanmarano Add deanmarano to community plugins list
- #8205: @deanmarano Add DNS plugin to community plugins list
### Tests
- #8246: @josegonzalez Add tests to prove that Procfile tasks all work for every builder
### Dependencies
- #8243: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.34.2 to 0.35.0 in /plugins/scheduler-k3s
- #8245: @dependabot[bot] chore(deps): bump github.com/go-resty/resty/v2 from 2.17.0 to 2.17.1 in /plugins/scheduler-k3s
- #8244: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.34.2 to 1.35.0 in /plugins/scheduler-k3s
- #8233: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.38.2 to 1.38.3 in /plugins/common
- #8241: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.32 to 2.11.33 in /plugins/scheduler-k3s
- #8240: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.19.1 to 1.19.2 in /plugins/scheduler-k3s
- #8239: @dependabot[bot] chore(deps): bump pyparsing from 3.2.5 to 3.3.1 in /docs/_build
- #8238: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.77.0 to 1.78.0 in /tests/apps/gogrpc
- #8237: @dependabot[bot] chore(deps): bump github.com/kedacore/keda/v2 from 2.18.2 to 2.18.3 in /plugins/scheduler-k3s
- #8235: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.19.2 to 3.19.4 in /plugins/scheduler-k3s
- #8232: @dependabot[bot] chore(deps): bump importlib-metadata from 8.7.0 to 8.7.1 in /docs/_build
- #8234: @dependabot[bot] chore(deps): bump k8s.io/client-go from 0.34.2 to 0.35.0 in /plugins/scheduler-k3s
- #8231: @dependabot[bot] chore(deps): bump github.com/expr-lang/expr from 1.17.6 to 1.17.7 in /plugins/scheduler-k3s
- #8208: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.45.0 to 0.46.0 in /plugins/common
- #8201: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.18.0 to 0.19.0 in /plugins/common
- #8214: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.10 to 1.36.11 in /tests/apps/gogrpc
- #8216: @dependabot[bot] chore(deps): bump actions/download-artifact from 6 to 7
- #8217: @dependabot[bot] chore(deps): bump actions/upload-artifact from 5 to 6
- #8228: @dependabot[bot] chore(deps): bump soupsieve from 2.8 to 2.8.1 in /docs/_build
- #8226: @dependabot[bot] chore(deps): bump ruby from 3.4.7 to 3.4.8 in /tests/apps/dockerfile-entrypoint
- #8227: @dependabot[bot] chore(deps): bump mkdocs-material from 9.7.0 to 9.7.1 in /docs/_build
- #8224: @dependabot[bot] chore(deps): bump traefik from 3.6.4 to 3.6.5 in /plugins/traefik-vhosts
- #8225: @dependabot[bot] chore(deps): bump timberio/vector from 0.51.1-debian to 0.52.0-debian in /plugins/logs
- #8220: @dependabot[bot] chore(deps): bump python from 3.14.1-bookworm to 3.14.2-bookworm in /tests/apps/dockerfile-release
- #8221: @dependabot[bot] chore(deps): bump python from 3.14.1-alpine to 3.14.2-alpine in /docs/_build
- #8218: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.19 to 10.19.1 in /docs/_build
- #8215: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.18 to 10.19 in /docs/_build
- #8209: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.38.2 to 1.38.3 in /plugins/config
- #8210: @dependabot[bot] chore(deps): bump github.com/kedacore/keda/v2 from 2.18.1 to 2.18.2 in /plugins/scheduler-k3s
- #8211: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.22.3 to 0.22.4 in /plugins/scheduler-k3s
- #8200: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.17.2 to 10.18 in /docs/_build
- #8202: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.18.0 to 0.19.0 in /plugins/scheduler-docker-local
- #8203: @dependabot[bot] chore(deps): bump traefik from 3.6.2 to 3.6.4 in /plugins/traefik-vhosts
- #8204: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.18.0 to 0.19.0 in /plugins/scheduler-k3s
# History
## 0.37.2
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.2/bootstrap.sh
sudo DOKKU_TAG=v0.37.2 bash bootstrap.sh
```
### Bug Fixes
- #8198: @josegonzalez Ensure we continue on with logic if the error returned from fetching all apps is NoAppsExist
### Dependencies
- #8196: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 4.6.0 to 5.0.0 in /plugins/haproxy-vhosts
- #8197: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.31 to 2.11.32 in /plugins/scheduler-k3s
# History
## 0.37.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.1/bootstrap.sh
sudo DOKKU_TAG=v0.37.1 bash bootstrap.sh
```
### Bug Fixes
- #8186: @josegonzalez Update url to download golang
- #8155: @josegonzalez Sanitize vector sink values in report output
- #8156: @josegonzalez Do not start nginx if there are no apps with nginx as a proxy
- #8152: @josegonzalez Ensure keda usage does not cause jank in scaling deployments
### New Features
- #8154: @josegonzalez Enable live-restore by default when installing Dokku
- #8151: @josegonzalez Allow exposing non-web processes as kubernetes services
### Refactors
- #8149: @josegonzalez Remove nginx checks for functionality that always exists
### Documentation
- #8170: @znz Fix version in migration docs
- #8169: @josegonzalez Update logging in doc generation to enhance doc generation debugging
- #8153: @josegonzalez Fix reference to letsencrypt-server property
- #8150: @josegonzalez Clarify system requirements for k3s usage
- #8148: @josegonzalez Clarify plugin installation documentation
### Dependencies
- #8192: @dependabot[bot] chore(deps): bump golang from 1.25.4 to 1.25.5 in /tests/apps/go-fail-predeploy
- #8191: @dependabot[bot] chore(deps): bump golang from 1.25.4 to 1.25.5 in /tests/apps/go-fail-postdeploy
- #8189: @dependabot[bot] chore(deps): bump golang from 1.25.4 to 1.25.5 in /tests/apps/gogrpc
- #8193: @dependabot[bot] chore(deps): bump python from 3.14.0-alpine to 3.14.1-alpine in /docs/_build
- #8190: @dependabot[bot] chore(deps): bump golang from 1.25.4 to 1.25.5 in /tests/apps/zombies-dockerfile-no-tini
- #8188: @dependabot[bot] chore(deps): bump golang from 1.25.4 to 1.25.5 in /tests/apps/zombies-dockerfile-tini
- #8194: @dependabot[bot] chore(deps): bump python from 3.14.0-bookworm to 3.14.1-bookworm in /tests/apps/dockerfile-release
- #8195: @dependabot[bot] chore(deps): bump django from 5.2.8 to 5.2.9 in /tests/apps/dockerfile-release
- #8177: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/nodejs-express-noprocfile
- #8178: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/dockerfile-procfile-bad
- #8179: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/nodejs-express
- #8180: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/dockerfile-procfile
- #8181: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/gitsubmodules
- #8183: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/checks-root
- #8182: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/nodejs-express-noappjson
- #8184: @dependabot[bot] chore(deps): bump express from 5.1.0 to 5.2.1 in /tests/apps/dockerfile-app-json-formations
- #8172: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.14.2 to 4.14.3 in /docs/_build
- #8173: @dependabot[bot] chore(deps): bump werkzeug from 3.1.3 to 3.1.4 in /tests/apps/python-flask
- #8164: @dependabot[bot] chore(deps): bump body-parser from 2.2.0 to 2.2.1 in /tests/apps/checks-root
- #8165: @dependabot[bot] chore(deps): bump github.com/go-resty/resty/v2 from 2.16.5 to 2.17.0 in /plugins/scheduler-k3s
- #8167: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.17.1 to 10.17.2 in /docs/_build
- #8162: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.30 to 2.11.31 in /plugins/scheduler-k3s
- #8161: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.23.0 to 1.24.0 in /plugins/scheduler-k3s
- #8159: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.19.0 to 3.19.2 in /plugins/scheduler-k3s
- #8158: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.34.1 to 1.34.2 in /plugins/scheduler-k3s
- #8143: @dependabot[bot] chore(deps): bump actions/checkout from 5 to 6
- #8145: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.22.1 to 0.22.3 in /plugins/scheduler-k3s
- #8146: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.34.1 to 0.34.2 in /plugins/scheduler-k3s
- #8144: @dependabot[bot] chore(deps): bump traefik from 3.6.1 to 3.6.2 in /plugins/traefik-vhosts
It is not sanitized in json format output as that is used for automation, but this should remove the need to redact any potentially sensitive information that users have in the sink, such as a token.
Closes#8147
If the values set by keda do not match the current deployment replicas value, the deployment object may be scaled in unexpected ways during a helm release. This change ensures keda will continue to manage that value correctly without the deployment object setting it back to something else.
# History
## 0.37.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.37.0/bootstrap.sh
sudo DOKKU_TAG=v0.37.0 bash bootstrap.sh
```
See the [0.37.0 migration guide](/docs/appendices/0.37.0-migration-guide.md) for more information on migrating to 0.37.0.
### Backwards Compatibility Breaks
- #8140: @josegonzalez Rename the scheduler-k3s:cluster-* commands to use a : instead of - for a delimiter
- #7982: @josegonzalez Remove references to pack being experimental
### Bug Fixes
- #8136: @josegonzalez Do not reset manually set port mappings when upgrading dokku
- #8114: @josegonzalez Ensure we can execute run commands when exec is executed as part of an entrypoint
- #8109: @josegonzalez Allow skipping the install trigger when installing a plugin
- #8104: @josegonzalez Drop deprecated aufs check
- #8100: @othercorey Add process-type label for run with procfile cmd
### New Features
- #8139: @josegonzalez Add aliases for select builder and scheduler plugins
- #8138: @josegonzalez Turn on buildpack trace mode when dokku trace is on
- #8137: @josegonzalez Add the ability to create k3s node profiles
- #8135: @josegonzalez Add support for git remotes with port specified inline
- #8112: @josegonzalez Implement cron and one-off run task TTLs
- #8106: @josegonzalez Support inline comments for app.json
- #8105: @josegonzalez Allow specifying kubelet-args when adding a new node to the cluster
- #8085: @josegonzalez Implement config:import command
- #8004: @Tashows Add buildpacks:detect subcommand
- #7991: @josegonzalez Add ability to pause/restart cron jobs
- #7989: @josegonzalez Add support to prevent overlapping execution of cron tasks
- #7986: @josegonzalez Add support for specifying CNB buildpacks via buildpacks command
- #7956: @josegonzalez Add a Railpack builder to Dokku
- #7608: @dragonhunt02 Add commands to proxy implementations for managing labels
### Refactors
- #8101: @josegonzalez Filter build docker-options correctly for each builder
### Documentation
- #8103: @josegonzalez Correct the release version for railpacks support
### Dependencies
- #8130: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 in /plugins/common
- #8110: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.76.0 to 1.77.0 in /tests/apps/gogrpc
- #8108: @dependabot[bot] chore(deps): bump js-yaml from 3.14.1 to 3.14.2 in /tests/apps/multi
- #8107: @dependabot[bot] chore(deps): bump click from 8.3.0 to 8.3.1 in /docs/_build
- #8098: @dependabot[bot] chore(deps): bump traefik from 3.5.4 to 3.6.1 in /plugins/traefik-vhosts
- #8097: @dependabot[bot] chore(deps): bump timberio/vector from 0.51.0-debian to 0.51.1-debian in /plugins/logs
- #8094: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.16.1 to 10.17.1 in /docs/_build
- #8092: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.23 to 9.7.0 in /docs/_build
- #8090: @dependabot[bot] chore(deps): bump sigs.k8s.io/kustomize/api from 0.20.1 to 0.21.0 in /plugins/scheduler-k3s
Node profiles can be used to specify repetitive options for clusters, making it easier to add specific types of instances quickly.
This PR additionally fixes kubelet-args specification - the same key can be specified multiple times, such as when specifying custom sysctl rules.
It can get repetitive to specify 'builder-' or 'scheduler-' prefixes for builder and scheduler commands. As these are mostly unique, Dokku now provides built-in aliases for the commands. Dokku still uses the long-form in all it's documentation, but these are a nice easter egg for determined users :)
Note that the null builder/scheduler plugins do not have aliases as they would shadow each other.
The jq binary doesn't support jsonc, so we can't modify it for testing purposes. Instead, just create an app.json with the correct heroku.postdeploy task.
During docker image generation, certain folders either do not exist or are symlinked in an odd fashion, causing the install trigger to fail. This is not the case at runtime, so we should defer the install trigger until container start and provide a method of skipping it when generating a docker image.
Closes#7308
We cannot grab a lock as cron:run with --detach will release the lock. Instead, just check if any containers for the specified cron_id are running and exit.
Without this, it is possible to keep an old build image around in the case of failed builds, and due to missing label support, the image will never be cleaned up.
# History
## 0.36.11
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.11/bootstrap.sh
sudo DOKKU_TAG=v0.36.11 bash bootstrap.sh
```
### Bug Fixes
- #8084: @josegonzalez Use the correct case for AS in Dockerfile
- #8083: @josegonzalez Use correct variable for tasks
- #8081: @josegonzalez Error out if the appname or app.json is missing when retrieving cron entries
### Refactors
- #8082: @josegonzalez Standardize naming in cron code
### Dependencies
- #8073: @dependabot[bot] chore(deps): bump timberio/vector from 0.50.0-debian to 0.51.0-debian in /plugins/logs
- #8080: @dependabot[bot] chore(deps): bump github.com/containerd/containerd from 1.7.28 to 1.7.29 in /plugins/scheduler-k3s
- #8079: @dependabot[bot] chore(deps): bump golang from 1.25.3 to 1.25.4 in /tests/apps/zombies-dockerfile-tini
- #8075: @dependabot[bot] chore(deps): bump golang from 1.25.3 to 1.25.4 in /tests/apps/go-fail-postdeploy
- #8078: @dependabot[bot] chore(deps): bump golang from 1.25.3 to 1.25.4 in /tests/apps/go-fail-predeploy
- #8077: @dependabot[bot] chore(deps): bump golang from 1.25.3 to 1.25.4 in /tests/apps/zombies-dockerfile-no-tini
- #8076: @dependabot[bot] chore(deps): bump golang from 1.25.3 to 1.25.4 in /tests/apps/gogrpc
- #8072: @dependabot[bot] chore(deps): update markdown requirement from <3.10,>=3.2.1 to >=3.2.1,<3.11 in /docs/_build
- #8074: @dependabot[bot] chore(deps): bump django from 5.2.7 to 5.2.8 in /tests/apps/dockerfile-release
- #8071: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.22 to 9.6.23 in /docs/_build
- #8068: @dependabot[bot] chore(deps): bump traefik from 3.5.3 to 3.5.4 in /plugins/traefik-vhosts
- #8069: @dependabot[bot] chore(deps): bump github.com/kedacore/keda/v2 from 2.18.0 to 2.18.1 in /plugins/scheduler-k3s
- #8066: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.29 to 2.11.30 in /plugins/scheduler-k3s
# History
## 0.36.10
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.10/bootstrap.sh
sudo DOKKU_TAG=v0.36.10 bash bootstrap.sh
```
### Bug Fixes
- #8063: @othercorey Use -t instead of deprecated --time in stop commands
- #8058: @josegonzalez Ensure the pre-receive hook and URLS files are correct when cloning or renaming apps
- #8059: @josegonzalez Expand variables for release tasks
- #8060: @josegonzalez Use updated http2 directive for setting http2 support
### Documentation
- #8051: @othercorey Fix "its" in Caddy SSL configuration documentation
### Dependencies
- #8065: @dependabot[bot] chore(deps): bump actions/upload-artifact from 4 to 5
- #8064: @dependabot[bot] chore(deps): bump actions/download-artifact from 5 to 6
- #8057: @dependabot[bot] chore(deps): bump node from 24-alpine to 25-alpine in /tests/apps/dockerfile-procfile-bad
- #8056: @dependabot[bot] chore(deps): bump node from 24-alpine to 25-alpine in /tests/apps/dockerfile-app-json-formations
- #8055: @dependabot[bot] chore(deps): bump node from 24-alpine to 25-alpine in /tests/apps/dockerfile-procfile
- #8054: @dependabot[bot] chore(deps): bump node from 24-alpine to 25-alpine in /tests/apps/dockerfile
- #8053: @dependabot[bot] chore(deps): bump node from 24-alpine to 25-alpine in /tests/apps/dockerfile-noexpose
Procfile commands need to be expanded with actual environment variables as procfile-util will otherwise empty them out. This doesn't happen for app.json scripts as they are never expanded until the docker container gets created.
Closes#8050
# History
## 0.36.9
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.9/bootstrap.sh
sudo DOKKU_TAG=v0.36.9 bash bootstrap.sh
```
### Bug Fixes
- #8032: @josegonzalez Set correct labels for tests/apps/dockerfile-release pip updates
### New Features
- #8047: @josegonzalez Add ability to disable letsencrypt for a given application or globally
### Dependencies
- #8049: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.19.0 to 1.19.1 in /plugins/scheduler-k3s
- #8048: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.21 to 9.6.22 in /docs/_build
- #8042: @dependabot[bot] chore(deps): bump django from 5.1.13 to 5.2.7 in /tests/apps/dockerfile-release
- #8043: @dependabot[bot] chore(deps): bump whitenoise from 6.2.0 to 6.11.0 in /tests/apps/dockerfile-release
- #8044: @dependabot[bot] chore(deps): bump djangorestframework from 3.15.2 to 3.16.1 in /tests/apps/dockerfile-release
- #8045: @dependabot[bot] chore(deps): bump psycopg2-binary from 2.9.5 to 2.9.11 in /tests/apps/dockerfile-release
- #8046: @dependabot[bot] chore(deps): bump dj-database-url from 1.0.0 to 3.0.1 in /tests/apps/dockerfile-release
- #8041: @dependabot[bot] chore(deps): bump golang from 1.25.2 to 1.25.3 in /tests/apps/gogrpc
- #8040: @dependabot[bot] chore(deps): bump golang from 1.25.2 to 1.25.3 in /tests/apps/go-fail-predeploy
- #8039: @dependabot[bot] chore(deps): bump golang from 1.25.2 to 1.25.3 in /tests/apps/zombies-dockerfile-no-tini
- #8037: @dependabot[bot] chore(deps): bump golang from 1.25.2 to 1.25.3 in /tests/apps/go-fail-postdeploy
- #8038: @dependabot[bot] chore(deps): bump golang from 1.25.2 to 1.25.3 in /tests/apps/zombies-dockerfile-tini
- #8036: @dependabot[bot] chore(deps): bump actions/setup-node from 5 to 6
- #8033: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.12.1 to 0.13.0 in /plugins/scheduler-k3s
- #8034: @dependabot[bot] chore(deps): bump github.com/kedacore/keda/v2 from 2.17.1-0.20250708210620-a239d2459a35 to 2.18.0 in /plugins/scheduler-k3s
# History
## 0.36.8
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.8/bootstrap.sh
sudo DOKKU_TAG=v0.36.8 bash bootstrap.sh
```
### Bug Fixes
- #8031: @josegonzalez Respect the k3s master node version when adding a new worker to the k3s cluster
- #7990: @josegonzalez Correct parsing of the --container-id flag for the enter command
### Documentation
- #8013: @othercorey Change command to add SSH key with sudo
- #7998: @bakatz Remove incorrect documentation about --envfile flag for config:export
### Dependencies
- #8028: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.42.0 to 0.43.0 in /plugins/common
- #8015: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.18.2 to 1.19.0 in /plugins/scheduler-k3s
- #8029: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.12.1 to 0.13.0 in /plugins/ps
- #8011: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.1 to 3.9.0 in /tests/apps/java
- #8012: @dependabot[bot] chore(deps): bump click from 8.1.8 to 8.3.0 in /docs/_build
- #8014: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.75.1 to 1.76.0 in /tests/apps/gogrpc
- #8018: @dependabot[bot] chore(deps): bump github/codeql-action from 3 to 4
- #8019: @dependabot[bot] chore(deps): bump golang from 1.25.1 to 1.25.2 in /tests/apps/zombies-dockerfile-no-tini
- #8020: @dependabot[bot] chore(deps): bump golang from 1.25.1 to 1.25.2 in /tests/apps/go-fail-predeploy
- #8021: @dependabot[bot] chore(deps): bump python from 3.13.7-bookworm to 3.14.0-bookworm in /tests/apps/dockerfile-release
- #8022: @dependabot[bot] chore(deps): bump golang from 1.25.1 to 1.25.2 in /tests/apps/gogrpc
- #8024: @dependabot[bot] chore(deps): bump golang from 1.25.1 to 1.25.2 in /tests/apps/zombies-dockerfile-tini
- #8023: @dependabot[bot] chore(deps): bump golang from 1.25.1 to 1.25.2 in /tests/apps/go-fail-postdeploy
- #8025: @dependabot[bot] chore(deps): bump python from 3.13.7-alpine to 3.14.0-alpine in /docs/_build
- #8026: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.22.0 to 1.23.0 in /plugins/scheduler-k3s
- #8027: @dependabot[bot] chore(deps): bump ruby from 3.4.6 to 3.4.7 in /tests/apps/dockerfile-entrypoint
- #8030: @dependabot[bot] chore(deps): bump rack from 2.2.19 to 2.2.20 in /tests/apps/ruby
- #8016: @dependabot[bot] chore(deps): bump rack from 2.2.18 to 2.2.19 in /tests/apps/ruby
- #8009: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.9 to 1.36.10 in /tests/apps/gogrpc
- #7994: @dependabot[bot] chore(deps): bump timberio/vector from 0.49.0-debian to 0.50.0-debian in /plugins/logs
- #8006: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.20 to 9.6.21 in /docs/_build
- #8003: @dependabot[bot] chore(deps): bump traefik from 3.5.2 to 3.5.3 in /plugins/traefik-vhosts
- #7996: @dependabot[bot] chore(deps): bump pyyaml from 6.0.2 to 6.0.3 in /docs/_build
- #8000: @dependabot[bot] chore(deps): bump markupsafe from 3.0.2 to 3.0.3 in /docs/_build
- #8001: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.13.5 to 4.14.2 in /docs/_build
- #8002: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.22.0 to 0.22.1 in /plugins/scheduler-k3s
- #7995: @dependabot[bot] chore(deps): bump rack from 2.2.17 to 2.2.18 in /tests/apps/ruby
- #7992: @dependabot[bot] chore(deps): bump hadolint/hadolint-action from 3.2.0 to 3.3.0
- #7993: @dependabot[bot] chore(deps): bump pyparsing from 3.2.4 to 3.2.5 in /docs/_build
- #7987: @dependabot[bot] chore(deps): bump ruby from 3.4.5 to 3.4.6 in /tests/apps/dockerfile-entrypoint
- #7983: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.34.0 to 1.34.1 in /plugins/scheduler-k3s
- #7984: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.19 to 9.6.20 in /docs/_build
- #7985: @dependabot[bot] chore(deps): bump pyparsing from 3.2.3 to 3.2.4 in /docs/_build
### Other
- #8008: @dependabot[bot] chore(deps): bump django from 5.1.12 to 5.1.13 in /tests/apps/dockerfile-release
Previously, it was possible to have a kubernetes version mismatch on new worker nodes if a newer version of kubernetes was released prior to upgrading the master nodes to that version. This can sometimes cause cluster instability.
This change fetches the lowest node version associated with a master node and then uses that to install k3s on the worker node.
# History
## 0.36.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.7/bootstrap.sh
sudo DOKKU_TAG=v0.36.7 bash bootstrap.sh
```
### Bug Fixes
- #7981: @josegonzalez Only install software-properties-common on Ubuntu and older Debian installations
- #7979: @josegonzalez Skip invalid apps when listing applications
- #7977: @kminek Remove server_tokens directive from main nginx config if present (com…
- #7974: @josegonzalez Ensure lsb_release is available on debian systems
### New Features
- #7978: @josegonzalez Add ability to list global cron tasks
- #7975: @josegonzalez Create SecurityContext for k3s scheduler from docker-options
### Dependencies
- #7972: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.34.0 to 0.34.1 in /plugins/scheduler-k3s
- #7973: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.18.6 to 3.19.0 in /plugins/scheduler-k3s
- #7971: @dependabot[bot] chore(deps): bump k8s.io/client-go from 0.34.0 to 0.34.1 in /plugins/scheduler-k3s
- #7970: @dependabot[bot] chore(deps): bump k8s.io/api from 0.34.0 to 0.34.1 in /plugins/scheduler-k3s
- #7966: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.19.0 to 1.22.0 in /plugins/scheduler-k3s
- #7963: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.75.0 to 1.75.1 in /tests/apps/gogrpc
- #7964: @dependabot[bot] chore(deps): bump traefik from 3.5.1 to 3.5.2 in /plugins/traefik-vhosts
- #7965: @dependabot[bot] chore(deps): bump k8s.io/apimachinery from 0.34.0 to 0.34.1 in /plugins/scheduler-k3s
- #7961: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.41.0 to 0.42.0 in /plugins/common
- #7960: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.8 to 1.36.9 in /tests/apps/gogrpc
### Other
- #7968: @josegonzalez chore: bump herokuish version from 0.11.0 to 0.11.3
- #7962: @dependabot[bot] chore(deps): bump django from 5.1.10 to 5.1.12 in /tests/apps/dockerfile-release
The previous method ended up validating the app name when checking if the app was deployed or not, which isn't necessary as that should only be performed at the command-level.
# History
## 0.36.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.6/bootstrap.sh
sudo DOKKU_TAG=v0.36.6 bash bootstrap.sh
```
### Bug Fixes
- #7955: @josegonzalez Ensure that the nixpacks bin is installed in /usr/bin/nixpacks in Docker image
- #7953: @josegonzalez Set correct label for nixpacks builder
- #7942: @josegonzalez Ensure the code is copied over to the new app on clone or rebase
- #7941: @josegonzalez Do not generate an https url when there is no SSL certificate
- #7940: @josegonzalez Silence openresty extract warnings during the deploy process
### Tests
- #7954: @josegonzalez Respect DOKKU_DOMAIN when deploying in tests
- #7943: @josegonzalez Remove unused test app
- #7939: @josegonzalez Add test for ensuring run commands work with pack-based builds
### Dependencies
- #7958: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.18.5 to 3.18.6 in /plugins/scheduler-k3s
- #7952: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.16.0 to 0.17.0 in /plugins/common
- #7951: @dependabot[bot] chore(deps): bump golang from 1.25.0 to 1.25.1 in /tests/apps/gogrpc
- #7950: @dependabot[bot] chore(deps): bump golang from 1.25.0 to 1.25.1 in /tests/apps/go-fail-postdeploy
- #7949: @dependabot[bot] chore(deps): bump golang from 1.25.0 to 1.25.1 in /tests/apps/zombies-dockerfile-no-tini
- #7947: @dependabot[bot] chore(deps): bump golang from 1.25.0 to 1.25.1 in /tests/apps/zombies-dockerfile-tini
- #7945: @dependabot[bot] chore(deps): bump golang from 1.25.0 to 1.25.1 in /tests/apps/go-fail-predeploy
- #7946: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.18 to 9.6.19 in /docs/_build
# History
## 0.36.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.5/bootstrap.sh
sudo DOKKU_TAG=v0.36.5 bash bootstrap.sh
```
### New Features
- #7937: @josegonzalez Add support for Debian Trixie
# History
## 0.36.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.4/bootstrap.sh
sudo DOKKU_TAG=v0.36.4 bash bootstrap.sh
```
### Bug Fixes
- #7914: @josegonzalez Fix nginx configuration building in k3s scheduler
### Dependencies
- #7935: @dependabot[bot] chore(deps): update markdown requirement from <3.9,>=3.2.1 to >=3.2.1,<3.10 in /docs/_build
- #7936: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.21.2 to 0.22.0 in /plugins/scheduler-k3s
- #7931: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.28 to 2.11.29 in /plugins/scheduler-k3s
- #7932: @dependabot[bot] chore(deps): bump actions/setup-python from 5 to 6
- #7933: @dependabot[bot] chore(deps): bump actions/setup-node from 4 to 5
- #7934: @dependabot[bot] chore(deps): bump hadolint/hadolint-action from 3.1.0 to 3.2.0
- #7920: @dependabot[bot] chore(deps): bump github.com/spf13/pflag from 1.0.9 to 1.0.10 in /plugins/common
- #7887: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.38.0 to 1.38.2 in /plugins/common
- #7847: @dependabot[bot] chore(deps): bump timberio/vector from 0.48.0-debian to 0.49.0-debian in /plugins/logs
- #7890: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.33.2 to 1.34.0 in /plugins/scheduler-k3s
- #7881: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 4.5.0 to 4.6.0 in /plugins/haproxy-vhosts
- #7880: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.13.4 to 4.13.5 in /docs/_build
- #7888: @dependabot[bot] chore(deps): bump soupsieve from 2.7 to 2.8 in /docs/_build
- #7902: @dependabot[bot] chore(deps): bump github.com/spf13/pflag from 1.0.7 to 1.0.9 in /plugins/common
- #7891: @dependabot[bot] chore(deps): bump k8s.io/kubectl from 0.33.3 to 0.34.0 in /plugins/scheduler-k3s
- #7895: @dependabot[bot] chore(deps): bump traefik from 3.5.0 to 3.5.1 in /plugins/traefik-vhosts
These shadow existing values managed by k3s itself, causing issues where the same header is injected with multiple values, which some frameworks do not support as they use the header directly without parsing to construct urls.
# History
## 0.36.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.3/bootstrap.sh
sudo DOKKU_TAG=v0.36.3 bash bootstrap.sh
```
### New Features
- #7878: @josegonzalez Allow specifying base64-encoded values in vector-sink DSN urls
### Dependencies
- #7873: @dependabot[bot] chore(deps): bump github.com/go-openapi/jsonpointer from 0.21.1 to 0.21.2 in /plugins/scheduler-k3s
- #7874: @dependabot[bot] chore(deps): bump k8s.io/api from 0.33.3 to 0.33.4 in /plugins/scheduler-k3s
- #7875: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.17 to 9.6.18 in /docs/_build
# History
## 0.36.2
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.2/bootstrap.sh
sudo DOKKU_TAG=v0.36.2 bash bootstrap.sh
```
### Bug Fixes
- #7872: @josegonzalez Correct issues when scaling non-web processes for the scheduler-k3s plugin
### Refactors
- #7871: @josegonzalez Remove public exposure of DOKKU_APP_TYPE in favor of builder detected property
### Dependencies
- #7868: @dependabot[bot] chore(deps): bump grunt-cli from 1.4.3 to 1.5.0 in /tests/apps/multi
- #7869: @dependabot[bot] chore(deps): bump bower from 1.8.12 to 1.8.14 in /tests/apps/multi
- #7870: @dependabot[bot] chore(deps): bump tmp from 0.2.4 to 0.2.5 in /tests/apps/multi
- #7867: @dependabot[bot] chore(deps): bump grunt from 1.5.3 to 1.6.1 in /tests/apps/multi
- #7866: @dependabot[bot] chore(deps): bump github.com/fluxcd/pkg/kustomize from 1.18.0 to 1.19.0 in /plugins/scheduler-k3s
- #7862: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.7 to 1.36.8 in /tests/apps/gogrpc
### Other
- #7864: @josegonzalez chore(deps): add dependabot entries for plugins/scheduler-k3s and tests/apps/multi
The DOKKU_APP_TYPE has long since ceased to be the correct way to specify the builder for the application. It's only usage has been during the detection phase, specifically to ensure that the herokuish plugin injects the correct docker arguments during the build. As such, it is safe to migrate away to a property in a patch release.
Users that seek to set a specific builder should use 'dokku builder:set $APP selected' instead.
Refs #7863
# History
## 0.36.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.1/bootstrap.sh
sudo DOKKU_TAG=v0.36.1 bash bootstrap.sh
```
### Bug Fixes
- #7846: @josegonzalez Correct issue in parsing escaped plus signs in vector sink values
- #7841: @leksyib14 Fix handling of equals sign in vector sink values
- #7844: @josegonzalez Do not change permissions on config directory symlinks
### Tests
- #7848: @josegonzalez Ensure tests properly fetch data from json output
- #7845: @josegonzalez Use the official github actions arm64 runner
### Dependencies
- #7861: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.74.2 to 1.75.0 in /tests/apps/gogrpc
- #7860: @dependabot[bot] chore(deps): bump flask from 3.1.1 to 3.1.2 in /tests/apps/python-flask
- #7859: @dependabot[bot] chore(deps): bump flask from 3.1.1 to 3.1.2 in /tests/apps/multi
- #7856: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.16 to 9.6.17 in /docs/_build
- #7857: @dependabot[bot] chore(deps): bump python from 3.13.6-alpine to 3.13.7-alpine in /docs/_build
- #7858: @dependabot[bot] chore(deps): bump python from 3.13.6-bookworm to 3.13.7-bookworm in /tests/apps/dockerfile-release
- #7855: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.25 to 11.0.26 in /tests/apps/java
- #7849: @dependabot[bot] chore(deps): bump golang from 1.24.6 to 1.25.0 in /tests/apps/zombies-dockerfile-tini
- #7850: @dependabot[bot] chore(deps): bump golang from 1.24.6 to 1.25.0 in /tests/apps/go-fail-predeploy
- #7851: @dependabot[bot] chore(deps): bump golang from 1.24.6 to 1.25.0 in /tests/apps/go-fail-postdeploy
- #7852: @dependabot[bot] chore(deps): bump golang from 1.24.6 to 1.25.0 in /tests/apps/gogrpc
- #7853: @dependabot[bot] chore(deps): bump golang from 1.24.6 to 1.25.0 in /tests/apps/zombies-dockerfile-no-tini
- #7842: @dependabot[bot] chore(deps): bump actions/checkout from 4 to 5
- #7821: @dependabot[bot] chore(deps): bump traefik from 3.4.4 to 3.5.0 in /plugins/traefik-vhosts
- #7843: @josegonzalez Bump go modules
- #7824: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.15 to 9.6.16 in /docs/_build
- #7823: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.16 to 10.16.1 in /docs/_build
- #7831: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.6 to 1.36.7 in /tests/apps/gogrpc
- #7839: @dependabot[bot] chore(deps): bump python from 3.13.5-bookworm to 3.13.6-bookworm in /tests/apps/dockerfile-release
- #7838: @dependabot[bot] chore(deps): bump python from 3.13.5-alpine to 3.13.6-alpine in /docs/_build
- #7837: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.40.0 to 0.41.0 in /plugins/common
- #7836: @dependabot[bot] chore(deps): bump golang from 1.24.5 to 1.24.6 in /tests/apps/zombies-dockerfile-tini
- #7835: @dependabot[bot] chore(deps): bump golang from 1.24.5 to 1.24.6 in /tests/apps/zombies-dockerfile-no-tini
- #7834: @dependabot[bot] chore(deps): bump golang from 1.24.5 to 1.24.6 in /tests/apps/go-fail-postdeploy
- #7833: @dependabot[bot] chore(deps): bump golang from 1.24.5 to 1.24.6 in /tests/apps/gogrpc
- #7832: @dependabot[bot] chore(deps): bump golang from 1.24.5 to 1.24.6 in /tests/apps/go-fail-predeploy
- #7828: @dependabot[bot] chore(deps): bump actions/download-artifact from 4 to 5
### Other
- #7854: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.18.4 to 3.18.5 in /plugins/scheduler-k3s
- #7825: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.26 to 2.11.28 in /plugins/scheduler-k3s
- #7830: @dependabot[bot] chore(deps): bump tmp from 0.2.1 to 0.2.4 in /tests/apps/multi
- #7829: @dependabot[bot] chore(deps): bump github.com/go-acme/lego/v4 from 4.24.0 to 4.25.2 in /plugins/scheduler-k3s
# History
## 0.36.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.36.0/bootstrap.sh
sudo DOKKU_TAG=v0.36.0 bash bootstrap.sh
```
See the [0.36.0 migration guide](/docs/appendices/0.36.0-migration-guide.md) for more information on migrating to 0.36.0.
This standardizes the extraction code and makes it easier to reuse in future implementations of file extraction.
Additionally, this adds a way to extract folders from codebases.
- Replace boolean return values with proper error handling in dockerTag and dockerPush functions
- Add detailed error context including Docker command exit codes and stderr output
- Remove TODO comments and improve error messages for better debugging
- Fix error message formatting in defer function
This addresses the TODO comments for better error handling and provides
users with actionable error information when Docker registry operations fail.
Closes: #XXXX
Rather than redeploy every formation, only deploy formations that have had their values changed from the defaults.
This still doesn't handle the case where we touch existing processes when scaling _up_, but should decrease the number of services touched otherwise during scaling.
Also note that there are no tests for this new behavior yet (tests incoming).
Refs #7396
Without this, we try to write the config for the app even though it doesn't exist anymore, causing issues with deleting apps with invalid cron configs.
# History
## 0.35.20
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.20/bootstrap.sh
sudo DOKKU_TAG=v0.35.20 bash bootstrap.sh
```
### Bug Fixes
- #7726: @josegonzalez Ensure compose projects are spawned from the /tmp directory
- #7725: @josegonzalez Uninstall hashicorp tap to fix formula releases
### Dependencies
- #7735: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.72.2 to 1.73.0 in /tests/apps/gogrpc
- #7737: @dependabot[bot] chore(deps): bump python from 3.13.3-alpine to 3.13.4-alpine in /docs/_build
- #7738: @dependabot[bot] chore(deps): bump python from 3.13.3-bookworm to 3.13.4-bookworm in /tests/apps/dockerfile-release
- #7745: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.38.0 to 0.39.0 in /plugins/common
- #7740: @dependabot[bot] chore(deps): bump golang from 1.24.3 to 1.24.4 in /tests/apps/gogrpc
- #7741: @dependabot[bot] chore(deps): bump golang from 1.24.3 to 1.24.4 in /tests/apps/go-fail-postdeploy
- #7742: @dependabot[bot] chore(deps): bump golang from 1.24.3 to 1.24.4 in /tests/apps/zombies-dockerfile-tini
- #7743: @dependabot[bot] chore(deps): bump golang from 1.24.3 to 1.24.4 in /tests/apps/go-fail-predeploy
- #7744: @dependabot[bot] chore(deps): bump golang from 1.24.3 to 1.24.4 in /tests/apps/zombies-dockerfile-no-tini
- #7730: @dependabot[bot] chore(deps): bump traefik from 3.4.0 to 3.4.1 in /plugins/traefik-vhosts
- #7729: @dependabot[bot] chore(deps): bump zipp from 3.21.0 to 3.22.0 in /docs/_build
- #7727: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.72.1 to 1.72.2 in /tests/apps/gogrpc
### Other
- #7746: @dependabot[bot] chore(deps): bump django from 5.0.14 to 5.1.10 in /tests/apps/dockerfile-release
- #7731: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.24 to 2.11.25 in /plugins/scheduler-k3s
A recent update to compose executes a stat call in the current working directory, which may have incorrect permissions for execution once the user is changed to the dokku user. This change forces all compose commands to execute in the /tmp directory by using a helper function to execute compose up/down.
Closes#7705
# History
## 0.35.19
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.19/bootstrap.sh
sudo DOKKU_TAG=v0.35.19 bash bootstrap.sh
```
### Bug Fixes
- #7686: @josegonzalez Untap aws/tap to correct issues in formula release
### Documentation
- #7707: @swrobel Remove duplicate hostname plugin
- #7687: @d9i Fix cron key in app.json docs
- #7677: @plafue Add continuous integration example for woodpecker ci
### Tests
- #7585: @josegonzalez Add test to prove Dokku respects the Procfile when deploying from an image
- #7678: @josegonzalez Revert "fix: update CID count in ps tests"
### Dependencies
- #7692: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.37.0 to 0.38.0 in /plugins/common
- #7626: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/dockerfile
- #7693: @dependabot[bot] chore(deps): bump traefik from 3.3.5 to 3.4.0 in /plugins/traefik-vhosts
- #7694: @dependabot[bot] chore(deps): bump golang from 1.24.2 to 1.24.3 in /tests/apps/go-fail-postdeploy
- #7695: @dependabot[bot] chore(deps): bump node from 23-alpine to 24-alpine in /tests/apps/dockerfile-procfile-bad
- #7696: @dependabot[bot] chore(deps): bump golang from 1.24.2 to 1.24.3 in /tests/apps/gogrpc
- #7697: @dependabot[bot] chore(deps): bump golang from 1.24.2 to 1.24.3 in /tests/apps/go-fail-predeploy
- #7698: @dependabot[bot] chore(deps): bump node from 23-alpine to 24-alpine in /tests/apps/dockerfile-procfile
- #7699: @dependabot[bot] chore(deps): bump golang from 1.24.2 to 1.24.3 in /tests/apps/zombies-dockerfile-no-tini
- #7700: @dependabot[bot] chore(deps): bump golang from 1.24.2 to 1.24.3 in /tests/apps/zombies-dockerfile-tini
- #7701: @dependabot[bot] chore(deps): bump node from 23-alpine to 24-alpine in /tests/apps/dockerfile
- #7702: @dependabot[bot] chore(deps): bump node from 23-alpine to 24-alpine in /tests/apps/dockerfile-app-json-formations
- #7704: @dependabot[bot] chore(deps): bump rack from 2.2.13 to 2.2.14 in /tests/apps/ruby
- #7711: @dependabot[bot] chore(deps): bump flask from 3.1.0 to 3.1.1 in /tests/apps/multi
- #7712: @dependabot[bot] chore(deps): bump flask from 3.1.0 to 3.1.1 in /tests/apps/python-flask
- #7713: @dependabot[bot] chore(deps): bump pyyaml-env-tag from 0.1 to 1.1 in /docs/_build
- #7714: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.12 to 9.6.14 in /docs/_build
- #7715: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.72.0 to 1.72.1 in /tests/apps/gogrpc
- #7716: @dependabot[bot] chore(deps): bump ruby from 3.4.3 to 3.4.4 in /tests/apps/dockerfile-entrypoint
- #7718: @dependabot[bot] chore(deps): bump timberio/vector from 0.46.1-debian to 0.47.0-debian in /plugins/logs
- #7703: @dependabot[bot] chore(deps): bump node from 23-alpine to 24-alpine in /tests/apps/dockerfile-noexpose
- #7688: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.14.3 to 10.15 in /docs/_build
- #7689: @dependabot[bot] chore(deps): bump importlib-metadata from 8.6.1 to 8.7.0 in /docs/_build
- #7671: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 in /tests/apps/gogrpc
- #7681: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.71.1 to 1.72.0 in /tests/apps/gogrpc
- #7680: @dependabot[bot] chore(deps): bump soupsieve from 2.6 to 2.7 in /docs/_build
- #7682: @dependabot[bot] chore(deps): bump packaging from 24.2 to 25.0 in /docs/_build
- #7673: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 in /plugins/common
- #7675: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 4.4.0 to 4.5.0 in /plugins/haproxy-vhosts
- #7676: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.11 to 9.6.12 in /docs/_build
### Other
- #7723: @josegonzalez Revert "chore(deps): bump helm.sh/helm/v3 from 3.14.2 to 3.17.3 in /plugins/scheduler-k3s"
- #7645: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.14.2 to 3.17.3 in /plugins/scheduler-k3s
- #7717: @dependabot[bot] chore(deps): bump setuptools from 70.0.0 to 78.1.1 in /tests/apps/dockerfile-release
- #7719: @d1ceward Fix: Add missing `systemctl` path detection in nginx-vhost plugin
- #7679: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.15 to 2.11.24 in /plugins/scheduler-k3s
# History
## 0.35.18
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.18/bootstrap.sh
sudo DOKKU_TAG=v0.35.18 bash bootstrap.sh
```
### Bug Fixes
- #7669: @josegonzalez fix: update CID count in ps tests
### Dependencies
- #7668: @dependabot[bot] chore(deps): bump timberio/vector from 0.43.1-debian to 0.46.1-debian in /plugins/logs
- #7670: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.13.3 to 4.13.4 in /docs/_build
- #7630: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/gitsubmodules
- #7666: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.36.0 to 0.37.0 in /plugins/common
- #7618: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/.websocket.disabled
- #7620: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/dockerfile-procfile-bad
- #7622: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/dockerfile-procfile
- #7629: @dependabot[bot] chore(deps): bump express from 5.0.1 to 5.1.0 in /tests/apps/checks-root
- #7623: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/dockerfile-noexpose
- #7627: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/nodejs-express-noprocfile
- #7631: @dependabot[bot] chore(deps): bump express from 4.21.2 to 5.1.0 in /tests/apps/dockerfile-app-json-formations
- #7667: @dependabot[bot] chore(deps): bump ruby from 3.4.2 to 3.4.3 in /tests/apps/dockerfile-entrypoint
### Other
- #7661: @josegonzalez chore: bump dokku-event-listener from 0.17.0 to 0.17.2
- #7660: @josegonzalez chore: bump plugn from 0.15.3 to 0.16.0
- #7659: @josegonzalez chore: bump gliderlabs-sigil from 0.11.0 to 0.11.4
- #7656: @josegonzalez chore: bump netrc from 0.10.0 to 0.10.2
- #7655: @josegonzalez chore: bump lambda-builder from 0.8.0 to 0.9.1
- #7663: @josegonzalez chore: bump herokuish from 0.10.2 to 0.10.3
- #7662: @josegonzalez chore: bump dokku-update from 0.9.4 to 0.9.6
- #7658: @josegonzalez chore: bump sshcommand from 0.19.0 to 0.20.0
- #7657: @josegonzalez chore: bump procfile-util from 0.19.0 to 0.20.3
- #7654: @josegonzalez chore: bump docker-image-builder from 0.8.0 to 0.8.1
- #7653: @josegonzalez chore: bump docker-container-healthchecker from 0.11.0 to 0.11.5
# History
## 0.35.17
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.17/bootstrap.sh
sudo DOKKU_TAG=v0.35.17 bash bootstrap.sh
```
### Bug Fixes
- #7606: @josegonzalez fix: bump dokku version in main.bicep when bumping azure versions
- #7650: @josegonzalez fix: set the correct default ingress class for k3s clusters
- #7649: @josegonzalez fix: decrease default in-use keda resources
- #7587: @turicas Correctly name paketo chown option
- #7584: @josegonzalez Install all builder binaries in Dokku docker image
- #7580: @josegonzalez Do not set network flag when building dockerfile images
- #7575: @josegonzalez Restore the git head ref when running repo:gc
- #7574: @josegonzalez fix: do not write VHOST file if the DOKKU_ROOT directory does not exist
### New Features
- #7648: @josegonzalez feat: add ability to ship k3s container logs via vector
- #7581: @josegonzalez Allow --volume flags to be passed to pack at buildtime
- #7583: @josegonzalez Send Host header when running container checks in docker-local
- #7572: @josegonzalez Add support for setting shm-size for kubernetes deployments
### Documentation
- #7652: @josegonzalez docs: use a cid-file in the plugin example
- #7647: @closeobserve Fix some golang docblock comments
- #7586: @turicas Remove `--` from `--git-url` in plugin installation docs
### Dependencies
- #7603: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.24 to 11.0.25 in /tests/apps/java
- #7641: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.12.0 to 0.13.0 in /plugins/scheduler-docker-local
- #7639: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.36.2 to 1.37.0 in /plugins/common
- #7646: @dependabot[bot] chore(deps): bump phusion/baseimage from noble-1.0.0 to noble-1.0.2
- #7610: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.5 to 1.36.6 in /tests/apps/gogrpc
- #7619: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.71.0 to 1.71.1 in /tests/apps/gogrpc
- #7624: @dependabot[bot] chore(deps): bump traefik from 3.3.4 to 3.3.5 in /plugins/traefik-vhosts
- #7632: @dependabot[bot] chore(deps): bump golang from 1.24.1 to 1.24.2 in /tests/apps/go-fail-postdeploy
- #7633: @dependabot[bot] chore(deps): bump golang from 1.24.1 to 1.24.2 in /tests/apps/zombies-dockerfile-tini
- #7634: @dependabot[bot] chore(deps): bump golang from 1.24.1 to 1.24.2 in /tests/apps/go-fail-predeploy
- #7643: @dependabot[bot] chore(deps): bump python from 3.13.2-bookworm to 3.13.3-bookworm in /tests/apps/dockerfile-release
- #7635: @dependabot[bot] chore(deps): bump golang from 1.24.1 to 1.24.2 in /tests/apps/gogrpc
- #7636: @dependabot[bot] chore(deps): bump golang from 1.24.1 to 1.24.2 in /tests/apps/zombies-dockerfile-no-tini
- #7613: @dependabot[bot] chore(deps): bump pyparsing from 3.2.1 to 3.2.3 in /docs/_build
- #7625: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.8 to 9.6.11 in /docs/_build
- #7644: @dependabot[bot] chore(deps): bump python from 3.13.2-alpine to 3.13.3-alpine in /docs/_build
- #7651: @dependabot[bot] chore(deps): update markdown requirement from <3.8,>=3.2.1 to >=3.2.1,<3.9 in /docs/_build
- #7595: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.7 to 45.0.8
- #7593: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.7 to 9.6.8 in /docs/_build
- #7589: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.34.0 to 0.36.0 in /tests/apps/gogrpc
- #7588: @dependabot[bot] chore(deps): bump rack from 2.2.12 to 2.2.13 in /tests/apps/ruby
- #7570: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.10.0 to 3.11.0 in /plugins/cron
- #7569: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.35.0 to 0.36.0 in /plugins/common
- #7568: @dependabot[bot] chore(deps): bump jinja2 from 3.1.5 to 3.1.6 in /docs/_build
### Other
- #7601: @dependabot[bot] chore(deps): bump github.com/expr-lang/expr from 1.15.8 to 1.17.0 in /plugins/scheduler-k3s
- #7602: @dependabot[bot] chore(deps): bump github.com/containerd/containerd from 1.7.20 to 1.7.27 in /plugins/scheduler-k3s
- #7637: @dependabot[bot] chore(deps): bump django from 5.0.13 to 5.0.14 in /tests/apps/dockerfile-release
- #7607: @dependabot[bot] chore(deps): bump gunicorn from 22.0.0 to 23.0.0 in /tests/apps/dockerfile-release
- #7596: @josegonzalez Drop compromisde tj-actions/changed-files from Ci
- #7582: @josegonzalez Add ability to disable vhosts for all apps
- #7576: @josegonzalez fix: properly handle NoAppsExist in network:rebuild-all and buildpacks:set
- #7571: @dependabot[bot] chore(deps): bump django from 5.0.11 to 5.0.13 in /tests/apps/dockerfile-release
Keda isn't in use by everyone, yet commands significant resources. This change makes it so a 2GB server is enough to run Dokku and a couple of small apps.
If a global vector-sink property on the logs plugin is set, we will use that to configure a log sink (defaulting to console output otherwise). Note that the actual configuration still needs to be a valid DSN representing a Vector log sink.
While this does not support pinning log sinks to specific apps, it opens up integration for those who use a single k3s cluster in shared tenancy.
I've manually audited our usage and it doesn't look like credentials were printed anywhere, but before they do for another PR, just remove the usage.
If this ends up failing CI, thats also fine, I'll just remove packer validation and manually run it if that file changes.
When git --aggressive is run on a bare repo, it deletes all head refs. This change copies the contents into memory and then writes them out at the end of the repo:gc call.
Closes#6973
# History
## 0.35.16
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.16/bootstrap.sh
sudo DOKKU_TAG=v0.35.16 bash bootstrap.sh
```
### Bug Fixes
- #7502: @josegonzalez Ensure all report subcommands exit 0 when there is no app
### New Features
- #7545: @josegonzalez feat: delegate authorized_keys file validation to sshcommand
### Documentation
- #7547: @creature Fix display of numbered list in troubleshooting docs
- #7542: @creature Include troubleshooting details about app A being served when app B was expected due to in-app SSL redirects
- #7530: @josegonzalez Finish sentence in docker-options documentation
- #7527: @2x2xplz Add swapoff to commands when creating or updating swap space
- #7526: @ebuckthal Update vector container volume mount description
### Dependencies
- #7565: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.11.0 to 0.12.0 in /plugins/common
- #7566: @dependabot[bot] chore(deps): bump rack from 2.2.11 to 2.2.12 in /tests/apps/ruby
- #7567: @dependabot[bot] chore(deps): bump jinja2 from 3.1.5 to 3.1.6 in /tests/apps/python-flask
- #7563: @dependabot[bot] chore(deps): bump golang from 1.24.0 to 1.24.1 in /tests/apps/zombies-dockerfile-tini
- #7561: @dependabot[bot] chore(deps): bump golang from 1.24.0 to 1.24.1 in /tests/apps/gogrpc
- #7558: @dependabot[bot] chore(deps): bump golang from 1.24.0 to 1.24.1 in /tests/apps/zombies-dockerfile-no-tini
- #7562: @dependabot[bot] chore(deps): bump golang from 1.24.0 to 1.24.1 in /tests/apps/go-fail-predeploy
- #7555: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.5 to 9.6.7 in /docs/_build
- #7564: @dependabot[bot] chore(deps): bump golang from 1.24.0 to 1.24.1 in /tests/apps/go-fail-postdeploy
- #7560: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.11.0 to 0.12.0 in /plugins/scheduler-docker-local
- #7559: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.70.0 to 1.71.0 in /tests/apps/gogrpc
- #7553: @dependabot[bot] chore(deps): bump traefik from 3.3.3 to 3.3.4 in /plugins/traefik-vhosts
- #7551: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.33.0 to 0.35.0 in /plugins/common
- #7550: @dependabot[bot] chore(deps): bump github.com/go-jose/go-jose/v4 from 4.0.4 to 4.0.5 in /plugins/scheduler-k3s
- #7548: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.9.2 to 0.9.3 in /plugins/openresty-vhosts
- #7541: @dependabot[bot] chore(deps): bump ruby from 3.4.1 to 3.4.2 in /tests/apps/dockerfile-entrypoint
- #7537: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.29.7 to 1.29.14 in /plugins/scheduler-k3s
- #7536: @dependabot[bot] chore(deps): bump golang from 1.23.6 to 1.24.0 in /tests/apps/zombies-dockerfile-no-tini
- #7535: @dependabot[bot] chore(deps): bump golang from 1.23.6 to 1.24.0 in /tests/apps/zombies-dockerfile-tini
- #7534: @dependabot[bot] chore(deps): bump golang from 1.23.6 to 1.24.0 in /tests/apps/go-fail-predeploy
- #7533: @dependabot[bot] chore(deps): bump golang from 1.23.6 to 1.24.0 in /tests/apps/go-fail-postdeploy
- #7532: @dependabot[bot] chore(deps): bump golang from 1.23.6 to 1.24.0 in /tests/apps/gogrpc
- #7531: @dependabot[bot] chore(deps): bump rack from 2.2.8.1 to 2.2.11 in /tests/apps/ruby
- #7525: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.32.0 to 0.33.0 in /plugins/common
- #7543: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.4 to 9.6.5 in /docs/_build
- #7512: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.10.0 to 0.11.0 in /plugins/common
- #7513: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.6 to 45.0.7
- #7514: @dependabot[bot] chore(deps): bump golang from 1.23.5 to 1.23.6 in /tests/apps/gogrpc
- #7515: @dependabot[bot] chore(deps): bump golang from 1.23.5 to 1.23.6 in /tests/apps/go-fail-predeploy
- #7516: @dependabot[bot] chore(deps): bump golang from 1.23.5 to 1.23.6 in /tests/apps/go-fail-postdeploy
- #7517: @dependabot[bot] chore(deps): bump golang from 1.23.5 to 1.23.6 in /tests/apps/zombies-dockerfile-tini
- #7518: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.13.1 to 4.13.3 in /docs/_build
- #7519: @dependabot[bot] chore(deps): bump golang from 1.23.5 to 1.23.6 in /tests/apps/zombies-dockerfile-no-tini
- #7521: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.4 to 1.36.5 in /tests/apps/gogrpc
- #7522: @dependabot[bot] chore(deps): bump python from 3.13.1-bookworm to 3.13.2-bookworm in /tests/apps/dockerfile-release
- #7523: @dependabot[bot] chore(deps): bump python from 3.13.1-alpine to 3.13.2-alpine in /docs/_build
- #7528: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.2 to 9.6.4 in /docs/_build
- #7510: @dependabot[bot] chore(deps): bump mkdocs-material from 9.6.1 to 9.6.2 in /docs/_build
- #7507: @dependabot[bot] chore(deps): bump traefik from 3.3.2 to 3.3.3 in /plugins/traefik-vhosts
- #7505: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.14.2 to 10.14.3 in /docs/_build
- #7506: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.12.3 to 4.13.1 in /docs/_build
- #7508: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.9.1 to 0.9.2 in /plugins/openresty-vhosts
- #7482: @dependabot[bot] chore(deps): bump github.com/spf13/pflag from 1.0.5 to 1.0.6 in /plugins/common
- #7500: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.30.0 to 0.33.0 in /tests/apps/gogrpc
- #7501: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.14 to 2.11.15 in /plugins/scheduler-k3s
- #7497: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.49 to 9.6.1 in /docs/_build
- #7479: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.14 to 10.14.2 in /docs/_build
- #7477: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.69.4 to 1.70.0 in /tests/apps/gogrpc
- #7476: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.2 to 1.36.4 in /tests/apps/gogrpc
- #7469: @dependabot[bot] chore(deps): bump golang from 1.23.4 to 1.23.5 in /tests/apps/go-fail-postdeploy
- #7468: @dependabot[bot] chore(deps): bump golang from 1.23.4 to 1.23.5 in /tests/apps/go-fail-predeploy
- #7467: @dependabot[bot] chore(deps): bump golang from 1.23.4 to 1.23.5 in /tests/apps/zombies-dockerfile-no-tini
- #7465: @dependabot[bot] chore(deps): bump golang from 1.23.4 to 1.23.5 in /tests/apps/zombies-dockerfile-tini
- #7466: @dependabot[bot] chore(deps): bump golang from 1.23.4 to 1.23.5 in /tests/apps/gogrpc
- #7462: @dependabot[bot] chore(deps): bump traefik from 3.3.1 to 3.3.2 in /plugins/traefik-vhosts
- #7460: @dependabot[bot] chore(deps): bump django from 5.0.10 to 5.0.11 in /tests/apps/dockerfile-release
- #7474: @dependabot[bot] chore(deps): bump importlib-metadata from 8.5.0 to 8.6.1 in /docs/_build
### Other
- #7554: @josegonzalez fix: update test for newer git version
The newer git version seems to remove the branches directory for some odd reason. I've attempted debugging this but that git version isn't available for Ubuntu 24.04 - Github Actions seems to install it regardless.
Rather than waste cycles, just remove it from CI.
Rather than try and validate this out of band, depend on sshcommand for performing any such checks on the file. There isn't any need for dokku to duplicate this when listing the contents of the file.
# History
## 0.35.14
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.14/bootstrap.sh
sudo DOKKU_TAG=v0.35.14 bash bootstrap.sh
```
### Bug Fixes
- #7441: @turicas Fix Vagrantfile NFS config
- #7417: @josegonzalez Write contents to stdout before writing to a file
- #7416: @josegonzalez Add missing DOKKU_LIB_HOST_ROOT to ensure plugins work in devcontainer setup
- #7412: @josegonzalez Remove cgroups dependencies
### New Features
- #7439: @josegonzalez Allow specifying a custom app label alias when shipping logs via vector
- #7419: @josegonzalez Add the ability to set a MAILFROM value for local cron emails
### Refactors
- #7415: @josegonzalez Use the golang version of CopyFromImage when copying files in bash
### Documentation
- #7437: @turicas Fix doc generation
- #7414: @josegonzalez Remove copyright date range
### Dependencies
- #7453: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.13 to 10.14 in /docs/_build
- #7451: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.31.0 to 0.32.0 in /plugins/common
- #7449: @dependabot[bot] chore(deps): bump pygments from 2.19.0 to 2.19.1 in /docs/_build
- #7450: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.1 to 1.36.2 in /tests/apps/gogrpc
- #7452: @dependabot[bot] chore(deps): bump traefik from 3.2.3 to 3.3.0 in /plugins/traefik-vhosts
- #7446: @dependabot[bot] chore(deps): bump github.com/otiai10/copy from 1.14.0 to 1.14.1 in /plugins/common
- #7445: @dependabot[bot] chore(deps): bump pygments from 2.18.0 to 2.19.0 in /docs/_build
- #7444: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.5 to 45.0.6
- #7436: @dependabot[bot] chore(deps): bump pyparsing from 3.2.0 to 3.2.1 in /docs/_build
- #7433: @dependabot[bot] chore(deps): bump k8s.io/kubernetes from 1.29.1 to 1.29.7 in /plugins/scheduler-k3s
- #7429: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.36.1 to 1.36.2 in /plugins/common
- #7427: @dependabot[bot] chore(deps): bump click from 8.1.7 to 8.1.8 in /docs/_build
- #7425: @dependabot[bot] chore(deps): bump jinja2 from 3.1.4 to 3.1.5 in /tests/apps/python-flask
- #7426: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.36.0 to 1.36.1 in /tests/apps/gogrpc
- #7428: @dependabot[bot] chore(deps): bump jinja2 from 3.1.4 to 3.1.5 in /docs/_build
- #7430: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.12 to 10.13 in /docs/_build
- #7432: @dependabot[bot] chore(deps): bump ruby from 3.3.6 to 3.4.1 in /tests/apps/dockerfile-entrypoint
- #7424: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.69.0 to 1.69.2 in /tests/apps/gogrpc
- #7420: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.35.2 to 1.36.0 in /tests/apps/gogrpc
- #7421: @dependabot[bot] chore(deps): bump traefik from 3.2.2 to 3.2.3 in /plugins/traefik-vhosts
- #7418: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.48 to 9.5.49 in /docs/_build
- #7411: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.68.1 to 1.69.0 in /tests/apps/gogrpc
### Other
- #7434: @turicas Add missing checks:set to checks help
- #7422: @Tashows Fix detached tty for k3s
Rather than writing directly to the file - thus utilizing whatever user docker is being executed as - we copy the file to stdout and then write it to the temp file. This ensures permissions on the file are as expected from Dokku's end.
Closes#7336
# History
## 0.35.13
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.13/bootstrap.sh
sudo DOKKU_TAG=v0.35.13 bash bootstrap.sh
```
### Bug Fixes
- #7410: @josegonzalez Only raise nil responses for k8s list calls as errors
- #7403: @Tashows Properly resolve imagePullSecrets from app and deploymentID if relevant property does not exist
- #7404: @josegonzalez Correctly handle scale to zero with the Keda http addon
- #7400: @Tashows Check if tty is actually used and support proper output when it's not
### Documentation
- #7395: @josegonzalez Add documentation for all file formats dokku uses
- #7399: @nonZero Add -w 0 to base64 call in config:set docs for safe usage in ssh commands
### Tests
- #7380: @josegonzalez Run unit tests outside of docker by default
### Dependencies
- #7409: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.30.0 to 0.31.0 in /plugins/docker-options
- #7405: @dependabot[bot] chore(deps): bump timberio/vector from 0.42.0-debian to 0.43.1-debian in /plugins/logs
- #7407: @dependabot[bot] chore(deps): bump traefik from 3.2.1 to 3.2.2 in /plugins/traefik-vhosts
- #7402: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.36.0 to 1.36.1 in /plugins/common
- #7390: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.29.0 to 0.30.0 in /plugins/common
- #7397: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.4 to 45.0.5
- #7398: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.47 to 9.5.48 in /docs/_build
- #7394: @dependabot[bot] chore(deps): bump django from 5.0.9 to 5.0.10 in /tests/apps/dockerfile-release
- #7385: @dependabot[bot] chore(deps): bump golang from 1.23.3 to 1.23.4 in /tests/apps/go-fail-predeploy
- #7386: @dependabot[bot] chore(deps): bump golang from 1.23.3 to 1.23.4 in /tests/apps/zombies-dockerfile-tini
- #7387: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.68.0 to 1.68.1 in /tests/apps/gogrpc
- #7388: @dependabot[bot] chore(deps): bump python from 3.13.0-alpine to 3.13.1-alpine in /docs/_build
- #7389: @dependabot[bot] chore(deps): bump six from 1.16.0 to 1.17.0 in /docs/_build
- #7392: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.9.0 to 0.10.0 in /plugins/scheduler-docker-local
- #7393: @dependabot[bot] chore(deps): bump python from 3.13.0-bookworm to 3.13.1-bookworm in /tests/apps/dockerfile-release
- #7384: @dependabot[bot] chore(deps): bump golang from 1.23.3 to 1.23.4 in /tests/apps/gogrpc
- #7383: @dependabot[bot] chore(deps): bump golang from 1.23.3 to 1.23.4 in /tests/apps/zombies-dockerfile-no-tini
- #7382: @dependabot[bot] chore(deps): bump golang from 1.23.3 to 1.23.4 in /tests/apps/go-fail-postdeploy
There is a bug in the Keda project that caused Keda to incorrectly handle empty trigger lists. If self-managing the ScaledObject when using an HTTPScaledObject, an external-push trigger must be created.
This change additionally updates the chart to fix any potential bugs in usage of keda.
Some files - those maintained by external organizations - have a very light treatment and solely point to the upstream documentation to reduce any issues creating examples/documentation for them that may differ in the future.
Closes#7315
# History
## 0.35.12
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.12/bootstrap.sh
sudo DOKKU_TAG=v0.35.12 bash bootstrap.sh
```
### Bug Fixes
- #7361: @josegonzalez Allow autoscaling config to have zero min replicas
### New Features
- #7379: @josegonzalez Provide ability to customize chart values via `scheduler-k3s:set`
### Documentation
- #7365: @binchengqu Correct some documentation types
### Dependencies
- #7378: @josegonzalez Update go modules
- #7376: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.46 to 9.5.47 in /docs/_build
- #7370: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.35.1 to 1.36.0 in /plugins/common
- #7377: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.9 to 2.11.14 in /plugins/scheduler-k3s
- #7369: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.35.1 to 1.36.0 in /plugins/config
- #7371: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.45 to 9.5.46 in /docs/_build
- #7366: @dependabot[bot] chore(deps): bump traefik from 3.2.0 to 3.2.1 in /plugins/traefik-vhosts
- #7364: @dependabot[bot] chore(deps): bump github.com/cert-manager/cert-manager from 1.13.3 to 1.15.4 in /plugins/scheduler-k3s
- #7363: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.44 to 9.5.45 in /docs/_build
- #7360: @dependabot[bot] chore(deps): bump flask from 3.0.3 to 3.1.0 in /tests/apps/python-flask
- #7358: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.35.1 to 1.35.2 in /tests/apps/gogrpc
- #7359: @dependabot[bot] chore(deps): bump flask from 3.0.3 to 3.1.0 in /tests/apps/multi
Dokku ships with default charts and customizes their helm values. In certain cases, it may be useful to further customize those values to better support specific installations. With this change, it is now possible to set custom values by providing the key in the format `chart.$CHART_NAME.$PROPERTY`. For instance, to increase timeouts for the keda http addon:
```shell
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.tcpConnectTimeout 120s
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.keepAlive 120s
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.responseHeaderTimeout 120s
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.idleConnTimeout 120s
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.tlsHandshakeTimeout 120s
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.expectContinueTimeout 120s
```
To reset a value to its default, simply set the value to an empty string.
```shell
dokku scheduler-k3s:set --global chart.keda-add-ons-http.interceptor.tcpConnectTimeout
```
Once the values are set, users will need to then run `scheduler-k3s:ensure-charts` with either the `--force` flag or specify the `--chart` flag with a list of charts to force apply.
```shell
dokku scheduler-k3s:ensure-charts --force
dokku scheduler-k3s:ensure-charts --chart keda-add-ons-http
```
Note that the existing dokku-provided values cannot be removed, but can be overridden.
# History
## 0.35.11
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.11/bootstrap.sh
sudo DOKKU_TAG=v0.35.11 bash bootstrap.sh
```
### Bug Fixes
- #7353: @indrat Add missing export DOKKU_LIB_HOST_ROOT when running dokku in container
### New Features
- #7355: @josegonzalez Add support for http-based scaling when deploying on the k3s scheduler
### Documentation
- #7349: @josegonzalez Create .well-known/funding-manifest-urls
### Dependencies
- #7345: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.67.1 to 1.68.0 in /tests/apps/gogrpc
- #7350: @dependabot[bot] chore(deps): bump zipp from 3.20.2 to 3.21.0 in /docs/_build
- #7351: @dependabot[bot] chore(deps): bump werkzeug from 3.1.2 to 3.1.3 in /tests/apps/python-flask
- #7347: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.28.0 to 0.29.0 in /plugins/common
- #7348: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.8.0 to 0.9.0 in /plugins/common
- #7344: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.3 to 45.0.4
- #7343: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.8.0 to 0.9.0 in /plugins/scheduler-docker-local
- #7342: @dependabot[bot] chore(deps): bump packaging from 24.1 to 24.2 in /docs/_build
- #7341: @dependabot[bot] chore(deps): bump golang from 1.23.2 to 1.23.3 in /tests/apps/zombies-dockerfile-tini
- #7340: @dependabot[bot] chore(deps): bump golang from 1.23.2 to 1.23.3 in /tests/apps/gogrpc
- #7339: @dependabot[bot] chore(deps): bump golang from 1.23.2 to 1.23.3 in /tests/apps/go-fail-predeploy
- #7338: @dependabot[bot] chore(deps): bump golang from 1.23.2 to 1.23.3 in /tests/apps/zombies-dockerfile-no-tini
- #7337: @dependabot[bot] chore(deps): bump golang from 1.23.2 to 1.23.3 in /tests/apps/go-fail-postdeploy
- #7335: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.43 to 9.5.44 in /docs/_build
- #7334: @dependabot[bot] chore(deps): bump ruby from 3.3.5 to 3.3.6 in /tests/apps/dockerfile-entrypoint
- #7333: @dependabot[bot] chore(deps): bump werkzeug from 3.1.1 to 3.1.2 in /tests/apps/python-flask
### Other
- #7357: @josegonzalez Run brew cleanup before running brew doctor
# History
## 0.35.10
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.10/bootstrap.sh
sudo DOKKU_TAG=v0.35.10 bash bootstrap.sh
```
### Bug Fixes
- #7324: @josegonzalez Correctly pull the deployment id from an app's helm values when executing dokku run under the k3s scheduler
- #7332: @josegonzalez Drop the pod name from stdout output when creating one-off containers under the k3s scheduler
- #7331: @josegonzalez Output logs for completed containers launched by the k3s scheduler
- #7330: @josegonzalez Disable stdio buffering so log coloring happens normally when fetching logs for k3s-scheduler managed apps
- #7329: @josegonzalez Correctly wait for one-off k3s pods to be ready
- #7328: @josegonzalez Execute one-off commands with DOKKU_APP_SHELL as the initial command under the k3s scheduler
- #7323: @josegonzalez Correct errors in brew doctor output when making a formula release
### Dependencies
- #7327: @dependabot[bot] chore(deps): bump watchdog from 5.0.3 to 6.0.0 in /docs/_build
- #7326: @dependabot[bot] chore(deps): bump werkzeug from 3.1.0 to 3.1.1 in /tests/apps/python-flask
Previously, a container that exited immediately would just show an error message, which is probably not what we want.
If the pod has exited, we will display the logs on stdout for the user and then exit appropriately.
This change also refactors how log streaming works so that we respect exiting when the stream has no content (such as when the container has exited). Previously, the container would just hang around forever due to not being properly canceled. Due to this refactor, the prefix is now split out into a separate writer.
This commit changes the launched pod to use the configured DOKKU_APP_SHELL - default /bin/bash - to launch processes. Without this, if a non-interactive process was executed and did not immediately exit, it was possible for that process to launch twice - once when the pod started, and once when entering the pod. Ideally we know whether the process is interactive or not, but this isn't always possible when running under a tty (non-tty == non-interactive). As such, this also removes the ability to launch one-off containers that do not have a configured shell in the container, but this is better than attempting to run commands twice.
The default homebrew setup with the macos-latest runners has issues that cause `brew doctor` to exit non-zero. The exit codes of the commands are ignored in case they are no longer necessary in the future.
# History
## 0.35.9
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.9/bootstrap.sh
sudo DOKKU_TAG=v0.35.9 bash bootstrap.sh
```
### Bug Fixes
- #7321: @josegonzalez Allow nginx commands when the scheduler is set to null
- #7313: @Tashows Remove prefixing releaseName with 'dokku-' in UninstallChart and GetValues calls in scheduler-k3s/triggers.go
### New Features
- #7322: @josegonzalez Add debugging information to brew bump-formula-pr
### Documentation
- #7312: @toanalien Fix typo in nginx documentation
### Dependencies
- #7320: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.34.2 to 1.35.1 in /plugins/common
- #7311: @dependabot[bot] chore(deps): bump traefik from 3.1.6 to 3.2.0 in /plugins/traefik-vhosts
- #7300: @dependabot[bot] chore(deps): bump github.com/fatih/color from 1.17.0 to 1.18.0 in /plugins/common
- #7319: @dependabot[bot] chore(deps): bump werkzeug from 3.0.6 to 3.1.0 in /tests/apps/python-flask
- #7317: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.42 to 9.5.43 in /docs/_build
- #7310: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.11.2 to 10.12 in /docs/_build
- #7299: @dependabot[bot] chore(deps): bump timberio/vector from 0.41.1-debian to 0.42.0-debian in /plugins/logs
- #7306: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.8.0 to 3.8.1 in /tests/apps/java
- #7305: @dependabot[bot] chore(deps): bump werkzeug from 3.0.4 to 3.0.6 in /tests/apps/python-flask
# History
## 0.35.8
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.8/bootstrap.sh
sudo DOKKU_TAG=v0.35.8 bash bootstrap.sh
```
### Bug Fixes
- #7295: @josegonzalez Respect the exit code and pass flags correctly when tailing nginx logs on k3s
- #7294: @josegonzalez Tail the correct container in the ingress-nginx pod
- #7293: @josegonzalez Strip non-numeric characters from certain ingress-nginx annotation values
### New Features
- #7296: @josegonzalez Implement nginx:show-config for k3s plugin
### Documentation
- #7297: @josegonzalez Document a required ps:restart in order to apply annotations, labels, and nginx properties
### Dependencies
- #7287: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.9.0 to 3.10.0 in /plugins/cron
- #7288: @dependabot[bot] chore(deps): bump markupsafe from 3.0.1 to 3.0.2 in /docs/_build
- #7289: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.41 to 9.5.42 in /docs/_build
# History
## 0.35.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.7/bootstrap.sh
sudo DOKKU_TAG=v0.35.7 bash bootstrap.sh
```
### Bug Fixes
- #7286: @josegonzalez Install netcat-traditional in 24.04 image
- #7284: @josegonzalez Use correct name for scheduler-proxy-logs trigger
- #7285: @josegonzalez Ensure builder pruning works when running under docker
- #7283: @danieldiekmeier Force `docker builder prune` to skip confirmation
# History
## 0.35.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.6/bootstrap.sh
sudo DOKKU_TAG=v0.35.6 bash bootstrap.sh
```
### Bug Fixes
- #7279: @josegonzalez Allow exit code 2 when waiting for cloud-init to complete
- #7255: @josegonzalez Do not attempt to expose the same mapped port more than once
### New Features
- #7278: @josegonzalez Allow usage of newer nginx.conf.sigil on older versions of dokku
- #7271: @josegonzalez Add support for non-local nginx implementations
- #7269: @josegonzalez Add support for various timeout-related functions to nginx, openresty and k3s plugins
### Dependencies
- #7272: @dependabot[bot] chore(deps): bump node from 22-alpine to 23-alpine in /tests/apps/dockerfile
- #7273: @dependabot[bot] chore(deps): bump node from 22-alpine to 23-alpine in /tests/apps/dockerfile-procfile
- #7274: @dependabot[bot] chore(deps): bump node from 22-alpine to 23-alpine in /tests/apps/dockerfile-app-json-formations
- #7275: @dependabot[bot] chore(deps): bump node from 22-alpine to 23-alpine in /tests/apps/dockerfile-noexpose
- #7276: @dependabot[bot] chore(deps): bump node from 22-alpine to 23-alpine in /tests/apps/dockerfile-procfile-bad
- #7270: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.40 to 9.5.41 in /docs/_build
- #7264: @dependabot[bot] chore(deps): bump pyparsing from 3.1.4 to 3.2.0 in /docs/_build
- #7244: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.27.0 to 0.28.0 in /plugins/common
- #7260: @dependabot[bot] chore(deps): bump traefik from 3.1.5 to 3.1.6 in /plugins/traefik-vhosts
- #7259: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.39 to 9.5.40 in /docs/_build
- #7258: @dependabot[bot] chore(deps): bump markupsafe from 3.0.0 to 3.0.1 in /docs/_build
- #7254: @dependabot[bot] chore(deps): bump cookie and express in /tests/apps/checks-root
- #7246: @dependabot[bot] chore(deps): bump python from 3.12.7-alpine to 3.13.0-alpine in /docs/_build
- #7247: @dependabot[bot] chore(deps): bump python from 3.12.7-bookworm to 3.13.0-bookworm in /tests/apps/dockerfile-release
- #7248: @dependabot[bot] chore(deps): bump markupsafe from 2.1.5 to 3.0.0 in /docs/_build
- #7252: @dependabot[bot] chore(deps): bump django from 5.0.8 to 5.0.9 in /tests/apps/dockerfile-release
### Other
- #7282: @josegonzalez Skip ssh key setup when starting docker image
- #7281: @josegonzalez Set hostname to dokku.me for devcontainer
- #7280: @josegonzalez Merge changes from digitialocean's image-check script
When deploying the Dokku via Docker, ssh keys are added directly via the ssh-keys:add command, and thus we can skip this step completely (as there won't be a public key in that path).
A change in cloud-init and/or the Ubuntu image provided by Digitalocean causes builds to fail due to cloud-init status exiting 2. The error is ignorable.
See digitalocean/marketplace-partners#186 for more details.
Folks might mistakenly pull the latest template file - which introduces new variables - causing deployment failures.
This change allows them to use the newer template by checking if the variables are set before using them.
Closes#7277
If the scheduler is not docker-local, we will assume that a separate plugin trigger will pull access/error logs on our behalf. For k3s, the naive implementation is to pull logs from a single container (multiple ingress-nginx pods will be supported in a future release).
Closes#7268
A newer release of Docker (27.3.1) appears to have issues with the -p flag appearing the same time more than once for a given port. This was previously not an issue, but we should remove the problem on our end regardless.
Closes#7251
# History
## 0.35.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.5/bootstrap.sh
sudo DOKKU_TAG=v0.35.5 bash bootstrap.sh
```
### New Features
- #7213: @josegonzalez Release Dokku on supported versions of Debian and Raspbian
### Documentation
- #7241: @josegonzalez Clarify phase utilization in docker-options docs
- #7240: @josegonzalez Update testing docs to specify that CI is performed on Ubuntu Noble
- #7218: @josegonzalez Fix reference to arm64
- #7215: @Lewiscowles1986 Clarify x64 as amd64/arch64 in readme
### Tests
- #7212: @josegonzalez Update python version used in test apps
### Dependencies
- #7243: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.34.2 to 1.35.1 in /tests/apps/gogrpc
- #7238: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.2 to 45.0.3
- #7237: @dependabot[bot] chore(deps): bump traefik from 3.1.4 to 3.1.5 in /plugins/traefik-vhosts
- #7227: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.67.0 to 1.67.1 in /tests/apps/gogrpc
- #7231: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.11.1 to 10.11.2 in /docs/_build
- #7228: @dependabot[bot] chore(deps): bump golang from 1.23.1 to 1.23.2 in /tests/apps/go-fail-postdeploy
- #7229: @dependabot[bot] chore(deps): bump golang from 1.23.1 to 1.23.2 in /tests/apps/zombies-dockerfile-tini
- #7230: @dependabot[bot] chore(deps): bump python from 3.12.6-bookworm to 3.12.7-bookworm in /tests/apps/dockerfile-release
- #7232: @dependabot[bot] chore(deps): bump golang from 1.23.1 to 1.23.2 in /tests/apps/go-fail-predeploy
- #7233: @dependabot[bot] chore(deps): bump python from 3.12.6-alpine to 3.12.7-alpine in /docs/_build
- #7234: @dependabot[bot] chore(deps): bump golang from 1.23.1 to 1.23.2 in /tests/apps/zombies-dockerfile-no-tini
- #7235: @dependabot[bot] chore(deps): bump golang from 1.23.1 to 1.23.2 in /tests/apps/gogrpc
- #7220: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.38 to 9.5.39 in /docs/_build
- #7221: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.10.2 to 10.11.1 in /docs/_build
- #7222: @dependabot[bot] chore(deps): bump watchdog from 5.0.2 to 5.0.3 in /docs/_build
### Other
- #7245: @moenoel fix: #7035 broke traefik https router rule
So I started by searching after reading README.md, and came across #6312
Maybe others assume x64 is synonymous with 64-bit, but I find the long-hand, helped me to understand that arm64 and aarch64, and amd64 as well as x86_64 (which I thought x64 most closely resembled) are all supported, and it's a minimum native bus width limitation, dispensing with the history of x86 and 8086, than anything else.
The policy has always been to only release for supported versions of operating systems, so this change aligns what we release for and how Dokku may be installed.
Folks running unmaintained operating systems should upgrade, as the packages are never guaranteed to exist in the Dokku apt repository.
# History
## 0.35.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.4/bootstrap.sh
sudo DOKKU_TAG=v0.35.4 bash bootstrap.sh
```
### Bug Fixes
- #7209: @josegonzalez Exit non-zero if any deployment tasks fails
- #7211: @josegonzalez Always set the git rev env var when building an app via git:sync
- #7208: @josegonzalez Compute path for docker-container-healthchecker
- #7205: @Cactusbone chore: fix vagrant dokku-windows config
### Tests
- #7210: @josegonzalez Ensure pack binary is installed correctly when running tests in a devcontainer
### Dependencies
- #7206: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.37 to 9.5.38 in /docs/_build
- #7207: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.10.1 to 10.10.2 in /docs/_build
- #7203: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.36 to 9.5.37 in /docs/_build
This fixes an issue for source-based Dokku installs where the binary is installed in /usr/local/bin instead of /usr/bin due to not being installed via an OS package.
Closes#7010
# History
## 0.35.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.3/bootstrap.sh
sudo DOKKU_TAG=v0.35.3 bash bootstrap.sh
```
### Bug Fixes
- #7200: @josegonzalez Automatically select a container type if none is specified
- #7199: @josegonzalez Check if nginx is running before reloading during an app deletion
- #7198: @josegonzalez Add builder-herokuish to default help output
- #7197: @josegonzalez Implement missing network:info command
### Tests
- #7201: @josegonzalez Run arm build on 22.04
### Dependencies
- #7193: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.9 to 10.10.1 in /docs/_build
- #7194: @dependabot[bot] chore(deps): bump traefik from 3.1.2 to 3.1.4 in /plugins/traefik-vhosts
- #7195: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.9.0 to 0.9.1 in /plugins/openresty-vhosts
- #7196: @dependabot[bot] chore(deps): bump socket.io from 4.7.5 to 4.8.0 in /tests/apps/.websocket.disabled
# History
## 0.35.2
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.2/bootstrap.sh
sudo DOKKU_TAG=v0.35.2 bash bootstrap.sh
```
### Bug Fixes
- #7191: @josegonzalez Revert to building Dokku on Ubunut 20.04 Focal to hotfix glibc issues
### New Features
- #7190: @josegonzalez Allow setting most nginx properties globally
# History
## 0.35.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.1/bootstrap.sh
sudo DOKKU_TAG=v0.35.1 bash bootstrap.sh
```
### Bug Fixes
- #7188: @josegonzalez Respect GO environment variables when building to ensure CGO is disabled
### Documentation
- #7187: @josegonzalez Remove reference to old web ui
### Dependencies
- #7115: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.26.0 to 0.27.0 in /plugins/common
- #7160: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.10.7 to 2.11.9 in /plugins/scheduler-k3s
- #7094: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.34.1 to 1.34.2 in /plugins/common
- #7096: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.34.1 to 1.34.2 in /plugins/config
- #7109: @dependabot[bot] chore(deps): bump watchdog from 4.0.2 to 5.0.2 in /docs/_build
- #7127: @dependabot[bot] chore(deps): bump python from 3.12.5-alpine to 3.12.6-alpine in /docs/_build
- #7117: @dependabot[bot] chore(deps): bump golang from 1.23.0 to 1.23.1 in /tests/apps/go-fail-postdeploy
- #7116: @dependabot[bot] chore(deps): bump golang from 1.23.0 to 1.23.1 in /tests/apps/zombies-dockerfile-tini
- #7112: @dependabot[bot] chore(deps): bump golang from 1.23.0 to 1.23.1 in /tests/apps/zombies-dockerfile-no-tini
- #7108: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.23 to 11.0.24 in /tests/apps/java
- #7113: @dependabot[bot] chore(deps): bump golang from 1.23.0 to 1.23.1 in /tests/apps/go-fail-predeploy
- #7110: @dependabot[bot] chore(deps): bump ruby from 3.3.4 to 3.3.5 in /tests/apps/dockerfile-entrypoint
- #7114: @dependabot[bot] chore(deps): bump golang from 1.23.0 to 1.23.1 in /tests/apps/gogrpc
- #7132: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/dockerfile-procfile-bad
- #7133: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/nodejs-express-noappjson
- #7134: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/gitsubmodules
- #7135: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/nodejs-express-noprocfile
- #7136: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/dockerfile-procfile
- #7137: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/dockerfile-app-json-formations
- #7140: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/.websocket.disabled
- #7141: @dependabot[bot] chore(deps): bump express from 4.19.2 to 4.21.0 in /tests/apps/nodejs-express
- #7161: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.65.0 to 1.67.0 in /tests/apps/gogrpc
- #7153: @dependabot[bot] chore(deps): bump luizm/action-sh-checker from 0.8.0 to 0.9.0
- #7152: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 45.0.0 to 45.0.2
- #7079: @dependabot[bot] chore(deps): bump pyparsing from 3.1.2 to 3.1.4 in /docs/_build
- #7097: @dependabot[bot] chore(deps): bump mkdocs from 1.6.0 to 1.6.1 in /docs/_build
- #7142: @dependabot[bot] chore(deps): bump importlib-metadata from 8.4.0 to 8.5.0 in /docs/_build
- #7186: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.33 to 9.5.36 in /docs/_build
- #7144: @dependabot[bot] chore(deps): bump zipp from 3.20.0 to 3.20.2 in /docs/_build
Without this, building Dokku on a newer operating system will result in binaries that do not work on older systems. The environment variables were only being set when building in docker, which has not been used in the release workflow for a while.
# History
## 0.35.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.35.0/bootstrap.sh
sudo DOKKU_TAG=v0.35.0 bash bootstrap.sh
```
See the [0.35.0 migration guide](/docs/appendices/0.35.0-migration-guide.md) for more information on migrating to 0.35.0.
### Bug Fixes
- #7179: @josegonzalez Remove references to version in compose files
- #7177: @josegonzalez Reference noble apt repository and not focal
- #7164: @josegonzalez Remove systemd on docker-based installations
- #7157: @Cactusbone Fix building in vagrant when jq is not available
- #7147: @Cactusbone Support older docker versions by setting ARG value with an equal sign
- #7088: @andreby Handle the case where parent PID is 0
- #7077: @bakatz Add cron dependency because it's necessary to run scheduled cron jobs
### New Features
- #7185: @josegonzalez Fix vagrant running on arm64 machines
- #7184: @josegonzalez Clear out docker builder cache once a day
- #7183: @josegonzalez Error out when the Dockerfile is missing during builder-dockerfile execution
- #7175: @josegonzalez Upgrade digitalocean image to Ubuntu Noble
- #7174: @josegonzalez Upgrade vagrant image to Ubuntu Noble
- #7173: @josegonzalez Upgrade builder docker image to Ubuntu Noble
- #7166: @josegonzalez Upgrade herokuish from 0.9.2 to 0.10.1
- #7075: @josegonzalez Upgrade herokuish builder to gliderlabs/herokuish:latest-24
- #7074: @josegonzalez Upgrade cnb builder to heroku/builder:24
- #7071: @josegonzalez Bump go version to 1.23.0
- #6853: @Reggino Support Ubuntu 24.04 LTS
- #6762: @josegonzalez Upgrade docker compose version in use
### Documentation
- #7180: @josegonzalez Reference actual properties for enabling the traefik api and dashboard
- #7178: @josegonzalez Fix link to docs site
- #7101: @strugee Fix typo in CNB documentation
- #7100: @no0dles SVG gets modified on release
### Tests
- #7176: @josegonzalez Fetch packages installed in ci from Ubuntu Noble repo
- #7172: @josegonzalez Run CI release processes on Ubuntu Noble
- #7171: @josegonzalez Run CI on Ubuntu Noble
- #7170: @josegonzalez Run CI codeql analysis on Ubuntu Noble
- #7169: @josegonzalez Run CI doc generation on Ubuntu Noble
- #7168: @josegonzalez Run CI linting on Ubuntu Noble
- #7073: @josegonzalez Drop codacy
### Dependencies
- #7148: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.8.0 to 0.9.0 in /plugins/openresty-vhosts
- #7139: @dependabot[bot] chore(deps): bump timberio/vector from 0.39.0-debian to 0.41.1-debian in /plugins/logs
- #7060: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.8.0 to 3.9.0 in /plugins/cron
- #7035: @dependabot[bot] chore(deps): bump traefik from 2.11.2 to 3.1.2 in /plugins/traefik-vhosts
- #7014: @dependabot[bot] chore(deps): bump timberio/vector from 0.39.0-debian to 0.40.0-debian in /plugins/logs
- #6985: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.10.7 to 2.11.6 in /plugins/scheduler-k3s
### Other
- #7165: @josegonzalez Upgrade Docker image to Ubuntu Noble 24.04
- #6784: @josegonzalez Remove --restart docker arguments when not running deploy-phase containers
There have been a number of tickets in the past - most recently #7061 - covering the fact that Dokku doesn't clean up disk utilization. The underlying issue is that Docker uses build cache that cannot be cleaned up in a targeted way - and usually doesn't even respect the builder gc settings in a way that makes sense. In fact, the computed disk space does not line up with actual disk utilization, causing it to be a mystery to anyone investigating the underlying problem.
This change introduces a cron-based mechanism that cleans up disk once a day. Cleaning up more often would potentially cause issues during a build if for some reason the prune and an app deploy happened at the same time - its not clear if there is a lock on build cache usage - so cleaning up after hours once a day is a decent tradeoff.
In the future, this setting may be modifiable, but it works well for now.
Closes#7061
Users may inadvertently set the builder to 'dockerfile' and have build errors when there is no Dockerfile. This change makes it clear that the dockerfile _must_ exist in order for the build to succeed.
Closes#7181
This change also skips running a restart of rsyslog as during install, the service isn't properly initiated. While this breaks upgrades of Dokku within containers, that is not how upgrades of container-based Dokku should work, so this is a fine trade-off.
On newer Ubuntu Noble, cron (among other things) has a transitory dependency on systemd, forcing our systemd/runit detection to fail. This change allows overriding the detected init on Ubuntu systems, ensuring we always do the right thing when interacting with init.
The systemd package was installed by default for some reason, causing issues when interacting with init processes. Specifically, we would detect systemctl on runit systems and incorrectly invoke that when restarting processes.
Additionally, ensure the copied binaries are executable.
Closes#7089
docker-image-labeler default DOCKER_IMAGE_LABELER_URL uses jq,
so jq needs to be available first.
This happens for example when using `vagrant up dokku-window`.
Fixes#7155
[Documentation](https://docs.docker.com/reference/dockerfile/#arg)
indicates that arguments must be passed using equal sign `=`.
This fixes error "ARG requires exactly one argument" using Docker
20.10.12 (and possibly many other versions).
This works around cases where developers may inadvertently add this to `run` containers which _should not_ have the `--restart` flag. Run containers are one-off, and if they fail, then they should fail hard.
# History
## 0.34.9
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.9/bootstrap.sh
sudo DOKKU_TAG=v0.34.9 bash bootstrap.sh
```
### Documentation
- #7062: @Tashows List dokku-image-size-limit plugin
### Dependencies
- #7070: @dependabot[bot] chore(deps): bump micromatch from 4.0.5 to 4.0.8 in /tests/apps/multi
- #7064: @dependabot[bot] chore(deps): bump importlib-metadata from 8.3.0 to 8.4.0 in /docs/_build
- #7068: @dependabot[bot] chore(deps): bump werkzeug from 3.0.3 to 3.0.4 in /tests/apps/python-flask
- #7065: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.22 to 11.0.23 in /tests/apps/java
- #7066: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.7 to 45.0.0
- #7067: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.1 to 3.8.0 in /tests/apps/java
- #7069: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.32 to 9.5.33 in /docs/_build
- #7063: @dependabot[bot] chore(deps): bump importlib-metadata from 8.2.0 to 8.3.0 in /docs/_build
- #7058: @dependabot[bot] chore(deps): update markdown requirement from <3.7,>=3.2.1 to >=3.2.1,<3.8 in /docs/_build
- #7059: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.31 to 9.5.32 in /docs/_build
# History
## 0.34.8
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.8/bootstrap.sh
sudo DOKKU_TAG=v0.34.8 bash bootstrap.sh
```
### Documentation
- #7046: @bakatz Fixes incorrect documentation link for null builder
- #6983: @polettix Clarify paths used by Dokku when looking for specific files
- #7012: @DavidTheProgrammer Fix grammar under HSTS Header section in ssl documentation
- #7019: @josegonzalez Clarify to users that the migration guides should be followed for upgrades
### Tests
- #7039: @josegonzalez Correct case of pip in builder-pack test output
### Dependencies
- #7057: @josegonzalez Update golang dependencies
- #7048: @dependabot[bot] chore(deps): bump soupsieve from 2.5 to 2.6 in /docs/_build
- #7041: @dependabot[bot] chore(deps): bump zipp from 3.19.2 to 3.20.0 in /docs/_build
- #7044: @dependabot[bot] chore(deps): bump gunicorn from 22.0.0 to 23.0.0 in /tests/apps/multi
- #7042: @dependabot[bot] chore(deps): bump watchdog from 4.0.1 to 4.0.2 in /docs/_build
- #7043: @dependabot[bot] chore(deps): bump gunicorn from 22.0.0 to 23.0.0 in /tests/apps/python-flask
- #7045: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.25.0 to 0.26.0 in /plugins/common
- #7050: @dependabot[bot] chore(deps): bump golang from 1.22.6 to 1.23.0 in /tests/apps/zombies-dockerfile-tini
- #7049: @dependabot[bot] chore(deps): bump golang from 1.22.6 to 1.23.0 in /tests/apps/zombies-dockerfile-no-tini
- #7051: @dependabot[bot] chore(deps): bump golang from 1.22.6 to 1.23.0 in /tests/apps/go-fail-predeploy
- #7052: @dependabot[bot] chore(deps): bump golang from 1.22.6 to 1.23.0 in /tests/apps/gogrpc
- #7053: @dependabot[bot] chore(deps): bump golang from 1.22.6 to 1.23.0 in /tests/apps/go-fail-postdeploy
- #7022: @dependabot[bot] chore(deps): bump github.com/docker/docker from 24.0.9+incompatible to 25.0.6+incompatible in /plugins/scheduler-k3s
- #7016: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.34.0 to 1.34.1 in /plugins/config
- #7036: @dependabot[bot] chore(deps): bump django from 5.0.7 to 5.0.8 in /tests/apps/dockerfile-release
- #7025: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.7.0 to 0.8.0 in /plugins/common
- #7034: @dependabot[bot] chore(deps): bump golang from 1.22.5 to 1.22.6 in /tests/apps/gogrpc
- #7033: @dependabot[bot] chore(deps): bump golang from 1.22.5 to 1.22.6 in /tests/apps/go-fail-postdeploy
- #7030: @dependabot[bot] chore(deps): bump golang from 1.22.5 to 1.22.6 in /tests/apps/go-fail-predeploy
- #7015: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.34.0 to 1.34.1 in /plugins/common
- #7011: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.8.1 to 10.9 in /docs/_build
- #7037: @dependabot[bot] chore(deps): bump python from 3.12.4-alpine to 3.12.5-alpine in /docs/_build
- #7023: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.30 to 9.5.31 in /docs/_build
- #7032: @dependabot[bot] chore(deps): bump pyyaml from 6.0.1 to 6.0.2 in /docs/_build
- #7031: @dependabot[bot] chore(deps): bump golang from 1.22.5 to 1.22.6 in /tests/apps/zombies-dockerfile-tini
- #7021: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.6 to 44.5.7
- #7029: @dependabot[bot] chore(deps): bump golang from 1.22.5 to 1.22.6 in /tests/apps/zombies-dockerfile-no-tini
- #6999: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.5 to 44.5.6
- #7002: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.12.0 to 0.12.1 in /plugins/ps
- #7004: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.28 to 9.5.30 in /docs/_build
- #7006: @dependabot[bot] chore(deps): bump importlib-metadata from 8.0.0 to 8.2.0 in /docs/_build
- #7007: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.33.1 to 1.34.0 in /plugins/common
- #7008: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.33.1 to 1.34.0 in /plugins/config
- #6996: @dependabot[bot] chore(deps): bump setuptools from 68.0.0 to 70.0.0 in /tests/apps/dockerfile-release
# History
## 0.34.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.7/bootstrap.sh
sudo DOKKU_TAG=v0.34.7 bash bootstrap.sh
```
### Bug Fixes
- #6984: @josegonzalez Correctly pass around arguments when displaying container log output
### New Features
- #6992: @josegonzalez feat: add logging when hsts nginx config is not using built-in template
### Dependencies
- #6988: @dependabot[bot] chore(deps): bump django from 5.0.6 to 5.0.7 in /tests/apps/dockerfile-release
- #6987: @dependabot[bot] chore(deps): bump ruby from 3.3.3 to 3.3.4 in /tests/apps/dockerfile-entrypoint
- #6972: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.9.0 to 0.12.0 in /plugins/ps
- #6898: @josegonzalez Update all dependencies in the dokku ecosystem
- #6978: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.21 to 11.0.22 in /tests/apps/java
- #6961: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.9.0 to 0.11.0 in /plugins/ps
- #6981: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.24.0 to 0.25.0 in /plugins/common
- #6980: @dependabot[bot] chore(deps): bump golang from 1.22.4 to 1.22.5 in /tests/apps/gogrpc
- #6979: @dependabot[bot] chore(deps): bump golang from 1.22.4 to 1.22.5 in /tests/apps/go-fail-postdeploy
- #6977: @dependabot[bot] chore(deps): bump golang from 1.22.4 to 1.22.5 in /tests/apps/zombies-dockerfile-tini
- #6976: @dependabot[bot] chore(deps): bump golang from 1.22.4 to 1.22.5 in /tests/apps/zombies-dockerfile-no-tini
- #6975: @dependabot[bot] chore(deps): bump golang from 1.22.4 to 1.22.5 in /tests/apps/go-fail-predeploy
- #6971: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.64.0 to 1.65.0 in /tests/apps/gogrpc
- #6963: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.27 to 9.5.28 in /docs/_build
- #6956: @dependabot[bot] chore(deps): bump importlib-metadata from 7.2.0 to 8.0.0 in /docs/_build
- #6951: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.7.0 to 3.7.1 in /tests/apps/java
- #6952: @dependabot[bot] chore(deps): bump importlib-metadata from 7.2.0 to 7.2.1 in /docs/_build
- #6955: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.3 to 44.5.5
- #6957: @dependabot[bot] chore(deps): bump djangorestframework from 3.14.0 to 3.15.2 in /tests/apps/dockerfile-release
- #6958: @dependabot[bot] chore(deps): bump github.com/gofrs/flock from 0.8.1 to 0.9.0 in /plugins/ps
# History
## 0.34.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.6/bootstrap.sh
sudo DOKKU_TAG=v0.34.6 bash bootstrap.sh
```
### Bug Fixes
- #6949: @josegonzalez Set permissions correctly on all files in the builder-release process
### Documentation
- #6948: @anand2312 Fix grammar in docs/getting-started/advanced-installation
### Dependencies
- #6943: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.2 to 44.5.3
- #6940: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.26 to 9.5.27 in /docs/_build
- #6941: @dependabot[bot] chore(deps): bump timberio/vector from 0.38.0-debian to 0.39.0-debian in /plugins/logs
- #6946: @dependabot[bot] chore(deps): bump importlib-metadata from 7.1.0 to 7.2.0 in /docs/_build
Due to the execution of profile files when running /exec, it was possible to get into a state where files owned by root would exist in a built herokuish image.
We now instead chown the files directly, which ensures profile files only get executed at runtime.
Closesgliderlabs/herokuish#1212
Refs dokku/dokku#6851
# History
## 0.34.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.5/bootstrap.sh
sudo DOKKU_TAG=v0.34.5 bash bootstrap.sh
```
### Bug Fixes
- #6835: @erickedji Add missing local RE_IPV4 & RE_IPV6 vars in core-post-deploy
### New Features
- #6808: @Coffee2CodeNL Traefik optional custom http https entrypoints
### Documentation
- #6937: @irth docs: add `network_mode: bridge` to the docker compose example
- #6871: @chrisjsimpson Update dockerfile example in port management docs
- #6857: @josegonzalez Update link to dokku development blog
- #6821: @andrew-womeldorf Add tailscale plugin to community plugin list
- #6823: @powdahound Remove errant tab character in cron:set help text
- #6809: @alexislefebvre Update CI badge in readme
### Dependencies
- #6934: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.1 to 3.7.0 in /tests/apps/java
- #6935: @dependabot[bot] chore(deps): bump braces from 3.0.2 to 3.0.3 in /tests/apps/multi
- #6938: @dependabot[bot] chore(deps): bump ruby from 3.3.2 to 3.3.3 in /tests/apps/dockerfile-entrypoint
- #6922: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.23.0 to 0.24.0 in /plugins/common
- #6929: @dependabot[bot] chore(deps): bump python from 3.12.3-alpine to 3.12.4-alpine in /docs/_build
- #6925: @dependabot[bot] chore(deps): bump zipp from 3.18.2 to 3.19.2 in /docs/_build
- #6914: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.5.1 to 44.5.2
- #6916: @dependabot[bot] chore(deps): bump ruby from 3.3.1 to 3.3.2 in /tests/apps/dockerfile-entrypoint
- #6921: @dependabot[bot] chore(deps): bump golang from 1.22.3 to 1.22.4 in /tests/apps/zombies-dockerfile-no-tini
- #6920: @dependabot[bot] chore(deps): bump golang from 1.22.3 to 1.22.4 in /tests/apps/zombies-dockerfile-tini
- #6923: @dependabot[bot] chore(deps): bump golang from 1.22.3 to 1.22.4 in /tests/apps/go-fail-postdeploy
- #6915: @dependabot[bot] chore(deps): bump lucaslorentz/caddy-docker-proxy from 2.8 to 2.9 in /plugins/caddy-vhosts
- #6924: @dependabot[bot] chore(deps): bump golang from 1.22.3 to 1.22.4 in /tests/apps/gogrpc
- #6927: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.24 to 9.5.26 in /docs/_build
- #6926: @dependabot[bot] chore(deps): bump golang from 1.22.3 to 1.22.4 in /tests/apps/go-fail-predeploy
- #6930: @dependabot[bot] chore(deps): bump packaging from 24.0 to 24.1 in /docs/_build
- #6931: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.34.1 to 1.34.2 in /tests/apps/gogrpc
- #6903: @dependabot[bot] chore(deps): bump requests from 2.31.0 to 2.32.0 in /tests/apps/lambda-python
- #6901: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.23 to 9.5.24 in /docs/_build
- #6908: @dependabot[bot] chore(deps): bump watchdog from 4.0.0 to 4.0.1 in /docs/_build
- #6909: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.4.0 to 44.5.1
- #6873: @dependabot[bot] chore(deps): bump werkzeug from 3.0.2 to 3.0.3 in /tests/apps/python-flask
- #6892: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.3.0 to 44.4.0
- #6891: @dependabot[bot] chore(deps): bump github.com/fatih/color from 1.16.0 to 1.17.0 in /plugins/common
- #6886: @dependabot[bot] chore(deps): bump golang from 1.22.2 to 1.22.3 in /tests/apps/gogrpc
- #6894: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.63.2 to 1.64.0 in /tests/apps/gogrpc
- #6888: @dependabot[bot] chore(deps): bump timberio/vector from 0.36.1-debian to 0.38.0-debian in /plugins/logs
- #6885: @dependabot[bot] chore(deps): bump golang from 1.22.2 to 1.22.3 in /tests/apps/zombies-dockerfile-tini
- #6887: @dependabot[bot] chore(deps): bump golang from 1.22.2 to 1.22.3 in /tests/apps/go-fail-postdeploy
- #6883: @dependabot[bot] chore(deps): bump golang from 1.22.2 to 1.22.3 in /tests/apps/zombies-dockerfile-no-tini
- #6879: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.34.0 to 1.34.1 in /tests/apps/gogrpc
- #6874: @dependabot[bot] chore(deps): bump jinja2 from 3.1.3 to 3.1.4 in /tests/apps/python-flask
- #6876: @dependabot[bot] chore(deps): bump pygments from 2.17.2 to 2.18.0 in /docs/_build
- #6875: @dependabot[bot] chore(deps): bump dokku/openresty-docker-proxy from 0.7.0 to 0.8.0 in /plugins/openresty-vhosts
- #6878: @dependabot[bot] chore(deps): bump jinja2 from 3.1.3 to 3.1.4 in /docs/_build
- #6880: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.22.0 to 0.23.0 in /plugins/common
- #6884: @dependabot[bot] chore(deps): bump golang from 1.22.2 to 1.22.3 in /tests/apps/go-fail-predeploy
- #6897: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.20 to 11.0.21 in /tests/apps/java
- #6896: @dependabot[bot] chore(deps): bump zipp from 3.18.1 to 3.18.2 in /docs/_build
- #6895: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.20 to 9.5.23 in /docs/_build
- #6858: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.8 to 10.8.1 in /docs/_build
- #6859: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.19 to 9.5.20 in /docs/_build
- #6860: @dependabot[bot] chore(deps): bump node from 21-alpine to 22-alpine in /tests/apps/dockerfile-procfile
- #6861: @dependabot[bot] chore(deps): bump node from 21-alpine to 22-alpine in /tests/apps/dockerfile-procfile-bad
- #6862: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.33.0 to 1.33.1 in /plugins/common
- #6863: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.33.0 to 1.33.1 in /plugins/config
- #6865: @dependabot[bot] chore(deps): bump node from 21-alpine to 22-alpine in /tests/apps/dockerfile
- #6866: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.33.0 to 1.34.0 in /tests/apps/gogrpc
- #6867: @dependabot[bot] chore(deps): bump node from 21-alpine to 22-alpine in /tests/apps/dockerfile-noexpose
- #6868: @dependabot[bot] chore(deps): bump node from 21-alpine to 22-alpine in /tests/apps/dockerfile-app-json-formations
- #6849: @dependabot[bot] chore(deps): bump mkdocs from 1.5.3 to 1.6.0 in /docs/_build
- #6852: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.18 to 9.5.19 in /docs/_build
- #6850: @dependabot[bot] chore(deps): bump ruby from 3.3.0 to 3.3.1 in /tests/apps/dockerfile-entrypoint
- #6845: @josegonzalez chore: update dependencies
- #6843: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.32.0 to 1.33.0 in /plugins/common
- #6844: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.32.0 to 1.33.0 in /plugins/config
- #6842: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.1.0 to 44.3.0
- #6841: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.7.1 to 10.8 in /docs/_build
- #6839: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.21.0 to 0.23.0 in /plugins/config
- #6837: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.21.0 to 0.23.0 in /tests/apps/gogrpc
- #6838: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.21.0 to 0.23.0 in /plugins/common
- #6840: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.21.0 to 0.23.0 in /plugins/scheduler-k3s
- #6836: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.0.1 to 44.1.0
- #6831: @dependabot[bot] chore(deps): bump gunicorn from 21.2.0 to 22.0.0 in /tests/apps/python-flask
- #6829: @dependabot[bot] chore(deps): bump gunicorn from 20.1.0 to 22.0.0 in /tests/apps/dockerfile-release
- #6830: @dependabot[bot] chore(deps): bump gunicorn from 21.2.0 to 22.0.0 in /tests/apps/multi
- #6828: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.17 to 9.5.18 in /docs/_build
- #6825: @dependabot[bot] chore(deps): bump sqlparse from 0.4.4 to 0.5.0 in /tests/apps/dockerfile-release
- #6819: @dependabot[bot] chore(deps): bump traefik from 2.11.1 to 2.11.2 in /plugins/traefik-vhosts
- #6817: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 44.0.0 to 44.0.1
- #6816: @dependabot[bot] chore(deps): bump python from 3.12.2-alpine to 3.12.3-alpine in /docs/_build
- #6818: @dependabot[bot] chore(deps): bump traefik from 2.11.0 to 2.11.1 in /plugins/traefik-vhosts
- #6810: @dependabot[bot] chore(deps): bump flask from 3.0.2 to 3.0.3 in /tests/apps/python-flask
- #6811: @dependabot[bot] chore(deps): bump flask from 3.0.2 to 3.0.3 in /tests/apps/multi
- #6812: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.63.0 to 1.63.2 in /tests/apps/gogrpc
### Other
- #6855: @kcdragon Update Health Check documentation to include `port`
This commit cleans up the codebase by removing the unused variables HTTP_ENTRY_POINT and HTTPS_ENTRY_POINT from the traefik-vhosts plugin's docker-args-process-deploy trigger.
The code changes add the capability to configure custom HTTP and HTTPS entry points for the Traefik virtual hosts plugin. New settings have been added to the list of valid and global keys. Also, function definitions for retrieving default HTTP and HTTPS entry points were included in the internal functions file. Furthermore, the 'docker-args-process-deploy' script now considers the new entry points while processing deployment arguments.
Also fixed a typo in set, line 13: "dashboard"-enabled -> "dashboard-enabled"
# History
## 0.34.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.4/bootstrap.sh
sudo DOKKU_TAG=v0.34.4 bash bootstrap.sh
```
### Bug Fixes
- #6801: @josegonzalez Guard against invalid proxy values due to move of port mapping to ports plugin
- #6798: @josegonzalez Implement missing scheduler-app-status trigger in k3s scheduler plugin
- #6791: @josegonzalez Correct issue where pre-deploy scripts do not have root access
### New Features
- #6800: @josegonzalez Update message for deployment tasks that execute in ephemeral containers
### Documentation
- #6799: @josegonzalez Document that a registry is required for k3s usage
### Tests
- #6802: @josegonzalez Update test for new deployment task output
### Dependencies
- #6807: @josegonzalez chore: bump go modules
- #6805: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.6.0 to 0.7.0 in /plugins/common
- #6806: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.21.0 to 0.22.0 in /plugins/common
- #6803: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.6.0 to 0.7.0 in /plugins/scheduler-docker-local
- #6804: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.6.0 to 0.7.0 in /plugins/app-json
- #6794: @dependabot[bot] chore(deps): bump golang from 1.22.1 to 1.22.2 in /tests/apps/zombies-dockerfile-tini
- #6796: @dependabot[bot] chore(deps): bump golang from 1.22.1 to 1.22.2 in /tests/apps/gogrpc
- #6793: @dependabot[bot] chore(deps): bump golang from 1.22.1 to 1.22.2 in /tests/apps/zombies-dockerfile-no-tini
- #6797: @dependabot[bot] chore(deps): bump golang from 1.22.1 to 1.22.2 in /tests/apps/go-fail-postdeploy
- #6795: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.62.1 to 1.63.0 in /tests/apps/gogrpc
- #6792: @dependabot[bot] chore(deps): bump golang from 1.22.1 to 1.22.2 in /tests/apps/go-fail-predeploy
Users somewhat infrequently set a port mapping as the proxy type, causing issues in exposing apps publicly. Ideally we list out the available proxy types, but that would be a potential bc-break for non-core plugins, so this is the way to go for now.
Closes#6764
This fixes an issue where the post-release-builder trigger inadvertently modifies the image. We take advantage of the fact that env vars are available at the `pre-release-builder` phase to ensure any image modifications occur as appropriate.
# History
## 0.34.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.3/bootstrap.sh
sudo DOKKU_TAG=v0.34.3 bash bootstrap.sh
```
### New Features
- #6785: @josegonzalez Update herokuish requirement to better support readonly containers
### Documentation
- #6788: @bumblefudge Fix typos in nginx documentation
- #6789: @crazehang Fix typos in documentation
### Dependencies
- #6786: @dependabot[bot] chore(deps): bump werkzeug from 3.0.1 to 3.0.2 in /tests/apps/python-flask
- #6787: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.16 to 9.5.17 in /docs/_build
- #6782: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.15 to 9.5.16 in /docs/_build
# History
## 0.34.2
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.2/bootstrap.sh
sudo DOKKU_TAG=v0.34.2 bash bootstrap.sh
```
### Bug Fixes
- #6779: @josegonzalez Add --global flag to ps:set
- #6778: @josegonzalez Popd out of tmp directory after a git push-based deployment
- #6777: @josegonzalez Use correct function name in openresty:report output
### Documentation
- #6781: @josegonzalez Update builder management docs to warn that globally setting a builder will force all apps to use that builder
- #6780: @josegonzalez Clarify ssh-keys commands to run when adding ssh keys in docker-based installation
### Other
- #6776: @josegonzalez Use a long git sha in the git:report output
The previous method sometimes truncated the sha, depending on how the app was deployed. Using the long sha will ensure that the value is stable, regardless of the deployment method.
Closes#6770
# History
## 0.34.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.1/bootstrap.sh
sudo DOKKU_TAG=v0.34.1 bash bootstrap.sh
```
### Bug Fixes
- #6775: @josegonzalez Ensure files get created with the correct permissions when building with herokuish
- #6739: @AndrewKvalheim Dereference annotated git tags when deploying via git:sync
- #6743: @testwill Fix typo in app-json output
### New Features
- #6768: @josegonzalez Migrate away from transitional packages
### Documentation
- #6763: @iloveitaly Add docker-compose example to installation docs
- #6757: @josegonzalez Add documentation issue template
- #6742: @josegonzalez Remove trailing whitespace from history doc
### Dependencies
- #6772: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 43.0.1 to 44.0.0
- #6766: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.14 to 9.5.15 in /docs/_build
- #6744: @dependabot[bot] chore(deps): bump github.com/docker/docker from 24.0.7+incompatible to 24.0.9+incompatible in /plugins/scheduler-k3s
- #6754: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/dockerfile-app-json-formations
- #6745: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/nodejs-express
- #6746: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 43.0.0 to 43.0.1
- #6747: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/.websocket.disabled
- #6748: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/nodejs-express-noprocfile
- #6749: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/nodejs-express-noappjson
- #6750: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/dockerfile-procfile-bad
- #6751: @dependabot[bot] chore(deps): bump importlib-metadata from 7.0.2 to 7.1.0 in /docs/_build
- #6752: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/dockerfile-procfile
- #6753: @dependabot[bot] chore(deps): bump express from 4.18.3 to 4.19.1 in /tests/apps/gitsubmodules
- #6741: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.31.1 to 1.32.0 in /plugins/common
- #6740: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.31.1 to 1.32.0 in /plugins/config
Several of the packages being installed were actually transitional packages, that is, the package itself is either a complete no-op (since the package is already installed), or else the package only exists to depend on another package of a new name (to support people who are running older operating systems).
For the former, we can drop the dependency entirely, and for the latter we should use the new package name directly.
refs/heads/master cannot be updated to an annotated tag per se; the rev
given must first be resolved to a commit. ^{commit} recursively
dereferences the rev until a commit is found.
Resolves#6737 and test failure:
# bats --filter annotated-tag tests/unit/git_3.bats
git_3.bats
✗ (git) git:sync existing [--no-build annotated-tag]
fatal: update_ref failed for ref 'refs/heads/master': cannot update ref 'refs/heads/master': trying to write non-commit object 6399bed673f513332f3d5d99e777e0262f42404c to branch 'refs/heads/master'
# History
## 0.34.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.34.0/bootstrap.sh
sudo DOKKU_TAG=v0.34.0 bash bootstrap.sh
```
See the [0.34.0 migration guide](/docs/appendices/0.34.0-migration-guide.md) for more information on migrating to 0.34.0.
### Bug Fixes
- #6724: @josegonzalez Correctly check if a repository has code or not in git plugin
- #6721: @josegonzalez Correct issue where cron properties cannot be retrieved if global
- #6720: @josegonzalez Add nginx-property binary to gitignore
- #6708: @josegonzalez Correctly handle quoted spaces over ssh
- #6707: @josegonzalez Correct issue where removing by index failed due to incorrect input validation
- #6705: @josegonzalez Ensure we cleanup the data directory on app deletion
- #6703: @josegonzalez Use copytruncate in logrotate commands
### New Features
- #6725: @josegonzalez Warn when publish ports if scaling up or zero downtime is enabled
- #6719: @josegonzalez Add a make target to copy the dokku binary over
- #6717: @josegonzalez Add ability to only build synced repo if there are changes
- #6715: @josegonzalez Add disk utilization to report output
- #6704: @josegonzalez Switch the default k3s routing layer from traefik to nginx
### Removals
- #6700: @josegonzalez Remove priority property from traefik plugin
### Refactors
- #6714: @josegonzalez Use CallPlugnTrigger instead of PlugnTriggerSetup
- #6713: @josegonzalez Use CallPlugnTrigger instead of PlugnTrigger
- #6712: @josegonzalez Use CallPlugnTrigger instead of PlugnTriggerOutput
- #6711: @josegonzalez Use CallPlugnTrigger instead of PlugnTriggerOutputAsString
- #6681: @josegonzalez Migrate to single ingress per app/domain combination when using nginx for k3s proxying
- #6156: @josegonzalez Migrate the app deploy lock to the data directory
### Documentation
- #6738: @josegonzalez Update migration guide for 0.34.x
- #6731: @strugee Clarify alternate proxy support status
### Dependencies
- #6736: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.13 to 9.5.14 in /docs/_build
- #6729: @dependabot[bot] chore(deps): update markdown requirement from <3.6,>=3.2.1 to >=3.2.1,<3.7 in /docs/_build
- #6728: @dependabot[bot] chore(deps): bump zipp from 3.17.0 to 3.18.1 in /docs/_build
- #6727: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.1.0 to 43.0.0
- #6723: @dependabot[bot] chore(deps): bump zipp from 3.17.0 to 3.18.0 in /docs/_build
- #6722: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.1.0 to 43.0.0
- #6710: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.32.0 to 1.33.0 in /plugins/scheduler-k3s
- #6709: @dependabot[bot] chore(deps): bump zipp from 3.17.0 to 3.18.0 in /docs/_build
### Other
- #6718: @josegonzalez Write current process id to all acquired lock files
- #6706: @josegonzalez Remove git:unlock command
- #6650: @bastianh Do not expose all containers via traefik by default
- #6632: @josegonzalez Simplify file ownership in the container by setting the process ownership during the build process
- #6630: @josegonzalez Remove unused code for copying cache directories
This allows us to check on what process created a lock.
Additionally, we now always have a DOKKU_PID value, even when running in cron (which does not have access to BASH_PID.
How the output is streamed changed a bit so we need to change the bats test
This will go back to zero if we ever re-implement how the container up starts for the docker-local scheduler.
These two are also still stored in the app repo directory and not copied over as properties, so would be susceptible to not having the code copied over.
The ingress-nginx ingress implementation is the standard ingress in the Kubernetes community, and it doesn't make sense for us to stray from that just to utilize the k3s default.
In the future, we might drop k3s, but this works well for now.
While using create is more correct, logs in Dokku are considered ephemeral, and thus shouldn't be considered subject to the more comprehensive log retention standards one might require out of a logging system.
By switching to copytruncate, we can ensure that logs mounted from within containers do not have that matched the old settings (closes#6633) and cases where the log file is written by a user other than the one specified in the old logrotate settings (closes#4000).
# History
## 0.33.9
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.9/bootstrap.sh
sudo DOKKU_TAG=v0.33.9 bash bootstrap.sh
```
### Bug Fixes
- #6695: @josegonzalez Do not attempt to install both k3s and traefik
- #6687: @josegonzalez Correct issue where ClusterTriggerAuthentication objects were filtered based on prefix
- #6686: @josegonzalez Validate input for the autoscaling-auth:set command
- #6678: @josegonzalez Handle case where most builders didn't detect amd64 images on arm64
- #6677: @josegonzalez Handle case where keda isn't installed properly
- #6676: @josegonzalez Drop extra logging call from app-json plugin
- #6674: @josegonzalez Remove systemd reverse dependency by dropping software-properties-common
### New Features
- #6698: @josegonzalez Upgrade ingress-nginx
- #6588: @taraszka Add extra tags to every image dokku push when push-extra-tags are set
- #6680: @josegonzalez Wait until helm charts are installed before marking a deploy as failed or completed
### Documentation
- #6699: @josegonzalez Add a placeholder migration guide for 0.33.0
- #6682: @josegonzalez Fix reference to formation key in autoscaling example
### Tests
- #6696: @josegonzalez Run k3s tests with a specified server ip
- #6679: @josegonzalez Split out k3s tests to speed up ci
### Dependencies
- #6697: @dependabot[bot] chore(deps): bump timberio/vector from 0.36.0-debian to 0.36.1-debian in /plugins/logs
- #6685: @dependabot[bot] chore(deps): bump github.com/go-jose/go-jose/v3 from 3.0.1 to 3.0.3 in /plugins/scheduler-k3s
- #6692: @dependabot[bot] chore(deps): bump packaging from 23.2 to 24.0 in /docs/_build
- #6693: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.7 to 42.1.0
- #6689: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.6 to 42.0.7
- #6683: @dependabot[bot] chore(deps): bump importlib-metadata from 7.0.1 to 7.0.2 in /docs/_build
- #6684: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.5 to 42.0.6
Rather than require a heavy chown operation across various paths, just chown the files already in the built image during the release process. This ensures we can skip not-only the chown process during the container start that herokuish injects, but also the one that Dokku runs which modifies mounted container paths as well during the pre-deploy.
Note that users will need to ensure any mounted volumes don't have permissions reset by other processes or containers won't be able to access them.
Setting a priority appears to cause minor outages in certain cases, so we should just avoid setting it on behalf of users and allow them to set this directly.
Domains cannot be reused across ingress objects, and port maps are a function of a domain, so the inversion here makes most sense (at the cost of some downtime when migrating.
Images would build but then fail to be tagged, causing deployment problems on arm64 architectures for a small number of images.
Also fix a minor issue in the nixpacks builder that caused any pre-release-builder triggers that consumed the image to get an empty string instead.
If keda is not installed, warn the user that it isn't installed and ignore the rest.
Ignoring the error here is fine as it gives the user context but doesn't block a deploy.
# History
## 0.33.8
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.8/bootstrap.sh
sudo DOKKU_TAG=v0.33.8 bash bootstrap.sh
```
### Bug Fixes
- #6675: @josegonzalez Remove the need for executing crontab as root
- #6660: @josegonzalez Handle case where systemctl isn't in /usr/bin
- #6659: @josegonzalez Add missing cron:set command
- #6658: @josegonzalez Execute go get/build with mod in readonly mode
- #6642: @josegonzalez Use correct annotations key for the ingress chart
- #6631: @josegonzalez Correctly use cache volume for herokuish builds
- #6629: @josegonzalez Use smaller reference to image pull secrets in secret naming
- #6628: @josegonzalez Ensure non-web processes do not attempt to perform web logic in k3s templates
- #6623: @josegonzalez Do not allow reusing the same scheme:host-port mappings when setting ports
- #6624: @taraszka Install jq in vagrant vm
- #6614: @josegonzalez Correct issue where --force-tty was not properly supported by run:detached calls
### New Features
- #6673: @josegonzalez Add image version as label to built images
- #6640: @josegonzalez Add initial support for injecting keda addons
- #6662: @josegonzalez Allow limiting letsencrypt to certain domains when using openresty as a proxy
- #6643: @josegonzalez Add ability to add extra labels
- #6639: @josegonzalez Add support for setting underscores-in-headers for nginx, openresty, and k3s
- #6634: @josegonzalez feat: install keda addon in k3s cluster
- #6616: @josegonzalez Ensure referenced images get updated by dependabot
- #6613: @josegonzalez Add a helper binary to deploy a test app for local development
### Refactors
- #6644: @josegonzalez Only apply the cluster issuers helm chart when setting letsencrypt properties
- #6641: @josegonzalez Rename image pull secrets to standardize on secret naming pattern
- #6626: @josegonzalez Copy code into initial base image via docker build
### Documentation
- #6656: @holamendi Fix typo in builder management docs
- #6652: @Calyhre Added dokku-mdns to list of community plugins
- #6649: @undercontr Added detach flag to Docker installation documentation
### Dependencies
- #6671: @josegonzalez Update dokku dependencies
- #6672: @dependabot[bot] chore(deps): bump golang from 1.22.0 to 1.22.1 in /tests/apps/go-fail-predeploy
- #6670: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.62.0 to 1.62.1 in /tests/apps/gogrpc
- #6669: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.32.0 to 1.33.0 in /tests/apps/gogrpc
- #6668: @dependabot[bot] chore(deps): bump golang from 1.22.0 to 1.22.1 in /tests/apps/zombies-dockerfile-tini
- #6667: @dependabot[bot] chore(deps): bump golang from 1.22.0 to 1.22.1 in /tests/apps/gogrpc
- #6664: @dependabot[bot] chore(deps): bump golang from 1.22.0 to 1.22.1 in /tests/apps/go-fail-postdeploy
- #6666: @dependabot[bot] chore(deps): bump pyparsing from 3.1.1 to 3.1.2 in /docs/_build
- #6665: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.12 to 9.5.13 in /docs/_build
- #6663: @dependabot[bot] chore(deps): bump golang from 1.22.0 to 1.22.1 in /tests/apps/zombies-dockerfile-no-tini
- #6661: @josegonzalez Bump go modules
- #6654: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.7 to 10.7.1 in /docs/_build
- #6653: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.20.0 to 0.21.0 in /plugins/common
- #6651: @dependabot[bot] chore(deps): bump python-dateutil from 2.9.0 to 2.9.0.post0 in /docs/_build
- #6648: @dependabot[bot] chore(deps): bump python-dateutil from 2.8.2 to 2.9.0 in /docs/_build
- #6645: @dependabot[bot] chore(deps): bump rack from 2.2.8 to 2.2.8.1 in /tests/apps/ruby
- #6646: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.11 to 9.5.12 in /docs/_build
- #6638: @josegonzalez chore: bump go modules
- #6635: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.4 to 42.0.5
- #6636: @dependabot[bot] chore(deps): bump timberio/vector from 0.36.X-debian to 0.36.0-debian in /plugins/logs
- #6637: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.19.0 to 0.20.0 in /plugins/common
- #6619: @dependabot[bot] chore(deps): bump traefik from v2.10 to 2.11 in /plugins/traefik-vhosts
- #6622: @josegonzalez chore(deps): bump timberio/vector from 0.35.X-debian to 0.36.X-debian in /plugins/logs
- #6618: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.10 to 9.5.11 in /docs/_build
- #6621: @dependabot[bot] chore(deps): bump byjg/easy-haproxy from 4.3.0 to 4.4.0 in /plugins/haproxy-vhosts
- #6610: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.14.1 to 3.14.2 in /plugins/scheduler-k3s
Through some random machinations, software-properties-common now has a dependency on systemd. This breaks the built docker image as plugins will think systemd is available, so `dokku plugin:install --core` will reference that over sv.
Since we don't manage ppas in Dokku anymore - the only use was for an nginx ppa so we could use a newer Nginx - this can be safely removed.
Also remove some other stuff related to systemd that aren't required anymore.
This was done by design previously - to fix an issue with RHEL not allowing running crontab as the current user - but is no longer necessary with the removal of non-Debian platform support.
The newer version is pulled by something in k3s and somehow is - probably through workspace magic - pulled into the config plugin tests. We pin to the older version since parsing changed at some point, which will cause issues for users.
A future update should move this to the latest version and cause a BC break, but for now lets pin as expected.
In most cases, it should be there, but it appears that system upgrades from Ubuntu 16.04 sometimes do not have usr-merge setup. As such, we need to fallback to the /bin/systemctl path if it exists.
This will avoid issues where a build or test will inadvertently update dependencies, causing drift between what is in code and what is being tested/run.
Rather than try to mount a directory into the container and use a symlink, directly mount the volume in.
Note that this requires deleting the task container prior to continuing in order to ensure the volume isn't still mounted prior to other tasks being executed.
The previous method used an ephemeral container, which was slightly more convoluted and required cleanup. The new method also allows us to set an initial WORKDIR, which is useful for ensuring 'docker exec' works as expected.
This doesn't make sense as a port can't be listened to twice on the same domain, so instead we should just fail immediately if someone attempts to perform this action.
Refs dokku/dokku-letsencrypt#269
Dokku uses a few external images for various bits of functionality, but these must be manually updated every so often due to being referenced in code.
By moving the references to Dockerfiles, we can take advantage of dependabot to issue automatic PRs when they are out of date.
# History
## 0.33.7
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.7/bootstrap.sh
sudo DOKKU_TAG=v0.33.7 bash bootstrap.sh
```
### Bug Fixes
- #6608: @josegonzalez Fix issue with setting k3s resource values and lower the initial default values
- #6607: @josegonzalez Call sed in unbuffered form to ensure log output is streamed to stdout
- #6600: @josegonzalez Use correct label key for worker nodes
- #6593: @josegonzalez Remove extra trailing newline to fix govet issue
### New Features
- #6595: @josegonzalez Add ability for users to specify alternative kubeconfig and kubecontext
### Refactors
- #6594: @josegonzalez Remove all calls to common.NewShellCmd
- #6592: @josegonzalez Remove all calls to common.NewShellCmdWithArgs
- #6591: @josegonzalez Always capture stdout/stderr when executing subprocesses
- #6590: @josegonzalez Remove all direct usage of go-sh outside of plugin trigger setup
### Dependencies
- #6609: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.61.1 to 1.62.0 in /tests/apps/gogrpc
- #6604: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.9 to 9.5.10 in /docs/_build
- #6603: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.2 to 42.0.4
- #6601: @dependabot[bot] chore(deps): bump helm.sh/helm/v3 from 3.13.3 to 3.14.1 in /plugins/scheduler-k3s
- #6596: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.61.0 to 1.61.1 in /tests/apps/gogrpc
This will provide the possibility for users to talk to existing kubernetes clusters, thereby removing one of the biggest reasons for having the old scheduler-kubernetes plugin around.
The new exec callers somehow setup the environment differently, causing sed to not properly detect that it should run in unbuffered form. This change forces sed to run in unbuffered mode.
Closes#6602
This is almost certainly the correct default for Dokku. While it's a BC break and might cause an increase in memory usage, the api is mostly internal and therefore this is safe to use.
# History
## 0.33.6
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.6/bootstrap.sh
sudo DOKKU_TAG=v0.33.6 bash bootstrap.sh
```
### Bug Fixes
- #6589: @josegonzalez Use image pull secrets instead of registries.yaml to reference private repositories when deploying via k3s
- #6581: @josegonzalez Fix issues in tls handling when deploying via k3s
- #6582: @josegonzalez Correctly handle extra whitespace in scale file contents
- #6390: @renweibo Prefer systemctl over sv when both exist while restarting nginx
- #6579: @josegonzalez Ensure k3s can be installed with taints
### New Features
- #6585: @josegonzalez Add more context to errors in fetching cron entries
- #6583: @josegonzalez Add WithContext functions for all subprocess-related code
### Refactors
- #6584: @josegonzalez Use new CallExecCommand when checking to see how help is being called
### Dependencies
- #6586: @dependabot[bot] chore(deps): bump mvdan.cc/sh/v3 from 3.7.0 to 3.8.0 in /plugins/cron
- #6587: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.8 to 9.5.9 in /docs/_build
- #6381: @dependabot[bot] chore(deps): bump actions/upload-artifact from 3 to 4
- #6578: @josegonzalez Bump go modules
### Other
- #6576: @Tashows Allow creating a detached container with TTY enabled for attaching remote terminal
While this will now more or less require a local docker login - which can be overridden by setting the image-pull-secrets property - this ensures every deploy has a valid context.
One annoying thing is that the secret is per-app vs global, meaning that if the secret must be rotated, all apps need to be redeployed. A future change can fix that by deploying a global secret, or if folks really desire, this can be done by setting the image-pull-secrets property on the app/globally.
# History
## 0.33.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.5/bootstrap.sh
sudo DOKKU_TAG=v0.33.5 bash bootstrap.sh
```
### Bug Fixes
- #6574: @josegonzalez Correct indentation when configuring https on a k3s app
### Documentation
- #6575: @josegonzalez Remove reference to web ui from digitalocean install documentation
### Dependencies
- #6573: @dependabot[bot] chore(deps): bump golang from 1.21.6 to 1.22.0 in /tests/apps/go-fail-postdeploy
- #6569: @dependabot[bot] chore(deps): bump golang from 1.21.6 to 1.22.0 in /tests/apps/go-fail-predeploy
- #6570: @dependabot[bot] chore(deps): bump golang.org/x/crypto from 0.18.0 to 0.19.0 in /plugins/common
- #6571: @dependabot[bot] chore(deps): bump golang from 1.21.6 to 1.22.0 in /tests/apps/zombies-dockerfile-tini
- #6572: @dependabot[bot] chore(deps): bump python from 3.12.1-alpine to 3.12.2-alpine in /docs/_build
# History
## 0.33.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.4/bootstrap.sh
sudo DOKKU_TAG=v0.33.4 bash bootstrap.sh
```
### Bug Fixes
- #6564: @josegonzalez Ignore link and volume flags for nixpacks builds
- #6563: @josegonzalez Wait until initial k3s node is ready before installing manifests
- #6561: @josegonzalez Index the process map to ensure the correct config is pulled
- #6560: @josegonzalez Skip app stop/delete when k3s is not installed
- #6559: @josegonzalez Check errors when writing properties
- #6556: @josegonzalez Respect the release namespace when creating resources for a k3s deploy
### New Features
- #6562: @josegonzalez Add support for specifying annotations on kubernetes resources
- #6555: @josegonzalez Add support for app-specific service accounts when deploying via k3s
- #6546: @josegonzalez Install kubectx and kubens helper binaries when setting up a k3s cluster
### Refactors
- #6558: @josegonzalez Use type-specific functions for writing contents to a file
- #6557: @josegonzalez Consolidate property fetching for nginx plugin into golang codebase
- #6536: @josegonzalez Manage vector container via compose
### Documentation
- #6545: @josegonzalez Migrate markdown doc rewriting into mkdocs hooks
### Tests
- #6554: @josegonzalez Fix issue where CI cannot install docker-buildx-plugin
### Dependencies
- #6568: @dependabot[bot] chore(deps): bump golang from 1.21.6 to 1.22.0 in /tests/apps/gogrpc
- #6567: @dependabot[bot] chore(deps): bump watchdog from 3.0.0 to 4.0.0 in /docs/_build
- #6566: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.7 to 9.5.8 in /docs/_build
- #6565: @dependabot[bot] chore(deps): bump golang from 1.21.6 to 1.22.0 in /tests/apps/zombies-dockerfile-no-tini
- #6551: @dependabot[bot] chore(deps): bump flask from 3.0.1 to 3.0.2 in /tests/apps/multi
- #6552: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.6 to 9.5.7 in /docs/_build
- #6553: @dependabot[bot] chore(deps): bump markupsafe from 2.1.4 to 2.1.5 in /docs/_build
- #6550: @dependabot[bot] chore(deps): bump flask from 3.0.1 to 3.0.2 in /tests/apps/python-flask
- #6548: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.19 to 11.0.20 in /tests/apps/java
### Other
- #6547: @josegonzalez Add support for nginx as a k3s ingress implementation
# History
## 0.33.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.3/bootstrap.sh
sudo DOKKU_TAG=v0.33.3 bash bootstrap.sh
```
### Bug Fixes
- #6542: @josegonzalez Drop -- when calling dokku run for cron-tab templating
### Documentation
- #6543: @josegonzalez Add support for badge shortcodes in documentation
# History
## 0.33.2
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.2/bootstrap.sh
sudo DOKKU_TAG=v0.33.2 bash bootstrap.sh
```
### Bug Fixes
- #6535: @josegonzalez Properly fetch default vector image if none is passed
- #6533: @josegonzalez Ensure all k3s traefik middleware resources are scoped to the process
- #6524: @josegonzalez Ensure all copied files always have line endings converted to unix-style
### New Features
- #6537: @josegonzalez Add the dokku logo as the chart icon
- #6527: @josegonzalez Upgrade vector image to 0.35.x
- #6534: @josegonzalez Allow specifying an ingress class via chart value
### Documentation
- #6530: @josegonzalez Fix indentation on letsencrypt sections for k3s scheduler docs
### Tests
- #6532: @josegonzalez Correct issues in tests for vector image log property
### Dependencies
- #6540: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.5 to 9.5.6 in /docs/_build
- #6538: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.1 to 42.0.2
- #6528: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 42.0.0 to 42.0.1
- #6529: @dependabot[bot] chore(deps): bump google.golang.org/protobuf from 1.31.0 to 1.32.0 in /tests/apps/gogrpc
### Other
- #6526: @josegonzalez Allow setting the vector image as a global property
Using compose instead of manual docker calls allows folks to customize the vector container by using a custom compose.yml template file. This opens us up to more customizations while aligning container management with how we do other external containers (such as for the proxy plugins).
Refs #5784
# History
## 0.33.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.33.0/bootstrap.sh
sudo DOKKU_TAG=v0.33.0 bash bootstrap.sh
```
### Bug Fixes
- #6466: @josegonzalez Use correct key for migrating global scheduler configuration on upgrade
- #6450: @josegonzalez Always set -- on docker run commands internally to avoid parsing flags on specified commands
- #6447: @josegonzalez Propagate arm64 build support for development builds
- #6445: @josegonzalez Do not strip whitespace when displaying a file for debugging purposes
- #6442: @josegonzalez Ignore go.work when bumping modules
- #6427: @josegonzalez Add missing gitignore entry for app-json trigger
### New Features
- #6500: @josegonzalez Add support for custom user namespaces when creating persistent storage directories
- #6492: @josegonzalez Add support for multierror when exiting triggers
- #6491: @josegonzalez Add wrappers for exec and ssh commands
- #6489: @josegonzalez Disable flag parsing for dokku enter
- #6469: @josegonzalez Allow generating an ssh deploy key via the git plugin
- #6468: @josegonzalez Implement global support for setting proxy type
- #6467: @josegonzalez Add ability to customize the registry repo with a template
- #6464: @josegonzalez Create helper function for exposing a docker image's working directory
- #6462: @josegonzalez Ensure ps:stop has a proper cli header
- #6460: @josegonzalez Add a post-registry-login trigger
- #6459: @josegonzalez Alias common registry names to docker.io
- #6457: @josegonzalez Add the ability to specify the output format when listing ports
- #6452: @josegonzalez Add alternative implementation for calling plugin triggers
- #6446: @josegonzalez Add support for global-only environment properties
- #6443: @josegonzalez Add support for exposing healthchecks in the AppJson struct
- #6435: @josegonzalez Implement native k3s scheduler support
- #6433: @josegonzalez Add go.work.sum to gitignore
- #6432: @josegonzalez Upgrade golang to 1.21.6
- #6430: @josegonzalez Reformat devcontainer file
- #6428: @josegonzalez Add ms-azuretools.vscode-docker to devcontainer setup
- #6313: @josegonzalez Set the platform flag in order to run amd64 images on arm64 deploy targets
### Refactors
- #6448: @josegonzalez Return an int32 for scale count
- #6444: @josegonzalez Allow setting a custom mode when writing a slice to a file
### Documentation
- #6517: @josegonzalez Remove k3s tutorial from documentation
- #6516: @josegonzalez Note that the external kubernetes plugin is deprecated
- #6515: @josegonzalez Replace the kubernetes plugin with k3s in the documentation
- #6514: @josegonzalez Add notes on k3s replacement of the scheduler-kubernetes plugin
- #6461: @josegonzalez Add documentation for implementing scheduler-related commands
- #6458: @josegonzalez Add docblocks to appjson structs
- #6420: @aochagavia Fix typo in zero downtime documentation
### Tests
- #6465: @josegonzalez Update haproxy tests so they pass
- #6449: @josegonzalez Run ci on ubuntu 22.04
- #6431: @josegonzalez Add golanglint-ci testing support
### Dependencies
- #6513: @dependabot[bot] chore(deps): bump github.com/containerd/containerd from 1.7.6 to 1.7.11 in /plugins/scheduler-k3s
- #6512: @josegonzalez Update github.com/gonsi/gomega golang dependency
- #6511: @josegonzalez Update crypto and sys golang dependencies
- #6494: @dependabot[bot] chore(deps): bump markupsafe from 2.1.3 to 2.1.4 in /docs/_build
- #6482: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.3 to 9.5.4 in /docs/_build
- #6478: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/zombies-dockerfile-tini
- #6456: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.29.1 to 1.60.1 in /tests/apps/gogrpc
- #6454: @dependabot[bot] chore(deps): bump flask from 3.0.0 to 3.0.1 in /tests/apps/python-flask
- #6455: @dependabot[bot] chore(deps): bump flask from 3.0.0 to 3.0.1 in /tests/apps/multi
- #6453: @josegonzalez Remove ignored dependency from dependabot
- #6451: @josegonzalez Update go modules
- #6439: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.30.0 to 1.31.0 in /plugins/config
- #6438: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.30.0 to 1.31.0 in /plugins/common
- #6437: @dependabot[bot] chore(deps): bump beautifulsoup4 from 4.12.2 to 4.12.3 in /docs/_build
- #6436: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 41.1.1 to 42.0.0
- #6425: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 41.0.1 to 41.1.1
- #6424: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.3 to 9.5.4 in /docs/_build
- #6421: @josegonzalez chore: bump golang.org/x/sync from 0.5.0 to 0.6.0
- #6419: @dependabot[bot] chore(deps): bump jinja2 from 3.1.2 to 3.1.3 in /docs/_build
- #6418: @dependabot[bot] chore(deps): bump jinja2 from 3.1.2 to 3.1.3 in /tests/apps/python-flask
- #6415: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/go-fail-postdeploy
- #6414: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/gogrpc
- #6413: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/go-fail-predeploy
- #6412: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/zombies-dockerfile-no-tini
- #6411: @dependabot[bot] chore(deps): bump golang from 1.21.5 to 1.21.6 in /tests/apps/zombies-dockerfile-tini
- #6410: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.19.0 to 0.20.0 in /tests/apps/gogrpc
- #6406: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.5.0 to 0.6.0 in /plugins/scheduler-docker-local
### Other
- #6463: @josegonzalez Use exported function from appjson module instead of manually parsing
- #6429: @josegonzalez Use go.work for development purposes
The previous mechanism of constructing the helm chart was pretty obnoxious due to needing to have some things in the object and some in template files that were appended afterwards. This change simplifies that by using template files per type with minimal replacements.
The idea here is that only k3s nodes can/should handle certificate requests. While users may wish to force these onto dedicated lb nodes in the future, at least for now, separating app workloads with routing seems like an okay trade-off.
Different options get applied to each depending on what is needed for the role.
This also updates how we initialize the cluster to better support how metrics exposure and cross-server networking.
The cron id is too long to store in the cronjob, so we generate a short identifier and look that up each time on deploy to ensure stability across time.
This utilizes a Kubernetes Job to start a pod in order to take advantage of completed Job cleanup in Kubernetes. It also properly handles interactivity by ensuring the container has a TTY.
Note that there is currently no provision for parsing docker arguments and translating them into their Kubernetes equivalents.
The big feature missing from deployments today is healthchecks, which require extra parsing of the app.json format since the healthchecks there aren't immediately serializable to kubernetes deployment healthchecks.
Other smaller missing functionality from the existing OSS kubernetes scheduler are:
- The ability to set custom pod annotations
- The ability to set custom deployment annotations
- The ability to mount volumes
Exposing these pieces of functionality will come at a later date, if at all.
While this might not seem super intuitive, the key is mostly related to git management, not the ssh-keys we currently use to add/remove access to push to dokku.
# History
## 0.32.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.32.4/bootstrap.sh
sudo DOKKU_TAG=v0.32.4 bash bootstrap.sh
```
### Bug Fixes
- #6407: @josegonzalez Upgrade ruby to fix the release process
- #6394: @josegonzalez Scope the delete of symlinked plugins in debian post-install to the plugin folders
### Refactors
- #6388: @Juneezee Replace deprecated `io/ioutil` functions
### Documentation
- #6385: @josegonzalez Fix docblock entries for properties in plugins
- #6384: @josegonzalez Cleanup some markdown in documentation
- #6365: @josegonzalez Split out archive/image deployment docs into their own file
### Tests
- #6408: @josegonzalez Add options to the release workflow
- #6359: @josegonzalez Update buildpack api for test buildpack
### Dependencies
- #6399: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.5 to 10.7 in /docs/_build
- #6398: @dependabot[bot] chore(deps): bump sinatra from 3.1.0 to 3.2.0 in /tests/apps/ruby
- #6395: @dependabot[bot] chore(deps): bump ruby from 3.2.2 to 3.3.0 in /tests/apps/dockerfile-entrypoint
- #6391: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.2 to 9.5.3 in /docs/_build
- #6392: @dependabot[bot] chore(deps): bump importlib-metadata from 7.0.0 to 7.0.1 in /docs/_build
- #6393: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.2.3 to 41.0.1
- #6387: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.18 to 11.0.19 in /tests/apps/java
- #6386: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.2.2 to 40.2.3
- #6377: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.2.1 to 40.2.2
- #6380: @dependabot[bot] chore(deps): bump github/codeql-action from 2 to 3
- #6379: @dependabot[bot] chore(deps): bump mkdocs-material from 9.5.1 to 9.5.2 in /docs/_build
- #6378: @dependabot[bot] chore(deps): bump python from 3.12.0-alpine to 3.12.1-alpine in /docs/_build
- #6376: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.14 to 9.5.1 in /docs/_build
- #6371: @dependabot[bot] chore(deps): bump golang from 1.21.4 to 1.21.5 in /tests/apps/gogrpc
- #6369: @dependabot[bot] chore(deps): bump golang from 1.21.4 to 1.21.5 in /tests/apps/zombies-dockerfile-tini
- #6368: @dependabot[bot] chore(deps): bump golang from 1.21.4 to 1.21.5 in /tests/apps/zombies-dockerfile-no-tini
- #6367: @dependabot[bot] chore(deps): bump importlib-metadata from 6.8.0 to 7.0.0 in /docs/_build
- #6366: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.2.0 to 40.2.1
- #6370: @dependabot[bot] chore(deps): bump golang from 1.21.4 to 1.21.5 in /tests/apps/go-fail-predeploy
- #6372: @dependabot[bot] chore(deps): bump golang from 1.21.4 to 1.21.5 in /tests/apps/go-fail-postdeploy
- #6373: @dependabot[bot] chore(deps): bump actions/setup-python from 4 to 5
- #6364: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.18.0 to 0.19.0 in /tests/apps/gogrpc
- #6361: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.4 to 10.5 in /docs/_build
- #6362: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.12 to 9.4.14 in /docs/_build
- #6360: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.1.1 to 40.2.0
- #6357: @dependabot[bot] chore(deps): bump mkdocs-material-extensions from 1.3 to 1.3.1 in /docs/_build
- #6355: @dependabot[bot] chore(deps): bump pygments from 2.16.1 to 2.17.2 in /docs/_build
- #6358: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.8 to 9.4.12 in /docs/_build
- #6348: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.3.1 to 10.4 in /docs/_build
Previously, we would try and traverse the entire dokku lib directory, causing extremely slow updates for installations with lots of data. This would also potentially cause issues for anyone using symlinks in their data directories.
Instead, just remove symlinks in the plugin directories.
The io/ioutil package has been deprecated as of Go 1.16 [1]. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.
[1]: https://golang.org/doc/go1.16#ioutil
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
# History
## 0.32.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.32.3/bootstrap.sh
sudo DOKKU_TAG=v0.32.3 bash bootstrap.sh
```
### Bug Fixes
- #6345: @josegonzalez Use updated pre-build trigger for builder-herokuish
### New Features
- #6346: @josegonzalez Update all go modules and add a command to bump modules
### Documentation
- #6339: @nschlemm Fixed link to vector sink documentation
- #6314: @josegonzalez Remove reference to DOKKU_SCHEDULER environment variable in favor of scheduler:set
- #6317: @edmorley Replace deprecated builder reference in persistent-storage.md
- #6325: @josegonzalez Add documentation on openresty includes
### Dependencies
- #6343: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.17.0 to 0.18.0 in /tests/apps/gogrpc
- #6338: @dependabot[bot] chore(deps): bump golang from 1.21.3 to 1.21.4 in /tests/apps/go-fail-postdeploy
- #6337: @dependabot[bot] chore(deps): bump golang from 1.21.3 to 1.21.4 in /tests/apps/gogrpc
- #6336: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.0.2 to 40.1.1
- #6335: @dependabot[bot] chore(deps): bump golang from 1.21.3 to 1.21.4 in /tests/apps/go-fail-predeploy
- #6334: @dependabot[bot] chore(deps): bump golang from 1.21.3 to 1.21.4 in /tests/apps/zombies-dockerfile-tini
- #6333: @dependabot[bot] chore(deps): bump golang from 1.21.3 to 1.21.4 in /tests/apps/zombies-dockerfile-no-tini
- #6328: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.7 to 9.4.8 in /docs/_build
- #6320: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.17 to 11.0.18 in /tests/apps/java
- #6318: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.6 to 9.4.7 in /docs/_build
- #6322: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 40.0.0 to 40.0.2
- #6323: @dependabot[bot] chore(deps): bump django from 4.1.10 to 4.1.13 in /tests/apps/dockerfile-release
### Other
- #6315: @josegonzalez Correct key in dependency file to fix docker-container-healthchecker installs on local arm64 servers
# History
## 0.32.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.32.1/bootstrap.sh
sudo DOKKU_TAG=v0.32.1 bash bootstrap.sh
```
### Bug Fixes
- #6286: @josegonzalez Remove trailing quote on openresty letsencrypt email
- #6287: @josegonzalez Recursively delete old custom openresty includes
### New Features
- #6303: @josegonzalez feat: add the ability to specify location-block includes
### Documentation
- #6288: @josegonzalez Add missing link to nixpacks builder
### Dependencies
- #6306: @dependabot[bot] chore(deps): bump org.apache.maven.plugins:maven-dependency-plugin from 3.6.0 to 3.6.1 in /tests/apps/java
- #6301: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.28.0 to 1.28.1 in /plugins/config
- #6304: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.2.3 to 39.2.4
- #6305: @dependabot[bot] chore(deps): bump actions/setup-node from 3 to 4
- #6297: @dependabot[bot] chore(deps): bump node from 20-alpine to 21-alpine in /tests/apps/dockerfile-procfile
- #6292: @dependabot[bot] chore(deps): bump node from 20-alpine to 21-alpine in /tests/apps/dockerfile-procfile-bad
- #6293: @dependabot[bot] chore(deps): bump node from 20-alpine to 21-alpine in /tests/apps/dockerfile
- #6294: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.3 to 10.3.1 in /docs/_build
- #6295: @dependabot[bot] chore(deps): bump node from 20-alpine to 21-alpine in /tests/apps/dockerfile-app-json-formations
- #6296: @dependabot[bot] chore(deps): bump node from 20-alpine to 21-alpine in /tests/apps/dockerfile-noexpose
- #6289: @dependabot[bot] chore(deps): bump mkdocs-material-extensions from 1.2 to 1.3 in /docs/_build
- #6290: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.2.2 to 39.2.3
# History
## 0.32.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.32.0/bootstrap.sh
sudo DOKKU_TAG=v0.32.0 bash bootstrap.sh
```
See the [0.32.0 migration guide](/docs/appendices/0.32.0-migration-guide.md) for more information on migrating to 0.32.0.
### New Features
- #6277: @josegonzalez Run ps:restore in parallel by default
- #6276: @josegonzalez Warn when incorrect interface/port in use for web processes
- #6132: @josegonzalez Add the ability to specify a custom mailto for all cron output
- #6124: @josegonzalez Add a shell function to check if a plugin trigger exists
- #5348: @josegonzalez Add nixpacks builder support
### Removals
- #6283: @josegonzalez Remove deprecated proxy-ports functions and and plugin subcommands
### Deprecations
- #6127: @josegonzalez Deprecate the builder-specific pre-release-* triggers in favor of a global pre-release-builder trigger
- #6126: @josegonzalez Deprecate the builder-specific post-build-* triggers in favor of a global post-build trigger
- #6125: @josegonzalez Deprecate the builder-specific pre-build-* triggers in favor of a global pre-build trigger
### Documentation
- #6284: @josegonzalez Document future removal of deprecated CHECKS file format
- #6123: @josegonzalez Add a migration guide for 0.32.x
### Dependencies
- #6285: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.5 to 9.4.6 in /docs/_build
- #6281: @josegonzalez Upgrade golang to 1.21
### Other
- #6155: @josegonzalez Remove ARM support
Users that misconfigure their process's listening interface or port will now see an additional healthcheck warning for web deploys. While only a single port is checked, this ensures that users at least have some context as to why their app isn't responding as expected.
Closes#4798
This will speed up restores in cases where app containers disappear on reboot or have new IPs, which primarily impacts the docker-local scheduler in conjunction with nginx.
Closes#4967
Building/testing for ARM does not happen often - the only runtime environment is Raspberry PI, which supports ARM64 - and complicates support for a ton of features. Aside from that, CI runs are much longer for ARM Dokku images, often reaching 15-20 minutes or just timing out completely.
Rather than support an architecture that doesn't have much usage by maintainers and has a lot of maintenance burden, we're removing the platform.
# History
## 0.31.5
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.31.5/bootstrap.sh
sudo DOKKU_TAG=v0.31.5 bash bootstrap.sh
```
### Bug Fixes
- #6275: @josegonzalez Update message referencing CHECKS file usage to app.json
- #6273: @josegonzalez Clean up local build images immediately after an image is released
### New Features
- #6274: @josegonzalez Add more version output to dokku report command
- #6255: @josegonzalez Add ci concurrency to linting workflow
- #6253: @josegonzalez Add ci concurrency to doc building
- #6254: @josegonzalez Add ci concurrency to codeql analysis
- #6222: @josegonzalez Install docker-buildx-plugin to silence buildx warnings
### Refactors
- #6257: @josegonzalez Manage Dokku system dependencies in a single file
### Documentation
- #6271: @josegonzalez Update list of official, community, and deprecated plugins
- #6224: @joeyates Correct typo in example app.json for healthchecks
- #6207: @AlejandroAkbal Update port clearing command in Dockerfile deploy documentation
### Tests
- #6278: @josegonzalez Remove pack installation from builder-lambda tests
### Dependencies
- #6269: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.14.0 to 0.17.0 in /plugins/common
- #6270: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.2.1 to 39.2.2
- #6262: @dependabot[bot] chore(deps): bump golang from 1.21.2 to 1.21.3 in /tests/apps/zombies-dockerfile-no-tini
- #6263: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.16.0 to 0.17.0 in /tests/apps/gogrpc
- #6264: @dependabot[bot] chore(deps): bump golang from 1.21.2 to 1.21.3 in /tests/apps/zombies-dockerfile-tini
- #6265: @dependabot[bot] chore(deps): bump golang from 1.21.2 to 1.21.3 in /tests/apps/go-fail-predeploy
- #6259: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.16 to 11.0.17 in /tests/apps/java
- #6260: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.4 to 9.4.5 in /docs/_build
- #6261: @dependabot[bot] chore(deps): bump golang from 1.21.2 to 1.21.3 in /tests/apps/gogrpc
- #6266: @dependabot[bot] chore(deps): bump golang from 1.21.2 to 1.21.3 in /tests/apps/go-fail-postdeploy
- #6258: @dependabot[bot] chore(deps): update markdown requirement from <3.5,>=3.2.1 to >=3.2.1,<3.6 in /docs/_build
- #6256: @josegonzalez chore: bump github.com/otiai10/copy and golang.org/x/sync
- #6241: @dependabot[bot] chore(deps): bump python from 3.11.5-alpine to 3.12.0-alpine in /docs/_build
- #6252: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.2 to 9.4.4 in /docs/_build
- #6235: @dependabot[bot] chore(deps): bump packaging from 23.1 to 23.2 in /docs/_build
- #6232: @dependabot[bot] chore(deps): bump werkzeug from 2.3.7 to 3.0.0 in /tests/apps/python-flask
- #6231: @dependabot[bot] chore(deps): bump flask from 2.3.3 to 3.0.0 in /tests/apps/python-flask
- #6248: @dependabot[bot] chore(deps): bump golang from 1.21.1 to 1.21.2 in /tests/apps/gogrpc
- #6251: @dependabot[bot] chore(deps): bump golang from 1.21.1 to 1.21.2 in /tests/apps/zombies-dockerfile-tini
- #6250: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.15.0 to 0.16.0 in /tests/apps/gogrpc
- #6249: @dependabot[bot] chore(deps): bump golang from 1.21.1 to 1.21.2 in /tests/apps/go-fail-predeploy
- #6247: @dependabot[bot] chore(deps): bump golang from 1.21.1 to 1.21.2 in /tests/apps/zombies-dockerfile-no-tini
- #6246: @dependabot[bot] chore(deps): bump golang from 1.21.1 to 1.21.2 in /tests/apps/go-fail-postdeploy
- #6245: @dependabot[bot] chore(deps): bump golang.org/x/sync from 0.3.0 to 0.4.0 in /plugins/scheduler-docker-local
- #6233: @dependabot[bot] chore(deps): bump flask from 2.3.3 to 3.0.0 in /tests/apps/multi
- #6239: @dependabot[bot] chore(deps): bump github.com/otiai10/copy from 1.12.0 to 1.14.0 in /plugins/ps
- #6234: @dependabot[bot] chore(deps): bump github.com/otiai10/copy from 1.12.0 to 1.14.0 in /plugins/builder
- #6240: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.2.0 to 39.2.1
- #6228: @josegonzalez Update all go modules and ensure all are tracked in dependabot
- #6227: @dependabot[bot] chore(deps): bump github.com/onsi/gomega from 1.27.10 to 1.28.0 in /plugins/common
- #6216: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.1.2 to 39.2.0
- #6217: @dependabot[bot] chore(deps): bump mkdocs-material from 9.4.1 to 9.4.2 in /docs/_build
- #6215: @dependabot[bot] chore(deps): bump mkdocs-material from 9.3.1 to 9.4.1 in /docs/_build
- #6214: @dependabot[bot] chore(deps): bump mkdocs-material-extensions from 1.1.1 to 1.2 in /docs/_build
- #6209: @dependabot[bot] chore(deps): bump zipp from 3.16.2 to 3.17.0 in /docs/_build
- #6211: @dependabot[bot] chore(deps): bump mkdocs from 1.5.2 to 1.5.3 in /docs/_build
- #6213: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.0.2 to 39.1.2
- #6202: @dependabot[bot] chore(deps): bump docker/setup-buildx-action from 2 to 3
- #6199: @dependabot[bot] chore(deps): bump docker/login-action from 2 to 3
- #6200: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 39.0.0 to 39.0.2
- #6201: @dependabot[bot] chore(deps): bump docker/setup-qemu-action from 2 to 3
- #6203: @dependabot[bot] chore(deps): bump mkdocs-material from 9.2.8 to 9.3.1 in /docs/_build
In some cases, we might hold onto intermediate images until the next deploy. While these images are generally part of newer images - and are therefore cleaned up when the child images are no longer in use - they cruft up the 'docker image ls' output, causing some folks to believe Dokku is not cleaning up images.
Refs #6272
This will allow us to more quickly update a dependency by adding support so that downstream repos can auto-push updates to the main repo when there is a release.
# History
## 0.31.4
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.31.4/bootstrap.sh
sudo DOKKU_TAG=v0.31.4 bash bootstrap.sh
```
### Documentation
- #5958: @gamedevsam Update command used to retrieve image digest when image is not pushed to a registry
### Dependencies
- #6194: @dependabot[bot] chore(deps): bump golang from 1.21.0 to 1.21.1 in /tests/apps/go-fail-predeploy
- #6197: @dependabot[bot] chore(deps): bump golang from 1.21.0 to 1.21.1 in /tests/apps/gogrpc
- #6195: @dependabot[bot] chore(deps): bump golang from 1.21.0 to 1.21.1 in /tests/apps/go-fail-postdeploy
- #6196: @dependabot[bot] chore(deps): bump golang from 1.21.0 to 1.21.1 in /tests/apps/zombies-dockerfile-tini
- #6193: @dependabot[bot] chore(deps): bump golang from 1.21.0 to 1.21.1 in /tests/apps/zombies-dockerfile-no-tini
- #6190: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.14.0 to 0.15.0 in /tests/apps/gogrpc
### Other
- #6191: @josegonzalez chore: remove debug logging from git plugin
# History
## 0.31.3
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.31.3/bootstrap.sh
sudo DOKKU_TAG=v0.31.3 bash bootstrap.sh
```
### Bug Fixes
- #6179: @rct-k Fix build cache for herokuish-built apps
### Tests
- #6177: @maxvisser Update shellcheck junit integration for newer version of shellcheck
### Dependencies
- #6186: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.2.1 to 10.3 in /docs/_build
- #6184: @dependabot[bot] chore(deps): bump soupsieve from 2.4.1 to 2.5 in /docs/_build
- #6183: @dependabot[bot] chore(deps): bump actions/checkout from 3 to 4
- #6187: @dependabot[bot] chore(deps): bump mkdocs-material from 9.2.6 to 9.2.8 in /docs/_build
- #6188: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 38.2.0 to 39.0.0
- #6173: @dependabot[bot] chore(deps): bump org.eclipse.jetty:jetty-servlet from 11.0.15 to 11.0.16 in /tests/apps/java
- #6174: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 38.1.3 to 38.2.0
- #6175: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.2 to 10.2.1 in /docs/_build
- #6176: @dependabot[bot] chore(deps): bump mkdocs-material from 9.2.5 to 9.2.6 in /docs/_build
- #6171: @dependabot[bot] chore(deps): bump pymdown-extensions from 10.1 to 10.2 in /docs/_build
- #6168: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 38.1.0 to 38.1.3
- #6170: @dependabot[bot] chore(deps): bump mkdocs-material from 9.2.3 to 9.2.5 in /docs/_build
- #6169: @dependabot[bot] chore(deps): bump python from 3.11.4-alpine to 3.11.5-alpine in /docs/_build
This used to be installed as moby-compose in Github Runners but they switched to the docker apt repo and don't install the plugin from the apt repository as it is outdated so we have to do it ourselves.
# History
## 0.31.1
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.31.1/bootstrap.sh
sudo DOKKU_TAG=v0.31.1 bash bootstrap.sh
```
### Bug Fixes
- #6133: @josegonzalez Properly handle tag and branch pushes
- #6131: @josegonzalez Ensure tmp files are cleaned up when commands exit
- #6130: @josegonzalez Correct package for container healthchecker when building digitalocean image
- #6121: @josegonzalez Add missing error-log-path function to openresty plugin
### Documentation
- #6129: @josegonzalez Cleanup markdown and use Github Admonitions
### Dependencies
- #6120: @dependabot[bot] chore(deps): bump click from 8.1.6 to 8.1.7 in /docs/_build
- #6119: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 37.6.0 to 37.6.1
- #6118: @dependabot[bot] chore(deps): bump werkzeug from 2.3.6 to 2.3.7 in /tests/apps/python-flask
- #6115: @dependabot[bot] chore(deps): bump golang from 1.20.7 to 1.21.0 in /tests/apps/zombies-dockerfile-no-tini
- #6114: @dependabot[bot] chore(deps): bump golang from 1.20.7 to 1.21.0 in /tests/apps/zombies-dockerfile-tini
- #6104: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.13.0 to 0.14.0 in /tests/apps/gogrpc
- #6113: @dependabot[bot] chore(deps): bump golang from 1.20.7 to 1.21.0 in /tests/apps/go-fail-predeploy
- #6112: @dependabot[bot] chore(deps): bump golang from 1.20.7 to 1.21.0 in /tests/apps/go-fail-postdeploy
- #6111: @dependabot[bot] chore(deps): bump golang from 1.20.7 to 1.21.0 in /tests/apps/gogrpc
- #6107: @dependabot[bot] chore(deps): bump pygments from 2.15.1 to 2.16.1 in /docs/_build
- #6106: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 37.5.2 to 37.6.0
- #6105: @dependabot[bot] chore(deps): bump sinatra from 3.0.6 to 3.1.0 in /tests/apps/ruby
### Other
- #6122: @josegonzalez Plugin trigger and event cleanup
# History
## 0.31.0
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.31.0/bootstrap.sh
sudo DOKKU_TAG=v0.31.0 bash bootstrap.sh
```
See the [0.31.0 migration guide](/docs/appendices/0.31.0-migration-guide.md) for more information on migrating to 0.31.0.
### Backwards Compatibility Breaks
- #6102: @josegonzalez Deprecate ARM as a build target
- #6029: @josegonzalez Provide users the ability to override auto-detected port mappings
### Bug Fixes
- #6110: @josegonzalez Correctly handle rebase when generating release notes for minor/major releases
- #6081: @josegonzalez Use correct namespace for haproxy service state tracking
- #6079: @josegonzalez Remove debugging code from builder-dockerfile plugin
- #6078: @josegonzalez Use correct quoting in format template when fetching exposed image ports
- #6070: @josegonzalez Do not write empty values for nginx container labels
- #6014: @josegonzalez Automatically clear the git source-image property when changing deployment methodologies
- #5985: @josegonzalez Mount the traefik data directory instead of the acme.json file when starting traefik
- #5979: @josegonzalez Do not start proxy implementations during server restore if they weren't manually started via the :start command
- #5973: @josegonzalez Remove all containers and images by label on app destroy
### New Features
- #6100: @josegonzalez Add support for non-web healthchecks via app.json
- #6098: @josegonzalez Upgrade traefik image from v2.8 to v2.10
- #6097: @josegonzalez Upgrade caddy image from 2.7 to 2.8
- #6082: @josegonzalez Add openresty proxy implementation
- #6057: @josegonzalez Inject docker labels when nginx proxy implementation is in use
- #6043: @josegonzalez Write auto-detected port mappings during a deploy
- #6013: @josegonzalez Export environment variables during dockerfile builds for use with value-less --build-arg flags
- #6007: @Firfi Add application/wasm to nginx.conf.sigil gzip
- #5993: @josegonzalez Un-deprecate apps and config cli aliases
- #5992: @josegonzalez Mount the vector data directory instead of the vector file
- #5991: @josegonzalez Add the ability to execute a cron task on the fly
- #5990: @josegonzalez Add json format output to cron:list command
- #5989: @josegonzalez Skip scaled processes that are missing in the Procfile
- #5978: @josegonzalez Export environment variables during dockerfile builds for use with value-less --build-arg flags
- #5908: @josegonzalez Generate jobs for crontab in parallel
- #5891: @josegonzalez Add support for specifying multiple networks on a given app
### Refactors
- #6042: @josegonzalez Rename port-map property to port
- #6021: @josegonzalez Simplify ports-configure codebase
- #6018: @josegonzalez Move code that fetches raw tcp ports for dockerfile deploys to ports plugin
- #6017: @josegonzalez Deprecate proxy-configure-ports plugin trigger in favor of ports-configure
- #6011: @josegonzalez Use ports-get plugn trigger for fetching port mappings
- #6010: @josegonzalez Use ports-clear plugn trigger to manage clearing the port map
- #5988: @josegonzalez Move crontab writing code to scheduler-docker-local plugin
- #5975: @josegonzalez Standardize on shorthand for redirecting all output to /dev/null
- #5974: @josegonzalez Standardize on ls subcommand when interacting with the docker binary
### Documentation
- #6116: @josegonzalez Remove extra newline in migration docs
- #6099: @josegonzalez Clean up references in proxy plugins
- #5987: @josegonzalez Clarify that a branch can be specified when updating a plugin
### Tests
- #6103: @josegonzalez Timeout docker image builds in CI
- #6101: @josegonzalez Make it possible to specify an alternative base domain for tests
- #6095: @josegonzalez Remove assertion for unconsumed build arguments
- #6094: @josegonzalez Correct assertion for dockerfile builds when a variable is eval'd
- #6080: @josegonzalez Add assertions to various bats tests
- #6076: @josegonzalez Use assert_output_not_exists instead of asserting output is empty string
- #6075: @josegonzalez Use an alternative curl request to ensure requests go to the local nginx
- #6074: @josegonzalez Fix issue where networks weren't being torn down during testing
- #6012: @josegonzalez Use ports:report to get the list of port mappings
- #5977: @josegonzalez Move all shellcheck disable definitions to .shellcheckrc
- #5976: @josegonzalez Remove Stickler configuration
### Other
- #6109: @josegonzalez Make heroku-22/jammy the default stack for cnb/herokuish builds
- #6096: @josegonzalez Upgrade vector image from 0.23.x to 0.31.x
- #6019: @josegonzalez Move code for fetching an available port to the ports plugin
- #6015: @josegonzalez Move CHECKS file extraction to the beginning of the deploy
- #5995: @josegonzalez Migrate the proxy port map from config variable to property system
- #5986: @josegonzalez Move all port management code to standalone ports plugin
- #5495: @josegonzalez Move herokuish app cache from the filesystem into a docker volume
With the integration branch where pull requests are merged prior to a release, we require a rebase every so often to ensure there aren't any issues upon merging to master. Unfortunately, this breaks the link between the original PR and the integration PR, thus causing changelog generation to fail as it depended upon those - now removed - merge request commits.
With this change, we introduce usage of milestones in order to track what is getting merged into a release. Milestones are only used for major/minor releases, and all others will fall back to the default git log method.
ARM usually takes quite a while to build. If it takes more than ~15 minutes, then it is usually going to fail anyways, so timeout early.
AMD64 takes ~3 minutes, and ARM64 appears to take 15 minutes.
AMD64 and ARM64 continue to be supported, but ARM in CI is not currently supported and doesn't get local testing either, so deprecating it now and removing it in the future makes most sense for the project.
This change converts existing CHECKS files into a healthchecks key that is understood by 'docker-container-healthchecker'. This tool supports a number of different types of container healthchecks - command, http, uptime - and can perform healthchecks against non-web processes.
The use of the old CHECKS file is now deprecated, and will be removed in the next minor version. Users can use the 'docker-container-healthchecker' to convert existing CHECKS files to the new format automatically.
Closes#2760
This plugin is mostly compatible with the nginx plugin, but runs the proxy within a docker container. Users do not have direct access to add custom openresty configuration at this time, but instead receive the ability to setup automatic ssl on first request via letsencrypt integration.
When developing Dokku, it is useful to use a real domain to test actual functionality. This is impossible if the domain is hardcoded to dokku.me in testing.
Previously, we would always set the port mapping during a dockerfile build, making it difficult for users to override mappings. We also only _sometimes_ updated the detected port mapping, further confusing issues when users were migrating from Dockerfile to Buildpacks for builds.
Now, we always detect the port mapping during the build process, and only use that detected port mapping if an override is not specified. This greatly simplifies the experience around port mapping, as now a user can create an app, set a port mapping, and that first deploy will respect the port mapping without an additional deploy.
The builder always has the best context for what the app should be listening on, and thus we can always specify a "default" port mapping at this stage. Users can override this map as desired later.
This change also results in the removal of a ton of internal code that is now centralized in the ports plugin.
Closes#4067
Due to how the variable was assigned, there were cases where the network was specified twice with a := as a delimiter. This would result in no network being removed.
This will allow users to switch to a docker label-based nginx proxy server transparently without rebuilds (after the first one), which would mimic how the caddy, haproxy, and traefik proxy implementations work.
See https://github.com/dokku/nginx-docker-proxy for an example server implementation.
During an app build, we now auto-detect ports based on the source code. This is usually http:80:5000, with Dockerfile-based deploys having their ports extracted from the docker image or Dockerfile. Additionally, we add an https:443 mapping for any detected http:80 mapping when there is an ssl certificate, and all http port mappings are transformed to https mappings for Dockerfile-based deploys.
While the ports aren't currently consumed, a future refactor will provide the ability to fallback to the new detected ports when there is no user-specified port mapping.
This makes deploys faster for any that are built from source as the image artifact isn't involved in those cases while also unifying how the file is handled.
Refs #2760
Exposing all config values will allow users to skip setting environment variables twice - once as a docker option and once as an env var. Docker will automatically pull the value from the environment if none is set for the --build-arg flag.
Users will still be required to specify each desired env var via --build-arg as otherwise docker builds will complain about unused build arguments.
Re-implements #5978 (lost in a rebase)
Closes#5903
This ensures users don't have issues with cached state in regards to files pulled from the repo/image.
Also add missing docs for deploy-source-set trigger.
Closes#5963
This better follows Heroku's output and is more useful to users. The subcommands will be treated as the primary, documented versions, while the aliases are there for convenience.
Closes#5362
The implementation was very heavily docker-local specific and thus didn't make a ton of sense to keep in the cron plugin.
This also re-introduces changes from #5908 to parallelize the crontab generation (which is also specific to the docker-local scheduler) that were lost during a rebase.
The impetus for this change was implementing a `cron:run` command. The logic for actually running the command isn't scheduler specific - merely invoking `dokku run` with the appropriate arguments - but all the logic around how the commands were retrieved were, so the change was made pre-emptively.
This allows folks to deploy apps that don't have a web process without needing to scale that process down before/after the first deploy. Note that the formations key in the app.json or a manual scale of other processes will be necessary to start anything non-web.
Closes#5700
This change makes interacting with port mappings more clear - folks might previously set the port mapping to the proxy type or vice-versa.
The existing proxy:ports* commands still exist but will show a deprecation warning for a single minor release.
Without this change, Docker - at least on arm64 - appears to mount the file as 0755 instead of 0600. We can trick docker by mounting the folder and then referencing _that_ instead.
This change ensures users don't have unnecessary proxies starting on their servers and potentially have apps not routing correctly due to another proxy squatting on a port.
Closes#5846
The shorthand is more prevalent in this codebase, and is something that bash supports, so we should just use the same thing everywhere.
Note that we do not use shorthand redirect in Makefile as shell parsing is a bit different in Make and the shorthand redirect doesn't seem to be properly supported, causing CI errors.
This makes standard use of shellcheck work without needing to provide extra configuration anywhere.
Also remove use of inline 'shellcheck disable' calls that are already defined in the .shellcheckrc and don't need to be set inline.
Previously, we would filter containers and images by name, which could be fail if the app was renamed or no longer was tagged "correctly" due to a rebuild. Now, we filter by label, ensuring an app is completely cleaned up on deletion.
Also:
- Move docker image cleanup from apps plugin to builder plugin: This isn't where it belongs - images should be cleaned up in a builder plugin (or the builders plugin) and not in the apps plugin, which has nothing to do with docker images anyways.
- Remove the code from the scheduler plugin, as that will only do anything if the scheduler is enabled for the app.
- Bypass image removal if there are no images to remove
- Always delete app containers: The herokuish builder creates intermediate build containers - something that should be refactored - and ideally this gets run in that builder plugin, but keeping the logic here ensures we don't have code duplication. This is otherwise safe as it will be a no-op if there are no containers to clean up.
Stickler-CI was shutdown in May 2023 - https://stickler-ci.com/shutting-down - and thus we no longer need configuration for it.
So long, and thanks for all the fish :)
# History
## 0.30.11
Install/update via the bootstrap script:
```shell
wget -NP . https://dokku.com/install/v0.30.11/bootstrap.sh
sudo DOKKU_TAG=v0.30.11 bash bootstrap.sh
```
### Dependencies
- #6091: @dependabot[bot] chore(deps): bump mkdocs from 1.5.1 to 1.5.2 in /docs/_build
- #6093: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 37.5.1 to 37.5.2
- #6088: @dependabot[bot] chore(deps): bump golang from 1.20.6 to 1.20.7 in /tests/apps/gogrpc
- #6087: @dependabot[bot] chore(deps): bump golang from 1.20.6 to 1.20.7 in /tests/apps/zombies-dockerfile-no-tini
- #6086: @dependabot[bot] chore(deps): bump golang.org/x/net from 0.12.0 to 0.13.0 in /tests/apps/gogrpc
- #6085: @dependabot[bot] chore(deps): bump golang from 1.20.6 to 1.20.7 in /tests/apps/go-fail-postdeploy
- #6084: @dependabot[bot] chore(deps): bump golang from 1.20.6 to 1.20.7 in /tests/apps/go-fail-predeploy
- #6083: @dependabot[bot] chore(deps): bump golang from 1.20.6 to 1.20.7 in /tests/apps/zombies-dockerfile-tini
- #6072: @dependabot[bot] chore(deps): bump tj-actions/changed-files from 37.5.0 to 37.5.1
- #6073: @dependabot[bot] chore(deps): bump pyparsing from 3.1.0 to 3.1.1 in /docs/_build
Consider [sponsoring Dokku](https://github.com/sponsors/dokku). Sponsorship goes directly to supporting activities such as fixing bugs and general maintenance.
- type:input
id:docs-link
attributes:
label:Link to the documentation page
description:Which docs page is impacted?
- type:textarea
id:description
attributes:
label:Documentation problem
description:Describe what you think is incorrect, not well documented, or missing from the documentation
validations:
required:true
- type:textarea
id:report-output
attributes:
label:dokku report
description:Please paste the output of the command `dokku report` so we know what systems any issue might apply to
# SC1001 - This \/ will be a regular '/' in this context - https://github.com/koalaman/shellcheck/wiki/SC1001
# SC1003 - Want to escape a single quote? echo 'This is how it'\''s done' - https://github.com/koalaman/shellcheck/wiki/SC1003
# SC1090 - Can't follow non-constant source. Use a directive to specify location - https://github.com/koalaman/shellcheck/wiki/SC1090
# SC1091 - Not following: FILE: does not exist (No such file or directory) - https://github.com/koalaman/shellcheck/wiki/SC1091
# - used for sourcing function files throughout the codebase
# SC1117 - Backslash is literal in "\n". Prefer explicit escaping: "\\n" - https://github.com/koalaman/shellcheck/wiki/SC1117
# SC2029 - Note that, unescaped, this expands on the client side - https://github.com/koalaman/shellcheck/wiki/SC2029
# SC2030 - Modification of var is local (to subshell caused by pipeline). - https://github.com/koalaman/shellcheck/wiki/SC2030
# SC2031 - var was modified in a subshell. That change might be lost. - https://github.com/koalaman/shellcheck/wiki/SC2031
# SC2034 - VAR appears unused - https://github.com/koalaman/shellcheck/wiki/SC2034
# - used for declaring desc and deprecated function variables
# SC2046 - Quote this to prevent word splitting - https://github.com/koalaman/shellcheck/wiki/SC2046
# SC2064 - Use single quotes, otherwise this expands now rather than when signalled. - https://github.com/koalaman/shellcheck/wiki/SC2064
# - used for traps
# SC2068 - Double quote array expansions to avoid re-splitting elements - https://github.com/koalaman/shellcheck/wiki/SC2068
# SC2086 - Double quote to prevent globbing and word splitting - https://github.com/koalaman/shellcheck/wiki/SC2086
# SC2119 - Use 'function "$@"' if function's $1 should mean script's $1 - https://github.com/koalaman/shellcheck/wiki/SC2119
# SC2120 - Function references arguments, but none are ever passed - https://github.com/koalaman/shellcheck/wiki/SC2120
# SC2128 - Expanding an array without an index only gives the first element - https://github.com/koalaman/shellcheck/wiki/SC2128
# SC2148 - Tips depend on target shell and yours is unknown. Add a shebang - https://github.com/koalaman/shellcheck/wiki/SC2148
# SC2153 - Possible misspelling: DOKKU_ROOT may not be assigned, but DOKKU_PORT is - https://github.com/koalaman/shellcheck/wiki/SC2153
# SC2154 - Var is referenced but not assigned - https://github.com/koalaman/shellcheck/wiki/SC2154
# SC2155 - Declare and assign separately to avoid masking return values - https://github.com/koalaman/shellcheck/wiki/SC2155
# - used throughout the codebase
disable=SC1091,SC2034,SC2064,SC2155
# SC2162 - read without -r will mangle backslashes - https://github.com/koalaman/shellcheck/wiki/SC2162
# SC2174 - When used with -p, -m only applies to the deepest directory - https://github.com/koalaman/shellcheck/wiki/SC2174
# SC2179 - Use array+=("item") to append items to an array - https://github.com/koalaman/shellcheck/wiki/SC2179
# SC2191 - The = here is literal. To assign by index, use ( [index]=value ) with no spaces. To keep as literal, quote it - https://github.com/koalaman/shellcheck/wiki/SC2191
# SC2199 - Arrays implicitly concatenate in [[ ]]. Use a loop (or explicit * instead of @) - https://github.com/koalaman/shellcheck/wiki/SC2199
# SC2207 - Prefer mapfile or read -a to split command output (or quote to avoid splitting) - https://github.com/koalaman/shellcheck/wiki/SC2207
- The nginx configuration (if applicable) via `dokku nginx:show-config APP_NAME`
- Link to the exact repository being deployed (if possible/applicable):
- If a deploy is failing or behaving unexpectedly:
- Application name
- The type of application being deployed (node, php, python, ruby, etc.)
- If using buildpacks, which custom buildpacks are in use
- If using a `Dockerfile`, the contents of that file
- If it exists, the contents of your `Procfile`.
- Application name
- The type of application being deployed (node, php, python, ruby, etc.)
- If using buildpacks, which custom buildpacks are in use
- If using a `Dockerfile`, the contents of that file
- If it exists, the contents of your `Procfile`.
- Output of failing Dokku commands after running `dokku trace:on`
(BEWARE: `trace:on` will print environment variables for some commands, be sure you're not exposing any sensitive information when posting issues. You may replace these values with XXXXXX):
You can then proceed to configure your server domain (via `dokku domains:set-global`) and user access (via `dokku ssh-keys:add`) to complete the installation.
HISTORY="${HISTORY}"$'\n\n'"See the [${NEXT_VERSION} migration guide](/docs/appendices/${NEXT_VERSION}-migration-guide.md) for more information on migrating to ${NEXT_VERSION}."
@@ -6,7 +6,8 @@ The best plan for disaster recovery is to always keep multiple (remote) copies o
## TLDR
> Warning: This method has many caveats. Please read this entire document before assuming these backups work as expected, and test your backups on a regular basis.
> [!WARNING]
> This method has many caveats. Please read this entire document before assuming these backups work as expected, and test your backups on a regular basis.
### Creating a backup
@@ -95,6 +96,14 @@ System administrators are highly encouraged to store persistent data in app-spec
See the [persistent storage documentation](/docs/advanced-usage/persistent-storage.md) for more information on how to attach persistent storage to your app.
### Restoring on a machine with a different CPU Architecture
When restoring a backup on a machine that has a different CPU architecture, you will need to clear out the `~/.basher` as it's not portable across different CPU architectures. Do so with the following command immediately after restoring your dokku configs:
```shell
rm -rf /home/dokku/.basher
```
## Recovering app code
In case of an emergency when your git repo and backups are completely lost, you can recover the last pushed copy from your remote Dokku server (assuming you still have the ssh key).
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
# 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:
# 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.
| `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 |
@@ -55,15 +56,19 @@ Please keep the above in mind when utilizing deployment tasks.
### Changing the `app.json` location
When deploying a monorepo, it may be desirable to specify the specific path of the `app.json` file to use for a given app. This can be done via the `app-json:set` command. If a value is specified and that file does not exist within the repository, Dokku will continue the build process as if the repository has no `app.json` file.
The `app.json` is expected to be found in a specific directory, depending on the deploy approach:
For deploys via the `git:from-image` and `git:load-image` commands, the `app.json` is extracted from the configured `WORKDIR` property of the image. For all other deploys - git push, `git:from-archive`, `git:sync` - will have the `app.json` extracted directly from the source code. Both cases will respect the configured `appjson-path` property value.
- The `WORKDIR` of the Docker image for deploys resulting from `git:from-image` and `git:load-image` commands.
- The root of the source code tree for all other deploys (git push, `git:from-archive`, `git:sync`).
Sometimes it may be desirable to set a different path for a given app, e.g. when deploying from a monorepo. This can be done via the `appjson-path` property:
The value is the path to the desired file *relative* to the base search directory, and will never be treated as absolute paths in any context. If that file does not exist within the repository, Dokku will continue the build process as if the repository has no `app.json`.
The default value may be set by passing an empty value for the option:
You can get a report about the app's storage status using the `app-json:report` command:
@@ -95,18 +101,20 @@ dokku app-json:report
```
=====> node-js-app app-json information
App-json computed appjson path: app2.json
App-json global appjson path: app.json
App-json global appjson path:
App-json appjson path: app2.json
=====> python-sample app-json information
App-json computed appjson path: app.json
App-json global appjson path: app.json
App-json global appjson path:
App-json appjson path:
=====> ruby-sample app-json information
App-json computed appjson path: app.json
App-json global appjson path: app.json
App-json global appjson path:
App-json appjson path:
```
The `appjson-path` and `global-appjson-path` keys hold the raw per-app and global value respectively, and are empty when nothing has been set. The `computed-appjson-path` key holds the effective value used at deploy time, falling back to the global value (where one has been set) and then to the built-in default of `app.json`.
@@ -140,7 +148,8 @@ Dokku provides limited support for the `app.json` manifest from Heroku (document
-`scripts.dokku.postdeploy`: This is run _after_ an app's containers are scheduled. Changes made to your image are _not_ committed at this phase.
-`scripts.postdeploy`: This is run _after_ an app's containers are scheduled. Changes made to your image are _not_ committed at this phase.
> Warning: Any failed `app.json` deployment task will fail the deploy. In the case of either phase, a failure will not affect any running containers.
> [!WARNING]
> Any failed `app.json` deployment task will fail the deploy. In the case of either phase, a failure will not affect any running containers.
The following is an example `app.json` file. Please note that only the `scripts.dokku.predeploy` and `scripts.dokku.postdeploy` tasks are supported by Dokku at this time. All other fields will be ignored and can be omitted.
@@ -158,6 +167,7 @@ The following is an example `app.json` file. Please note that only the `scripts.
#### Procfile Release command
> [!IMPORTANT]
> New as of 0.14.0
The `Procfile` also supports a special `release` command which acts in a similar way to the [Heroku Release Phase](https://devcenter.heroku.com/articles/release-phase). This command is executed _after_ an app's docker image is built, but _before_ any containers are scheduled. This is also run _after_ any command executed by `scripts.dokku.predeploy`.
The `docker-options` plugin allows users to specify custom [container options](https://docs.docker.com/engine/reference/run/) for containers created by Dokku at various phases.
## About Dokku phases
## Usage
Dokku deploys your application in multiple "phases" and the `docker-options` plugin allows you to pass arguments to their underlying docker container:
### Background
-`build`: the container that executes the appropriate buildpack
-`deploy`: the container that executes your running/deployed application
-`run`: the container that executes any arbitrary command via `dokku run`
#### Phases
Manipulation of docker options will not restart running containers. This enables multiple options to be set/unset before final application. As such, changing an app's dockeroptions must be followed by a `dokku ps:rebuild` in order to take effect.
Dokku deploys your app in multiple "phases" and the `docker-options` plugin allows you to pass arguments to their underlying docker container:
More information on supported Docker options can be found here: https://docs.docker.com/engine/reference/commandline/run/.
-`build`: The `build` phase is used to provide container options that are available during the build process for use by the various builders.
- A given builder may strip out or ignore options that are unsupported by the builder in question - as an example, the `dockerfile` builder does not support mounted volumes.
-`deploy`: The `deploy` phase is used to provide container options that are set on _deployed_ process types. This covers every process type specified in an app `Procfile` as well as any default processes your app may deploy.
- The `deploy` phase is usually the correct phase to add options for running containers.
-`run`: The `run` phase is used to provide container options to one-off containers created by `dokku run`, `dokku run:detached`, and any cron tasks specified in your `app.json`.
> [!IMPORTANT]
> The `run` phase does _not_ correspond 1-to-1 to `docker run` or `docker container run` commands. Specifying a container option at the `run` phase will only be invoked on containers created by the `run` plugin and cron tasks. Please be sure to specify options at the correct phase for your use-case.
Adding or removing docker-options will not apply to any running containers, and only applies to containers created _after_ the options have been modified. As such, changing an app's docker options must be followed by a `dokku ps:rebuild` or a deploy in order to take effect.
#### Supported Docker Options
More information on supported Docker options can be found [here](https://docs.docker.com/engine/reference/commandline/run/).
Container options configured via the `docker-options` plugin are not used to modify the process a container runs. Container options are the `[OPTIONS]` portion of the following, where `[CONTAINER_COMMAND]` and `[ARG]` are the process and the arguments passed to it that are launched in the created container: `docker run [OPTIONS] [CONTAINER_COMMAND] [ARG...]`. Please see the documentation for [customizing the run command](/docs/deployment/builders/dockerfiles.md#customizing-the-run-command) or use a [Procfile](/docs/deployment/builders/dockerfiles.md#procfiles-and-multiple-processes) to modify the command used by a Dockerfile-based container.
## Examples
#### Scheduler support
### Add Docker options
Docker options are written in Docker's own vocabulary and are passed verbatim to `docker run` by the `docker-local` scheduler. Other schedulers translate only the subset that has an equivalent in their own runtime, and ignore the rest.
Add some options for the deployed/running app and when executing [`dokku run`](/docs/processes/one-off-tasks.md):
The `k3s` scheduler translates `--cap-add`, `--cap-drop`, `--privileged`, and `--sysctl` into their Kubernetes equivalents. See the [k3s scheduler documentation](/docs/deployment/schedulers/k3s.md) for details, including the restriction that only namespaced sysctls can be set on a pod.
```shell
# Mount a host volume in a Docker container: "-v /host/path:/container/path"
> Note: When [mounting a host directory](https://docs.docker.com/engine/reference/run/#volume-shared-filesystems) in a Dokku app you should first create that directory as user `dokku` and then mount the directory under `/app` in the container using `docker-options` as above. Otherwise the app will lack write permission in the directory.
#### Mounting volumes and host directories
### Remove a Docker option
Docker supports volume and host directory mounting via the `-v` or `--volume` flags. In order to simplify usage, Dokku provides a `storage` plugin as an abstraction to interact with persistent storage. In most cases, the Dokku project recommends using the persistent storage plugin over directly manipulating docker options at different phases. See the [persistent storage documentation](/docs/advanced-usage/persistent-storage.md) for more information on how to attach persistent storage to your app.
### Commands
#### Add Docker options
To add a docker option to an app, use the `docker-options:add` command. This takes an app name, a comma-separated list of phases, and the docker-option to add.
```shell
dokku docker-options:remove node-js-app run "-v /var/log/node-js-app:/app/logs"
Multiple docker options can also be specified in a single call. Each `--flag [value]` group is detected on flag boundaries, shell-tokenized for quoting safety, and stored as its own entry so it round-trips through `docker-options:report` and `docker-options:list`:
Option values are stored and passed to the container verbatim. Quoting only controls how a value is split into words - no shell expansion is performed, so `$(...)`, backticks, `$VAR`, and globs are treated literally rather than being interpreted by the shell. This is what lets values such as a Traefik router rule be applied as-is:
> Options added before 0.38.25 were expanded by the shell when a container was created. Any such option that relied on shell expansion - `$(...)`, backticks, or `$VAR` - is treated as a literal string after upgrading and must be re-added with the value already resolved:
A misplaced `--process PROC` (i.e. one specified after the app name instead of before it) is honored as a subcommand flag rather than stored as a docker option, so the two invocations below behave identically:
```shell
dokku docker-options:add --process web node-js-app deploy "--ulimit nofile=12""--shm-size 256m"
dokku docker-options:add node-js-app deploy "--ulimit nofile=12""--shm-size 256m" --process web
```
#### Remove a Docker option
To remove docker options from an app, use the `docker-options:remove` command. This takes an app name, a comma-separated list of phases, and the docker-option to remove.
```shell
dokku docker-options:remove node-js-app run "--ulimit nofile=12"
```
Multiple phases can be specified by using a comma when specifying phases:
A stored option is matched by shell word rather than by exact string, so the value only has to be equivalent to the stored one, not byte-identical. Quoting an option one way removes an option that was stored quoted another way:
When process-specific options are configured (see below), the report exposes one additional dynamic flag per configured `process.deploy` pair, named `--docker-options-deploy.<process>`:
The JSON report includes the existing string keys (`build`, `deploy`, `run`, and `deploy.<process>` when configured) plus parallel `-list` keys for the same shorthand keys. Each `-list` value is a JSON array with one element per option as originally stored via `docker-options:add`, which allows export tooling to round-trip options that contain spaces without splitting the legacy space-joined strings. Empty phases emit an empty array (`[]`). The deprecated `docker-options-*` prefixed keys are unchanged and do not gain `-list` companions.
Docker options can be scoped to specific process types declared in the app's `Procfile` by passing one or more `--process` flags. This is useful when a deploy-phase option (for example a port mapping) makes sense for one process type but would conflict with another - the canonical case being a `web` process that needs `-p 6789:5000` published while the `worker` process must not bind that port.
Process scoping is supported only for the `deploy` phase. The `build` phase runs once per app and the `run` phase covers ad-hoc commands and cron tasks where no Procfile process type is in play; both reject `--process`.
There is no `--global` flag. Omitting `--process` keeps the historical behavior of applying the option to every container in the app. Avoiding a `--global` flag here is intentional: elsewhere in Dokku `--global` means "across all apps" (e.g. `dokku config:set --global`), which would be misleading in this plugin where the scope is always one app.
#### Setting process-specific options
```shell
# Add a port mapping only to the web process
dokku docker-options:add --process web node-js-app deploy "-p 6789:5000"
Multiple `--process` flags can be combined to apply the same option to several process types in one call:
```shell
dokku docker-options:add --process web --process api node-js-app deploy "-v /shared:/shared"
```
If `--process` names a process type that is not currently declared in the app's `Procfile`, the command succeeds but emits a warning. This allows configuring options ahead of a deploy that adds the new process type.
The `_default_` value is reserved internally and cannot be passed to `--process`.
#### Removing and clearing process-specific options
```shell
# Remove a single option from one process
dokku docker-options:remove --process web node-js-app deploy "-p 6789:5000"
Without `--process`, `:remove` and `:clear` operate on the default scope only - per-process lists are left untouched.
#### Listing options for a process and phase
The `docker-options:list` command prints the options stored for a single process+phase pair, one option per line. Omitting `--process` lists the default scope.
```shell
dokku docker-options:list node-js-app --process web --phase deploy
The following properties are recorded internally by the docker-options plugin and are not exposed via `docker-options:report`:
| Property | Scope | Description | Source |
|---|---|---|---|
| `migrated-from-files` | global | Global migration sentinel that records that the legacy `DOCKER_OPTIONS_<PHASE>` flat-file store has been drained into plugin properties | `plugins/docker-options/functions.go` writes `"true"` once the install-time migration runs |
| `migrated-build` | per-app | Per-app marker recording that the app's legacy `DOCKER_OPTIONS_BUILD` file was drained into the `_default_.build` property list. Only set when the legacy file contained non-empty content | `plugins/docker-options/functions.go` writes `"true"` after the per-phase drain |
| `migrated-deploy` | per-app | Per-app marker recording that the app's legacy `DOCKER_OPTIONS_DEPLOY` file was drained into the `_default_.deploy` property list. Only set when the legacy file contained non-empty content | `plugins/docker-options/functions.go` writes `"true"` after the per-phase drain |
| `migrated-run` | per-app | Per-app marker recording that the app's legacy `DOCKER_OPTIONS_RUN` file was drained into the `_default_.run` property list. Only set when the legacy file contained non-empty content | `plugins/docker-options/functions.go` writes `"true"` after the per-phase drain |
| `migrated-traefik-backticks` | global | Global sentinel recording that stored Traefik labels whose backticks carried a stray backslash have been repaired | `plugins/docker-options/functions.go` writes `"true"` once the install-time repair runs |
| `migrated-canonical-options` | global | Global sentinel recording that stored options have been rewritten into the canonical form, quoting values whose shell metacharacters were left bare by an older legacy-file drain and splitting entries that carried several flags | `plugins/docker-options/functions.go` writes `"true"` once the install-time rewrite runs |
Docker provides an _events_ command to show system's real time events. Likewise, Dokku can record events as syslog entries and also provides a plugin to display the last ones.
> New as of 0.5.0. Named storage entries new as of 0.38.0.
The preferred method to mount external containers to a Dokkumanaged container, is to use the Dokku storage plugin.
The preferred method to attach persistent storage to a Dokku-managed container is the Dokku storage plugin.
```
storage:ensure-directory [--chown option] <directory> # Creates a persistent storage directory in the recommended storage path
storage:list <app> [--format text|json] # List bind mounts for app's container(s) (host:container)
storage:mount <app> <host-dir:container-dir> # Create a new bind mount
storage:report [<app>] [<flag>] # Displays a checks report for one or more apps
storage:unmount <app> <host-dir:container-dir> # Remove an existing bind mount
storage:annotations:report [<name>] [<flag>] # Display annotations for one or more storage entries
storage:annotations:set <name> <key> [<value>] # Set or clear a single annotation on a storage entry
storage:create <name> [<path>] [flags] # Register a named storage entry
storage:destroy <name> [--force] [--destroy-host-dir] # Remove a named storage entry (must be unmounted from every app first)
storage:ensure-directory [--chown option] <directory> # [DEPRECATED] use storage:create instead
storage:exec <name> [-- <cmd>...] # Run a command (or shell) in a temporary container that mounts the entry
storage:info <name> [--format text|json] # Show details for one storage entry
storage:labels:report [<name>] [<flag>] # Display labels for one or more storage entries
storage:labels:set <name> <key> [<value>] # Set or clear a single label on a storage entry
storage:list <app> [--format text|json] # List bind mounts for an app's container(s) (legacy host:container view)
storage:list-entries [--scheduler s] [--format text|json] # List registered storage entries
storage:mount <app> <name> --container-dir <path> [flags] # Mount a named entry into an app
storage:mount <app> <host-dir:container-dir> # [LEGACY] colon-form mount, docker-local only
storage:report [<app>] [<flag>] # Display a storage report for one or more apps
storage:report --global # Display a cluster-wide entry inventory
storage:set <name> <property> [<value>] # Update a storage entry in place
storage:unmount <app> <name> [--container-dir <path>] # Remove an attachment
storage:wait <name> # Block until a k3s entry's PVC is bound
```
> The storage plugin is compatible with storage mounts created with the docker-options. The storage plugin will only list mounts from the deploy/run phase.
A storage entry is the source of truth for the underlying volume - a host directory on docker-local, or a PersistentVolumeClaim on k3s. Multiple apps can mount the same entry, and an attachment carries the per-app details (container path, phases, subpath, readonly, process type). Names are globally unique across the install and must be DNS-1123 labels (lowercase letters, digits, dashes) of 45 characters or less so they can be used verbatim as Helm release and PVC names.
The legacy `storage:mount <app> <host>:<container>` form continues to work on docker-local. On a k3s app it is rejected; create a named entry with `storage:create --scheduler k3s` and mount it instead. Existing colon-form mounts are migrated automatically the first time the new code runs - they show up as `legacy-<hash>` entries in `storage:list-entries`.
The storage plugin supports the following mount points:
- explicit paths that exist on the host
- docker volumes
- explicit paths that exist on the host (docker-local)
- docker volumes (docker-local)
- PersistentVolumeClaims provisioned via a StorageClass (k3s)
- hostPath-backed PVs (k3s)
## Usage
@@ -36,7 +54,6 @@ dokku storage:list node-js-app
The output format can also be set to `json` for programmatic access:
Each entry mirrors the underlying attachment. `readonly` (boolean) and `volume_options` (string) reflect `Attachment.Readonly` and `Attachment.VolumeOptions` directly and are only present when set, so external tooling can drift-detect attachments against the raw attachment fields. For example, a mount created with `--volume-options noexec,nosuid --volume-readonly` renders as:
A storage directory can be created with the `storage:ensure-directory` command. This command will create a subdirectory in the recommended `/var/lib/dokku/data/storage` path - created during Dokku installation - and prepare it for use with an app.
By default, permissions are set for usage with Herokuish buildpacks. These permissions can be changed via the `--chown` option according to the following table:
-`--chown herokuish` (default): Use `32767:32767` as the folder permissions.
- This is used for apps deployed with Buildpacks via Herokuish.
- This is used for apps deployed with Buildpacks via Herokuish.
-`--chown heroku`: Use `1000:1000` as the folder permissions.
- This is used for apps deployed with Cloud Native Buildpacks using the `heroku/buildpacks` builder.
-`--chown packeto`: Use `2000:2000` as the folder permissions.
- This is used for apps deployed with Cloud Native Buildpacks using the `cloudfoundry/cnb` or `packeto` builders.
- This is used for apps deployed with Cloud Native Buildpacks using the `heroku/builder` builder.
-`--chown paketo`: Use `2000:2000` as the folder permissions.
- This is used for apps deployed with Cloud Native Buildpacks using the `cloudfoundry/cnb` or `paketo` builders.
-`--chown root`: Use `0:0` as the folder permissions.
- This is used for containers that run their processes as root, as is typical for most Dockerfile or Docker image deploys.
-`--chown false`: Skips the `chown` call.
-`--chown <uid>`: Use `<uid>:<uid>` as the folder permissions, where `<uid>` is a custom numeric user/group id.
- This is used for containers that run their processes as a uid/gid that doesn't correspond to any of the above named options.
Users deploying via Dockerfile will want to specify `--chown false` and manually `chown` the created directory if the user and/or group id of the runnning process in the deployed container do not correspond to any of the above options.
> Warning: Failing to set the correct directory ownership may result in issues in persisting files written to the mounted storage directory.
The `--chown` flag - whether on `storage:create` or `storage:ensure-directory` - only manages the default `/var/lib/dokku/data/storage/<name>` location. If a custom `<path>` is passed to `storage:create`, the chown call is refused and the operator must chown the path themselves.
> [!WARNING]
> Failing to set the correct directory ownership may result in issues in persisting files written to the mounted storage directory.
### Setting directory permissions
> [!IMPORTANT]
> New as of 0.38.27
Where `--chown` states who owns the host directory, `--mode` states its permission bits. It takes a 3 or 4 digit octal mode, and is a `--mode` flag on `storage:create` and a `mode` property on `storage:set`:
```shell
dokku storage:create node-js-data --mode 0777
```
```shell
dokku storage:set node-js-data mode 0770
```
Omitting the value clears the mode, leaving the directory's permissions alone on subsequent runs:
```shell
dokku storage:set node-js-data mode
```
Without a mode, a newly created directory keeps the `0755` default and a pre-existing directory keeps whatever permissions it already had. The value is stored on the entry and re-applied every time `storage:create` or `storage:set` runs against it, so a declarative caller converges the directory by re-running the same command rather than reaching for `chmod` over SSH. The mode is shown by `storage:info`:
The mode is applied to the directory itself and does not recurse into its contents. Like `--chown`, it is docker-local only and only manages the default `/var/lib/dokku/data/storage/<name>` location - it is refused for k3s entries and for entries created with a custom `<path>`. That refusal also covers migrated `legacy-*` entries, whose host paths come from the original colon-form mount rather than the default location.
### Updating a storage entry
> [!IMPORTANT]
> The property form is new as of 0.38.27. Prior versions used flags, which still work but emit a deprecation warning.
An existing entry is edited with `storage:set`, which takes a property and a value. Omitting the value unsets the property, restoring whatever the entry defaults to:
```shell
dokku storage:set node-js-data chown herokuish
dokku storage:set node-js-data chown
```
The following properties can be set:
| Property | Description | Unsetting it means |
|---|---|---|
| `chown` | Ownership preset or numeric uid for the host directory | no chown is performed |
| `mode` | Octal permissions for the host directory | permissions are left alone |
| `namespace` | Namespace holding the PVC (k3s) | the `default` namespace |
| `storage-class-name` | PVC storage class (k3s) | rejected, see below |
`access-mode` and `storage-class-name` cannot be changed on an entry that already exists, because Kubernetes cannot apply either to a bound PVC. Both a different value and an empty one are refused, since clearing is equally a change:
! storage:set cannot change access-mode in place; recreate the entry
```
Setting `chown` or `mode` on a docker-local entry applies the change to the host directory immediately. Every other property is a metadata write, and k3s entries re-apply their helm release so the cluster picks the change up.
The older flag form - `dokku storage:set node-js-data --mode 0770` - continues to work and warns. It gained unset semantics too, so `--mode ""` clears the mode the same way omitting the positional value does.
### Annotations and labels
> [!IMPORTANT]
> New as of 0.38.27
Annotations and labels are attached to a storage entry one key at a time, matching the [scheduler-k3s equivalents](/docs/deployment/schedulers/k3s.md#setting-annotations). On k3s they propagate to both the PersistentVolumeClaim and the PersistentVolume, so backup tools like Velero and Longhorn can find the volume.
Keys may contain `/`, as the Kubernetes-style keys above do, and are stored verbatim. To clear a single key, omit the value. Other keys are left untouched, so a declarative caller does not need to re-send the whole set on every call:
JSON output emits the keys flat, and a single value can be read directly with a flag of the form `--storage-annotations.<key>` (or `--storage-labels.<key>`), which requires an entry name:
`storage:create` still accepts repeatable `--annotation key=value` and `--label key=value` flags for setting the initial set at creation time. The same flags on `storage:set` are deprecated in favor of these commands, because they replace the entire map rather than a single key.
### Mounting storage into apps
@@ -99,6 +252,17 @@ In the first example, Dokku will then mount the shared contents of `/var/lib/dok
> If the `/storage` path within the container had pre-existing content, the container files will be over-written. This may be an issue for users that create assets at build time but then mount a directory at the same place during runtime. Files are not merged.
For named storage entries, additional Docker mount options can be passed via `--volume-options`. The value is a comma-separated mount-options string stored verbatim on the attachment and rendered into the `-v` flag at deploy time. This is useful for SELinux labels (`Z`, `z`) or hardening flags (`noexec,nosuid`):
```shell
dokku storage:create node-js-data
dokku storage:mount node-js-app node-js-data --container-dir /app/storage --volume-options Z
```
When combined with `--volume-readonly`, the rendered options become `ro,<volume-options>` - for example, `--volume-options noexec,nosuid --volume-readonly` renders as `:ro,noexec,nosuid`.
Re-running `storage:mount` against a named entry with the same `--container-dir` and `--process-type` updates the existing attachment's mount-time attributes (`--phase`, `--volume-subpath`, `--volume-readonly`, `--volume-chown`, `--volume-options`) in place rather than appending a duplicate. This is the idempotent equivalent of `storage:set` for entries, and lets declarative tooling change a mount-time attribute without an unmount-then-remount dance that would briefly drop the volume from `storage:report`. Mount-time fields are rewritten wholesale, not merged - omitting a flag on a re-mount clears any previously-set value. The legacy `host:container[:opts]` form still rejects duplicates with `Mount path already exists.`.
Once persistent storage is mounted, the app requires a restart. See the [process scaling documentation](/docs/processes/process-management.md) for more information.
```shell
@@ -123,8 +287,68 @@ Once persistent storage is unmounted, the app requires a restart. See the [proce
dokku ps:restart app-name
```
### Destroying storage entries
A named storage entry can be removed with the `storage:destroy` command. The entry must first be unmounted from every app that mounts it.
```shell
dokku storage:destroy rdmtest-entry
```
As the command is destructive - removing the registry entry and, depending on the scheduler and reclaim policy, the underlying volume - it will default to asking for confirmation before executing the removal.
```
! WARNING: Potentially Destructive Action
! This command will destroy storage entry rdmtest-entry.
! To proceed, type "rdmtest-entry"
> rdmtest-entry
-----> Storage entry rdmtest-entry destroyed
```
The confirmation may be avoided by providing the `--force` flag, which is useful for non-interactive or automated callers:
```shell
dokku storage:destroy rdmtest-entry --force
```
The global `--force` flag is also supported:
```shell
dokku --force storage:destroy rdmtest-entry
```
#### Removing the host directory
> [!IMPORTANT]
> New as of 0.38.27
By default a docker-local entry's host directory survives `storage:destroy` - the entry is deregistered but the data stays on disk. The `--destroy-host-dir` flag removes the directory and everything in it:
! Storage entry node-js-data is backed by /var/lib/dokku/data/storage/node-js-data, which will be removed along with its contents.
! WARNING: Potentially Destructive Action
! This command will destroy storage entry node-js-data.
! To proceed, type "node-js-data"
```
The removal is recursive, so it succeeds whether or not the directory is empty. It is only permitted for entries at the default `/var/lib/dokku/data/storage/<name>` location; an entry created with a custom `<path>` is refused, and the operator removes the path themselves.
The same removal can be declared ahead of time with `--reclaim-policy`, which behaves for a docker-local host directory the way it behaves for a k3s PersistentVolume. An entry created with `Delete` has its host directory removed on `storage:destroy` without any extra flag, while `Retain` - the default when unset - keeps it:
`--destroy-host-dir` is docker-local only. On a k3s entry the underlying volume is already governed by the reclaim policy recorded on the entry, so passing the flag is an error.
### Displaying storage reports for an app
> [!IMPORTANT]
> New as of 0.8.1
You can get a report about the app's storage status using the `storage:report` command:
@@ -167,6 +391,60 @@ You can pass flags which will output only the value of the specific information
In addition to the aggregated `Storage build/deploy/run mounts:` lines, the report emits one flat dotted key per attachment field, indexed from `1`. The key shape is `--storage-attachment.<index>.<field>` for each of `entry-name`, `host-path`, `container-path`, `phases`, `process-type`, `subpath`, `readonly`, `volume-options`, and `volume-chown`. Fields render as empty strings when unset, and attachments are ordered by lex-sort of the index (so `10` sorts before `2`):
Storage run mounts: -v /var/lib/dokku/data/storage/node-js-data:/app/storage:Z
```
The same keys are exposed in JSON output, both in the stripped (`attachment.1.volume-options`) and legacy (`storage-attachment.1.volume-options`) forms:
You cannot use mounted volumes during the build phase of a Dockerfile deploy. This is because Docker does not support volumes when executing `docker build`.
> Warning: **This can cause data loss** if you bind a mount under `/app` in buildpack apps as herokuish will attempt to remove the original app path during the build phase.
> [!WARNING]
> **This can cause data loss** if you bind a mount under `/app` in buildpack apps as herokuish will attempt to remove the original app path during the build phase.
## App User and Persistent Storage file ownership (buildpack apps only)
> [!IMPORTANT]
> New as of 0.7.1
By default, Dokku will execute your buildpack app processes as the `herokuishuser` user. You may override this by setting the `DOKKU_APP_USER` config variable.
> NOTE: this user must exist in your herokuish image.
> [!NOTE]
> this user must exist in your herokuish image.
Additionally, the default `docker-local` scheduler that comes with Dokku will ensure your storage mounts are owned by either `herokuishuser` or the overridden value you have set in `DOKKU_APP_USER`. See the [docker-local scheduler documentation](/docs/deployment/schedulers/docker-local.md#disabling-chown-of-persistent-storage) docs for more information.
## Properties
### Internal properties
The following property is recorded internally by the storage plugin and is not exposed via `storage:report`:
| Property | Scope | Description | Source |
|---|---|---|---|
| `legacy-mounts-migrated` | per-app | Per-app marker recording that the app's legacy `-v` docker-options entries were drained into named storage entries plus attachments. Only set when at least one `-v` line was actually migrated; apps that have never had legacy mounts never receive this marker | `plugins/storage/migrate.go` writes `"true"` after a successful drain |
plugin:disable <name> # Disable an installed plugin (third-party only)
plugin:enable <name> # Enable a previously disabled plugin
plugin:install [--core|git-url [--committish tag|branch|commit|--name custom-plugin-name]] # Optionally download git-url (with custom tag/committish) & run install trigger for active plugins (or only core ones)
plugin:install [--core|git-url] [--committish branch|commit|tag] [--name custom-plugin-name] [--skip-install-trigger] # Optionally download git-url (and pin to the specified branch/commit/tag) & run install trigger for active plugins (or only core ones)
plugin:installed <name> # Checks if a plugin is installed
plugin:install-dependencies [--core] # Run install-dependencies trigger for active plugins (or only core ones)
plugin:list # Print active plugins
plugin:list [--format stdout|json] # Print active plugins
plugin:trigger <args...>. # Trigger an arbitrary plugin hook
plugin:uninstall <name> # Uninstall a plugin (third-party only)
plugin:update [name [committish]] # Optionally update named plugin from git (with custom tag/committish) & run update trigger for active plugins
plugin:update [name [branch|commit|tag]] # Optionally update named plugin from git (and pin to the specified branch/commit/tag) & run update trigger for active plugins
```
```shell
@@ -35,38 +36,72 @@ dokku plugin:list
```
plugn: dev
00_dokku-standard 0.30.10 enabled dokku core standard plugin
> Warning: All plugin commands other than `plugin:list` and `plugin:help` require sudo access and must be run directly from the Dokku server.
The list can also be emitted as JSON via the `--format json` flag. In addition to the name, version, enabled state, and description shown in the default output, the JSON output includes whether a plugin is a core plugin and - for git-based third-party plugins - the install source (the git remote URL, the currently checked-out commit, and the followed branch). This is useful for tooling that reconstructs a server's set of installed plugins:
The `source_url`, `committish`, and `branch` fields are only populated for plugins installed from a git repository. They are empty for core plugins as well as for plugins installed from a tarball or a local `file://` path. When a plugin is pinned to a specific commit or tag (a detached checkout), the `branch` field is empty while `committish` still reports the exact commit.
> [!WARNING]
> All plugin commands other than `plugin:list` and `plugin:help` require sudo access and must be run directly from the Dokku server.
> Note: Plugins installed in this method within a [docker-based installation](/docs/getting-started/install/docker.md) of Dokku do not persist across installs. Please see the [plugin installation section](/docs/getting-started/install/docker.md#plugin-installation) of the docker-based installation docs for further details.
> [!NOTE]
> Plugins installed in this method within a [docker-based installation](/docs/getting-started/install/docker.md) of Dokku do not persist across installs. Please see the [plugin installation section](/docs/getting-started/install/docker.md#plugin-installation) of the docker-based installation docs for further details.
Installing a plugin is easy as well using the `plugin:install` command. This command will also trigger the `install` pluginhook on all existing plugins.
@@ -125,6 +161,12 @@ The `--core` flag may also be indicated as the sole argument, though it is only
dokku plugin:install --core
```
If installing plugins in a Dockerfile, you will want to skip the `install` trigger. This will be run on container boot.
Finally, all flags may be omitted to trigger the `install` procedures for both core and third-party plugins:
```shell
@@ -165,6 +207,12 @@ An optional commit SHA-like object may be specified.
dokku plugin:update postgres 2.0.0
```
Any future invocation of `plugin:update` will respect the previously specified SHA-like object. To follow a particular branch again, specify that branch:
```shell
dokku plugin:update postgres main
```
### Uninstalling a plugin
Third party plugins can be uninstalled using the `plugin:uninstall` command:
registry:login [--password-stdin] <server> <username> [<password>] # Login to a docker registry
registry:report [<app>] [<flag>]# Displays a registry report for one or more apps
registry:set <app> <key> (<value>) # Set or clear a registry property for an app
registry:login [--global|--password-stdin] [<app>] <server> <username> [<password>] # Login to a docker registry
registry:logout [--global] [<app>] <server> # Logout from a docker registry
registry:report [<app>] [<flag>] # Displays a registry report for one or more apps
registry:set <app>|--global <key> (<value>) # Set or clear a registry property for an app
```
The registry plugin enables interacting with remote registries, which is useful when either deploying images via `git:from-image` or when interacting with custom schedulers to deploy built image artifacts.
@@ -14,34 +16,75 @@ The registry plugin enables interacting with remote registries, which is useful
### Logging into a registry
The `registry:login` command can be used to log into a docker registry. The following are examples for logging into various common registries:
The `registry:login` command can be used to log into a docker registry. Credentials can be stored globally (for all apps) or on a per-app basis.
#### Global login
To log in globally (credentials shared by all apps), use the `--global` flag:
For security reasons, the password may also be specified as stdin by specifying the `--password-stdin` flag. This is supported regardless of the registry being logged into.
> [!NOTE]
> For backwards compatibility, if the `--global` flag is omitted and only three arguments are provided (server, username, password), the command will behave as a global login but will show a deprecation warning.
#### Per-app login
To log in for a specific app, specify the app name as the first argument:
Per-app credentials are stored in `/var/lib/dokku/config/registry/$APP/config.json` and are automatically used for docker operations (build, push, pull) for that specific app.
#### Password via stdin
For security reasons, the password may also be specified as stdin by specifying the `--password-stdin` flag. This is supported for both global and per-app logins:
For certain Docker registries - such as Amazon ECR or Google's GCR registries - users may instead wish to use a docker credential helper to automatically authenticate against a server; please see the documentation regarding the credential helper in question for further setup instructions.
### Logging out from a registry
The `registry:logout` command can be used to log out from a docker registry:
```shell
# global logout
dokku registry:logout --global docker.io
# per-app logout
dokku registry:logout node-js-app docker.io
```
When an app is destroyed, any per-app registry credentials are automatically removed.
### Setting a remote server
To specify a remote server registry for pushes, set the `server` property via the `registry:set` command. The default value for this property is empty string. Setting the value to `docker.io` or `hub.docker.com` will result in the computed value being empty string (as that is the default, implicit registry), while any non-zero length value will have a `/` appended to it if there is not one already.
@@ -98,7 +141,31 @@ Setting the property value to an empty string will reset the value to the system
```shell
# per-app
dokku registry:set node-js-app push-on-release
dokku registry:set node-js-app image-repo
```
### Templating the image repository name
Instead of setting the image repository name on a per-app basis, it can be set via a template with the `image-repo-template` property. The property can be set globally or for a specific app, with the per-app value overriding the global value when both are present:
Dokku uses a Golang template and has access to the `AppName` variable as shown above. The per-app `image-repo` property always takes precedence over the rendered template when both are set.
Setting the property value to an empty string will reset the value to the system default. Resetting the value can be done per app or globally.
When `push-on-release` is enabled, Dokku treats the remote registry as the canonical store for app images. If a local image disappears - for example because a `docker image prune` cron ran, the host rebooted, or an operator removed it manually - subsequent commands that need the image (`ps:restart`, `ps:scale`, `dokku run`, `domains:add`, `certs:add`, etc.) will pull the missing tag back from the registry automatically. Per-app registry credentials configured via `registry:login` are honored during the pull. This recovery covers the deployed numeric tag pushed by the registry plugin - a missing `latest` tag will be ignored.
### Push extra tags
To push the image on release with extra tags, set the `push-extra-tags` to a comma-separated list of tags via the `registry:set` command. The default value for this property is empty. Setting the property will result in the image being tagged with extra tags every release.
This property can be set for a single app or globally via the `--global` flag. When set globally, the app-specific value will always overide the global value. The default global value for this property is `false`.
Setting the property value to an empty string will reset the value to the system default. Resetting the value can be done per app or globally.
```shell
# per-app
dokku registry:set node-js-app push-extra-tags
# globally
dokku registry:set --global push-extra-tags
```
## Properties
### Settable properties
> [!NOTE]
> The `Report flags` column lists the CLI argument names accepted by `registry:report`. The JSON keys emitted by `registry:report --format json` are the same names with the leading `--registry-` stripped (e.g. `image-repo`, `global-server`, `computed-push-on-release`). Legacy keys with the `registry-` prefix (e.g. `registry-image-repo`) are also emitted during the 0.38.x deprecation window and will be removed in a future major release.
| `image-repo` | app only | `dokku/<app>` | `--registry-image-repo`, `--registry-computed-image-repo` | Repository name used when pushing the app's image (overrides the global template) |
| `image-repo-template` | app + global | none | `--registry-image-repo-template`, `--registry-global-image-repo-template`, `--registry-computed-image-repo-template` | Go template used to compute the per-app image repository when `image-repo` is unset |
| `push-extra-tags` | app + global | none | `--registry-push-extra-tags`, `--registry-global-push-extra-tags`, `--registry-computed-push-extra-tags` | Comma-separated list of additional tags pushed alongside the deploy tag |
| `push-on-release` | app + global | `false` | `--registry-push-on-release`, `--registry-global-push-on-release`, `--registry-computed-push-on-release` | When `true`, pushes the image to the registry on every successful build |
| `server` | app + global | none | `--registry-server`, `--registry-global-server`, `--registry-computed-server` | Registry server host (e.g. `ghcr.io`) used when pushing images |
@@ -16,7 +17,8 @@ The resource plugin is meant to allow users to limit or reserve resources for a
By default, Dokku allows unlimited resource access to apps deployed on a server. In some cases, it may be desirable to limit this on a per-app or per-process-type basis. The `resource` plugin allows management of both resource "limits" and resource "reservations", where each resource request type has specific meaning to the scheduler in use for a given app.
> Warning: The meaning of a values and it's units are specific to the scheduler in use for a given app. If a value is incorrect for a scheduler, this may result in containers failing to start correctly. If a scheduler does not support a given resource type combination, it will be ignored. All resource commands require an app rebuild or deploy in order to take effect.
> [!WARNING]
> The meaning of a values and it's units are specific to the scheduler in use for a given app. If a value is incorrect for a scheduler, this may result in containers failing to start correctly. If a scheduler does not support a given resource type combination, it will be ignored. All resource commands require an app rebuild or deploy in order to take effect.
Valid resource options include:
@@ -30,7 +32,7 @@ Valid resource options include:
See the [Supported Resource Management Properties](/docs/deployment/schedulers/docker-local.md#supported-resource-management-properties) section of the docker local scheduler documentation for more information on how each resource limit maps to Docker.
Resource limits and reservations are applied only during the `run` and `deploy` phases of an application, and will not impact the `build` phase of an application.
Resource reservations are applied only during the `run` and `deploy` phases of an application. Resource limits also apply during the `build` phase when explicitly configured against the `build` process type - see [Build-time Resource Limits](#build-time-resource-limits) below.
### Resource Limits
@@ -118,6 +120,40 @@ dokku resource:limit --process-type web node-js-app
nvidia-gpu:
```
#### Build-time Resource Limits
> [!IMPORTANT]
> New as of 0.38.0
Resource limits may be applied to the build container by using the special `build` process type. This allows constraining memory and CPU usage during the `build` phase, which is otherwise unconstrained.
=====> Setting resource limits for node-js-app (build)
memory: 4g
```
Build-time limits are applied via the `docker-args-process-build` plugin trigger. They do not inherit from default (`_default_`) limits - only limits explicitly set against the `build` process type are applied at build time. This is intentional: build phases often require more memory than the runtime process, and silently inheriting a small runtime limit would cause confusing OOM failures.
> [!WARNING]
> Do not use `build` as a runtime process type in your `Procfile`. The `build` name is reserved by the resource plugin to scope limits to the build container, and using it as a Procfile entry will cause those limits to be applied to that runtime container as well.
Resource keys outside the supported set for a builder are silently ignored. Reservations (`resource:reserve`) are never applied at build time - only limits.
#### Clearing Resource Limits
In cases where the values are incorrect - or there is no desire to limit resources - resource limits may be cleared using the `resource:limit-clear` command.
By default, Dokku will ship a PCI Compliant nginx configuration. For developers whose users are on older browsers or mobile devices, you may need to ship a custom `nginx.conf.sigil` to enable ciphers for older browsers.
See the [nginx customization](/docs/networking/proxies/nginx/#customizing-the-nginx-configuration) docs for more details.
See the [nginx customization](/docs/networking/proxies/nginx.md#customizing-the-nginx-configuration) docs for more details.
## Nginx Error Pages
We now ship with nicer error pages by default. You are free to customize your Dokku installation via a custom `nginx.conf.sigil` to change what error pages are displayed in different circumstances.
See the [nginx customization](/docs/networking/proxies/nginx/#customizing-the-nginx-configuration) docs for more details.
See the [nginx customization](/docs/networking/proxies/nginx.md#customizing-the-nginx-configuration) docs for more details.
@@ -8,7 +8,7 @@ The `tls` name is no longer a reserved app name, and can be used by applications
-`git#git_deploy_branch()` is deprecated in favor of `plugn trigger git-deploy-branch`.
- The `config` command is deprecated in favor of `config:show`.
- Usage of this command in conjunction with either the `--export` or `--shell` flag is deprecated in favor of `config:export --format` with the correct format value (`exports` or `shell`, respectively).
- Usage of this command in conjunction with either the `--export` or `--shell` flag is deprecated in favor of `config:export --format` with the correct format value (`exports` or `shell`, respectively).
- The `nginx:build-config` command is deprecated in favor of `proxy:build-config`.
- The `plugin:list` command no longer outputs the version for the `plugn` binary.
- Users building docker images that run Dokku will need to use a new sudoer wrapper for the `docker-image-labeler` binary to work correctly. A reference version has been placed in the `docker` skeleton directory. This should only impact platform developers, and users of our Docker image will already have the file available.
- The `dokku` user's cron is now in use by Dokku itself. Customizations will be overwritten. Users are encouraged to use a cron entry in`/etc/cron.d/dokku` to avoid this issue.
- The `dokku` user's cron is now in use by Dokku itself. Customizations will be overwritten. Users are encouraged to use a cron file at`/etc/cron.d/dokku` to avoid this issue.
- As of 0.23.0, Dokku will now inject the `max-size` log driver option for applications. This is restricted to app-configured log driver values empty, `local` or `json-file` in 0.23.1 to increase setup compatibility. Users who configure alternative log drivers at the system level will need to either set the global `max-size` property to `unlimited` or switch to the built-in `vector` logging support.
@@ -19,7 +19,7 @@ Before upgrading, uninstall the registry plugin via `dokku plugin:uninstall regi
- The `dokku run` command now always removes the ephemeral container on exit. Users that need a persistent container should instead specify a `console` process type in their `Procfile` specifying an available shell (usually either `bash` or `sh`) and scale that container appropriately.
- The `pre-deploy` plugin trigger is now called internally by Dokku. Scheduler plugins should avoid calling this trigger, as any image changes introduced by subsequent trigger calls will be ignored.
- The default image used for Herokuish Buildpack builds is now `gliderlabs/herokuish:latest-20`, and is based on both the `heroku-20` stack as well as Ubuntu 20.04. Users that wish to stick with the old, `heroku-18`/Ubuntu 18.04 builder may specify `gliderlabs/herokuish:latest-18` as their builder image. Please see the [herokuish buildpack deployment documentation](/docs/deployment/builders/herokuish-buildpacks.md#customizing-the-buildpack-stack-builder) for more information on how to specify a custom buildpack stack builder.
- This change does not impact any users of Cloud Native Buildpacks.
- This change does not impact any users of Cloud Native Buildpacks.
- We fixed an issue that required extracting Procfiles at the beginning of a deploy. Due to this change, a `Dockerfile` app contains a `Procfile` that does not specify a `web` process will fail to start. Usage of a `Procfile` with _only_ a `release` command should be replaced with a `scripts.dokku.postdeploy` deployment task in the `app.json` file. The alternative is to define the `web` process in the `Procfile`. See the [deployment task documentation](/docs/advanced-usage/deployment-tasks.md) for more information.
- The `scheduler` plugin now controls the scheduler in use for deploys. Apps will have their `DOKKU_SCHEDULER` environment variables migrated to the scheduler plugin, after which that value will be removed from said app. Please see the [scheduler documentation](/docs/deployment/schedulers/scheduler-management.md) for more information.
- The `deploy-source` metadata from `apps:report` is now no longer computed on the fly, but hydrated at deploy time via the `deploy-source-set` trigger. This value may be empty until your next deploy.
- Additionally, the `deploy-source` trigger has now been removed.
- Additionally, the `deploy-source` trigger has now been removed.
- Herokuish build cache is now mounted from a docker volume - eg. `cache-node-js-app` - instead of the local filesystem. All existing app cache will be cleared upon upgrading past 0.29.0.
- The `vector` container integration now mounts config to `/etc/vector` instead of the path `/etc/vector/vector.json`, allowing users the ability to provide extra configuration for Vector Sinks. To take advantage of the new functionality, the vector container should be stopped (via `dokku logs:vector-stop`) and then started (via `dokku logs:vector-start`).
- The `traefik` integration now mounts config to `/data` instead of the path `/acme.json`, fixing permissions issues under certain architectures. To take advantage of the new functionality, the traefik container should be stopped (via `dokku traefik:stop`) and then started (via `dokku traefik:start`).
- Users no longer need to clear the `source-image` git property when transitioning from image-based deploys (`git:from-image` and `git:load-image`) to other deployment methods (git push, `git:from-archive`, `git:sync`).
- For deploys via the `git:from-image` and `git:load-image` commands, the `CHECKS` file is now extracted from the configured `WORKDIR` property of the image. For all other deploys - git push, `git:from-archive`, `git:sync` - will have the `CHECKS` extracted directly from the source code. The filename in both cases is `CHECKS` and cannot be modified.
- Port mappings are now auto-detected during the build process. Users may override detected port mappings via the `ports` plugin. A default port mapping of `http:80:5000` will be used if none is otherwise specified.
- Users building docker images that run Dokku will need to use a new sudoer wrapper for the `docker-container-healthchecker` binary to work correctly. A reference version has been placed in the `docker` skeleton directory. This should only impact platform developers, and users of our Docker image will already have the file available.
- The default image used for Herokuish Buildpack builds is now `gliderlabs/herokuish:latest-22`, and is based on both the `heroku-22` stack as well as Ubuntu 22.04. Users that wish to stick with the old, `heroku-20`/Ubuntu 20.04 builder may specify `gliderlabs/herokuish:latest-20` as their builder image. Please see the [herokuish buildpack deployment documentation](/docs/deployment/builders/herokuish-buildpacks.md#customizing-the-buildpack-stack-builder) for more information on how to specify a custom buildpack stack builder.
- The default image used for Cloud Native Buildpack builds is now `heroku/builder:22`, and is based on both the `heroku-22` stack as well as Ubuntu 22.04. Users that wish to stick with the old, `heroku-20`/Ubuntu 20.04 builder may specify `heroku/buildpacks:20` as their builder image. Please see the [herokuish buildpack deployment documentation](/docs/deployment/builders/herokuish-buildpacks.md#customizing-the-buildpack-stack-builder) for more information on how to specify a custom buildpack stack builder.
## Deprecations
- The `proxy:ports*` commands have been replaced with the new `ports` plugin. Users will be able to use the old `proxy:ports*` commands for a single minor release, and they will be removed in the next minor release.
- The `common#get_available_port()` function has been deprecated and will be removed in the next release. Users should avoid interacting with this function and instead use the `ports-get-available` plugin trigger for fetching an available port.
- The `proxy-configure-ports` plugin trigger has been deprecated and will be removed in the next release. Users should instead trigger the `ports-configure` plugin trigger.
- The `common#get_dockerfile_exposed_ports()` function is deprecated and will be removed in the next release. There is no replacement for this as it's only use in Dokku core was in the `builder-dockerfile` plugin.
- The `common#get_exposed_ports_from_image()` function is deprecated and will be removed in the next release. There is no replacement for this as it's only use in Dokku core was during the build process.
- The environment variable `DOKKU_PROXY_PORT_MAP` has been migrated to the properties system. Direct changes to the value will be ignored, and users should interact with port maps via the `ports` plugin.
- The `CHECKS` file is deprecated in favor of defining healthchecks in the `app.json` file. The [docker-container-healthchecker](https://github.com/dokku/docker-container-healthchecker) tool can be used to generate healthcheck entries in `app.json` format from existing `CHECKS` files. See the [zero-downtime deploy documentation](/docs/deployment/zero-downtime-deploys.md) for more information on how the new zero downtime check format works.
- ARM support is now deprecated, and will be removed in the next minor release. ARM releases are not tested in CI and do not get testing locally. Users of ARM installations on platforms such as the Raspberry PI should consider migrating to ARM64. ARM64 will continue to be supported by Dokku, and there are no plans to remove support for ARM64.
## Un-Deprecations
- The bare `apps` and `config` cli aliases are no longer deprecated. This better follows Heroku's output and is more useful to users. The subcommands will be treated as the primary, documented versions, while the aliases are there for convenience.
## Removals
- The variable `RAW_TCP_PORTS` is no longer exposed for `nginx.conf.sigil` templating.
- The environment variable `DOKKU_DOCKERFILE_PORTS` is no longer in use. Users wishing to change port mappings should instead use the `ports` plugin.
- The `common#get_app_raw_tcp_ports()` function has been removed in the next release. Users should instead use the `ports-get` plugin trigger for fetching ports for an app.
- The plugin trigger `network-compute-ports` has been removed. It's only use was in the `scheduler-docker-local` plugin, for exposing ports. It's functionality is now implemented via the `ports` plugin.
- The plugin trigger `network-get-port` has been removed. It's only use was in the `scheduler-docker-local` plugin, for recording ports. It's functionality is now implemented via the `ports` plugin.
- The following `pre-build-*` plugin triggers have been deprecated and will be removed in the next release. Users should instead trigger the `pre-build` plugin trigger.
- pre-build-buildpack
- pre-build-dockerfile
- pre-build-lambda
- pre-build-pack
- The following `pre-release-*` plugin triggers have been deprecated and will be removed in the next release. Users should instead trigger the `pre-release-builder` plugin trigger.
- pre-release-buildpack
- pre-release-dockerfile
- pre-release-lambda
- pre-release-pack
- The following `post-build-*` plugin triggers have been deprecated and will be removed in the next release. Users should instead trigger the `post-build` plugin trigger.
- post-build-buildpack
- post-build-dockerfile
- post-build-lambda
- post-build-pack
- The `CHECKS` file was deprecated in the previous release in favor of defining healthchecks in the `app.json` file. It's support and auto-migration to healthchecks in the `app.json` file will be removed in the next release. See the [zero-downtime deploy documentation](/docs/deployment/zero-downtime-deploys.md) for more information on how the new zero downtime check format works.
## Removals
- ARM support has been removed. Users of ARM installations on platforms such as the Raspberry PI should consider migrating to ARM64. ARM64 will continue to be supported by Dokku, and there are no plans to remove support for ARM64.
- The following proxy-port related code has been removed. It is replaced by the `ports` plugin and it's related plugin triggers.
- The `disable-chown` property of the `scheduler-docker-local` plugin has been removed. Mounted paths will no longer have file permissions changed during the pre-deploy phase. Files baked into the container image for herokuish builds will always be owned by the correct user.
- The `git:unlock` command has been removed. It was previously used to "unlock" a temporary directory that already existed. The directory the `git:unlock` command used to cleanup is now properly removed on exit of the `git:from-image` command.
- The k3s plugin no longer supports port mappings other than `https:443` and `http:80`. If no matching port map is specified, Dokku will use expose the app on the first port mapping, with priority given to `https` mappings over `http`.
- Golang functions to invoke plugin triggers named `PlugnTrigger*` have been removed in favor of `CallPlugnTrigger`.
## Changes
- The k3s scheduler now creates an Ingress object per domain instead of one per port mapping. This will cause a short amount of downtime during the next app deploy after upgrading to 0.34.0
- App lock files have been removed from the `/home/dokku` directory and moved into the `data/apps` directory.
- Logs are now rotated via `copytruncate` instead of `create` in logrotate.
- The k3s scheduler now defaults to nginx as it's default proxy implementation. The traefik proxy implementation is still available, though users will need to set the global `ingress-class` k3s property to `traefik` via the following command:
The `pre-deploy` plugin trigger is deprecated as of `0.34.4`. It is currently invoked during the `post-release-builder` plugin trigger, where image mutation is heavily discouraged. Users should instead move any trigger usage to the `pre-release-builder` plugin trigger. The `pre-deploy` plugin trigger will be removed in a future release.
- The provided `dokku/dokku:latest` Docker image now runs Ubuntu 24.04 Noble. Users that install custom packages within their docker-based installations should be sure to check package compatibility with Ubuntu 24.04.
- The default image used for Cloud Native Buildpack builds is now `heroku/builder:24`, and is based on both the `heroku-24` stack as well as Ubuntu 24.04. Users that wish to stick with the old, `heroku-22`/Ubuntu 22.04 builder may specify `heroku/buildpacks:22` as their builder image. Please see the [cloud native buildpack deployment documentation](/docs/deployment/builders/cloud-native-buildpacks.md#customizing-the-buildpack-stack-builder) for more information on how to specify a custom buildpack stack builder.
- The default image used for Herokuish Buildpack builds is now `gliderlabs/herokuish:latest-24`, and is based on both the `heroku-24` stack as well as Ubuntu 24.04. Users that wish to stick with the old, `heroku-22`/Ubuntu 22.04 builder may specify `gliderlabs/herokuish:latest-22` as their builder image. Please see the [herokuish buildpack deployment documentation](/docs/deployment/builders/herokuish-buildpacks.md#customizing-the-buildpack-stack-builder) for more information on how to specify a custom buildpack stack builder.
- The `vector` image used by Dokku for enhanced logging support has been upgraded from 0.39.x to 0.41.x. To take advantage of the new image, execute the following commands:
```
dokku logs:vector-stop
dokku logs:vector-start
```
- The `openresty` image used by Dokku for proxying via openresty has been upgraded from 0.8.0 to 0.9.0. To take advantage of the new image, execute the following commands:
- Process stop timeouts are now configured via the `ps` property `stop-timeout-seconds`. Existing `DOKKU_DOCKER_STOP_TIMEOUT` environment variables will be automatically migrated to the new value.
- Processes now default to a `30` second stop timeout.
- The `domains:clear` command no longer runs domain setup after clearing the domains. Use `domains:reset` or run `domains:setup` manually to have the same effect.
- The deprecated `DOKKU_DISABLE_ANSI_PREFIX_REMOVAL` setting has been removed. Dokku deploys no longer use shell escape codes to modify output, and thus deploy output may now contain `remote:` as a prefix in each lines output.
## Deprecations
Ubuntu 20.04 is now a deprecated installation target. The operating system will be considered EOL by Canonical in April 2025. Users are encouraged to upgrade to Ubuntu 24.04 or consider switching their instllation method to the [Docker-based installation method](/docs/getting-started/install/docker.md) to avoid any disruption in usage.
- The `app.json` file format is now parsed as JSONC and supports inline comments.
- The `scheduler-k3s:cluster-add` command is now `scheduler-k3s:cluster:add`.
- The `scheduler-k3s:cluster-list` command is now `scheduler-k3s:cluster:list`.
- The `scheduler-k3s:cluster-remove` command is now `scheduler-k3s:cluster:remove`.
## Removals
- Support for the `DOKKU_DOCKERFILE_CACHE_BUILD` environment variable has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for the `DOKKU_DOCKER_BUILD_OPTS` environment variable has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for the `no-cache` nixpacks property has been removed. Use the `docker-options` plugin to set build arguments for your app instead.
- Support for customizing the label-key for the caddy proxy has been removed. Always use `caddy.` as a prefix for your caddy directives.
- Dokku now generates a minimal nginx configuration for apps without running `web` processes (undeployed apps, apps with no `web` process type, or apps with stopped web processes). This configuration returns `502 Bad Gateway` responses, ensuring the app's domain resolves and monitoring tools can detect non-200 status codes. The configuration is automatically replaced with the full proxy configuration once the app is deployed with running `web` processes. See the [nginx documentation](/docs/networking/proxies/nginx.md#nginx-configuration-for-undeployed-apps) for more details.
- Users with custom `nginx.conf.sigil` templates that reference `DOKKU_APP_WEB_LISTENERS` should be aware that this variable may now be empty when the template is rendered for apps without running web processes. Custom templates should handle this case gracefully, for example by using a conditional to serve an error page instead of proxying:
- The path on disk to both the global `ENV` file and app `ENV` files have been moved. Users should reference environment variables via the provided plugin triggers rather than directly sourcing the ENV files. Existing ENV files are merged into the new location and removed once they have been drained. **Changed in 0.38.26:** removal previously happened on the subsequent Dokku install for app ENV files, and never happened at all for the global ENV file. **Changed in 0.38.27:** an ENV file found at the old path after its migration has been recorded is never merged into the new location, because the new location holds every change made since. Such a file is removed when its values agree with the current config, and otherwise moved aside to `ENV.migrated` with the keys it disagrees on named in a warning, so its values can still be applied by hand with `dokku config:set`. That copy is left for review and should be deleted afterwards: Dokku no longer reads it, and it holds everything it was not allowed to import - including keys that were unset on purpose, which for a revoked secret means a copy lingering on disk.
- During a fresh apt install, the upstream nginx default vhost files (`/etc/nginx/sites-enabled/default`, `/etc/nginx/sites-available/default`, and `/etc/nginx/conf.d/default.conf`) are renamed to `${path}.dokku-disabled` (not deleted) to avoid a `duplicate default server for 0.0.0.0:80` error. Operators with local customizations can recover them by inspecting the `.dokku-disabled` siblings. Upgrade-in-place installs do not touch any existing nginx files.
- Fresh apt installs now ship a catch-all default site at `/etc/nginx/conf.d/00-default-vhost.conf` that rejects requests with unknown Host headers using `ssl_reject_handshake on` (HTTPS) and `return 444` (HTTP). This replaces the manual workaround previously documented in the nginx docs. The behavior can be opted out at install time via the `dokku/install_default_site` debconf prompt. On nginx older than 1.19.4 (e.g., Debian Bullseye's nginx 1.18.0), the postinst installs an HTTP-only variant of the catch-all that omits the SSL listener and `ssl_reject_handshake`, since that directive is unsupported on those versions. See the [Default site documentation](/docs/networking/proxies/nginx.md#default-site).
- The `docker-local` scheduler now sends `SIGTERM` to old containers immediately after a successful deploy, 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 `wait-to-retire` grace period and `stop-timeout-seconds` hard-stop continue to apply as before. See the [zero downtime deploys documentation](/docs/deployment/zero-downtime-deploys.md#wait-to-retire) for more details.
- The `docker-local` scheduler no longer queues an image for retirement when another running container of the same app still uses it. This fixes the case where a `ps:rebuild` against an image-based deploy (`git:from-image`) produced an identical-SHA image and the `dokku-retire` cron timer would log `Image ... has running containers, skipping rm` on every run. Stuck entries from prior versions are pruned automatically on the next `ps:retire` run.
- All `:report` subcommands now accept the `--global` flag, which scopes the report to globally-configured properties. The flag composes with `--format json`, so a JSON report of global properties can be obtained via, for example, `dokku scheduler:report --global --format json`. Previously, combining `--global` with `--format json` was rejected with an "info flag" error, and `--global` on its own was treated as an unknown flag.
- Every `:report` key of the form `<plugin>-global-<property>` now returns the raw stored global value (empty when the property has never been set) instead of the resolved value with the built-in default substituted in. A new `<plugin>-computed-<property>` key has been added wherever a default existed and returns the effective value (per-app value, falling back to the global value, then to the built-in default). This affects `app-json`, `builder-dockerfile`, `builder-herokuish`, `builder-lambda`, `builder-nixpacks`, `builder-pack`, `builder-railpack`, `caddy`, `checks`, `git`, `haproxy`, `logs`, `network`, `nginx`, `openresty`, `proxy`, `registry`, `scheduler`, `scheduler-k3s` and `traefik`. External tooling that read `<plugin>-global-<property>` and depended on the default value should switch to `<plugin>-computed-<property>`. The bare `<plugin>-<property>` keys for caddy/haproxy/traefik/openresty global-only properties (`caddy-image`, `haproxy-log-level`, `traefik-api-enabled`, `openresty-image`, `openresty-letsencrypt-email`, `openresty-letsencrypt-server`, `openresty-allowed-letsencrypt-domains-func-base64`, etc.) have also been replaced by the `global-` and `computed-` pair.
- The `ps` and `cron` plugins now follow the same `<plugin>-global-<property>` / `<plugin>-computed-<property>` convention. The `ps:report` keys `stop-timeout-seconds`, `global-stop-timeout-seconds`, and `computed-stop-timeout-seconds` have been renamed to `ps-stop-timeout-seconds`, `ps-global-stop-timeout-seconds`, and `ps-computed-stop-timeout-seconds`. The `cron:report` keys `cron-mailfrom` and `cron-mailto` have been renamed to `cron-global-mailfrom` and `cron-global-mailto`, and new `cron-computed-mailfrom` and `cron-computed-mailto` keys have been added. The corresponding user-facing `--<flag>` arguments to `ps:report` and `cron:report` were renamed alongside the JSON keys; no aliases are kept. Additionally, both `ps:report --global` and `cron:report --global` now emit the `<plugin>-computed-<property>` keys for every settable global property with a default (`ps-computed-procfile-path`, `ps-computed-stop-timeout-seconds`, `cron-computed-maintenance`, `cron-computed-mailfrom`, `cron-computed-mailto`), matching the shape used by the other plugins.
- A second round of `:report` additions surfaces every remaining settable-but-unreported property under the same raw/global/computed convention so external tooling can verify drift via `:report --format json` without falling back to a generic bash task. The `ps` plugin gains `--ps-dockerfile-start-cmd` and `--ps-computed-dockerfile-start-cmd`, `--ps-start-cmd` and `--ps-computed-start-cmd`, and the `--ps-skip-deploy` / `--ps-global-skip-deploy` / `--ps-computed-skip-deploy` triple (default `false`). The `builder` plugin gains the `--builder-skip-cleanup` triple (default `false`). The `scheduler` plugin gains the `--scheduler-shell` triple. The `proxy` plugin gains the `--proxy-proxy-port` and `--proxy-proxy-ssl-port` triples and exposes the raw `disabled` property as `--proxy-disabled` / `--proxy-computed-disabled`, alongside the existing inverted `--proxy-enabled`. The `openresty` plugin gains `--openresty-global-log-level` and `--openresty-computed-log-level` (default `ERROR`). The `nginx` plugin gains the `--nginx-nginx-service-command` triple. The `scheduler-k3s` plugin gains `--scheduler-k3s-global-token`, but the value is masked as `*******` in default stdout output; the raw value is returned only when the report is requested via `--format json` or when this flag is queried explicitly by name. The traefik `dns-provider-<env_var>` keys are reported as `--traefik-global-dns-provider-<env_var>` and follow the same masking and explicit-query rules, as does the traefik `basic-auth-password` property, whose `--traefik-global-basic-auth-password` and `--traefik-computed-basic-auth-password` keys are masked in default stdout output.
- All Go-implemented plugins (`app-json`, `apps`, `builder`, `buildpacks`, `builds`, `cron`, `docker-options`, `logs`, `network`, `ports`, `proxy`, `ps`, `registry`, `resource`, `scheduler`, `scheduler-k3s`, `storage`) now emit JSON keys from `:report --format json` without the `<plugin>-` head segment, matching the shape bash plugins have always emitted. For example, `dokku ps:report myapp --format json` now contains `stop-timeout-seconds`, `global-stop-timeout-seconds`, and `computed-stop-timeout-seconds` keys. The CLI flag names (`--ps-stop-timeout-seconds`, etc.) are unchanged, and `:set` semantics are unchanged. For backwards compatibility during the 0.38.x patch series, the old `<plugin>-<property>` JSON keys are emitted side-by-side with the new keys, so external scripts reading either shape continue to work. The legacy keys will be dropped in a future major release. External JSON consumers should migrate to the new key shape.
- The `scheduler-k3s` plugin now manages env config and the dokku-generated image pull Secret as their own helm releases with stable names (`config-{app}` and `pull-secret-{app}`) rather than bundling them into the app helm chart with a per-deploy timestamp suffix (`env-{app}.{ts}` / `ims-{app}.{ts}`). This fixes two bugs: a helm rollback of the app chart no longer deletes Secrets that older ReplicaSets still reference, and the Deployment's `imagePullSecrets` list no longer accumulates references to nonexistent Secrets across deploys. The next deploy of an app switches the Deployment's `envFrom` and `imagePullSecrets` references to the stable names and prunes any leaked entries; existing live Deployments do not need to be patched manually. App rename now also uninstalls the old `tls-{app}`, `config-{app}`, and `pull-secret-{app}` releases under the previous app name; the new name's releases are recreated on the next deploy or certs sync.
- **New in 0.38.25:** Values supplied through docker options, `dokku run`'s `-e`/`--env` flag, and `--ttl-seconds` are no longer evaluated by the shell when assembling a container's arguments; they are now tokenized and passed through verbatim. This closes a command-injection vector where a `$(...)` or backtick expression in one of these values executed on the host as the `dokku` user during build, deploy, or run. As a result, shell metacharacters such as `$(...)`, backticks, `$VAR`, and globs in these values are treated literally instead of being expanded, and `--ttl-seconds` must now be a plain integer. Existing Traefik docker-options labels (those whose label key begins with `traefik.`) whose backticks were stored with a stray backslash are repaired automatically the first time `dokku` runs after the upgrade, so they become valid on the next deploy.
- **New in 0.38.26:** Docker options drained out of the pre-0.38.0 `DOCKER_OPTIONS_<PHASE>` files were copied verbatim rather than being re-serialized the way `docker-options:add` stores them, so `docker-options:remove` compared the canonical string it builds against a value that could never match it and exited successfully without removing anything. Removal now matches stored options by shell word instead of by exact string, so those entries can be removed with the value as originally written. Stored options are also rewritten into the canonical form the first time `dokku` runs after the upgrade: values whose shell metacharacters were left unquoted are quoted, and an entry that carried several flags on one line becomes one entry per flag, which additionally fixes `ps:report` reading a restart policy off such a line and the `k3s` scheduler translating only the first of several `--cap-add`/`--sysctl` flags. Options added through `docker-options:add` are already canonical and are left untouched.
- **New in 0.38.26:** Deprecated `DOKKU_*` config variables belonging to plugins whose install step runs before the `config` plugin's were not migrated to their plugin property on the upgrade run. Install steps fire in alphabetical order, so `apps`, `builder`, and `checks` read an app's environment before the `config` plugin had relocated the `ENV` file, found nothing, and moved nothing - without reporting anything. `dokku config:show` kept listing the variable while the plugin behaved as though it were unset, which for `DOKKU_CHECKS_SKIPPED` meant a process type silently regained a health check it was meant to skip. The relocation is now performed before any deprecated variable is read, regardless of install order. Affected installs recover on their next `dokku plugin:install --core`, which the upgrade already runs; the variables listed below can also be re-applied by hand using their replacement command.
- **New in 0.38.27:** The 0.38.26 upgrade merged the leftover pre-0.38.0 `ENV` file back over the current config. Releases 0.38.0 through 0.38.25 recorded the migration and left that file on disk on purpose, and 0.38.26 read it as a hand-edit, so the environment as it stood at the 0.38.x upgrade won over every `dokku config:set` and `dokku config:unset` made since - including reinstating variables and secrets that had been deliberately unset. Nothing appeared broken, because running containers keep the environment they were created with; the rewound values would have reached containers on the next deploy. The 0.38.26 run consumed the leftover file, so this cannot happen a second time, but it also cannot be undone automatically. To check an app that was upgraded to 0.38.26 and has a container still running from before that upgrade, compare each key in `dokku config:show <app>` against `docker exec <container> printenv <key>` - `GIT_REV` is expected to differ after a deploy, anything else that differs was rewound. Repair with `dokku config:set --no-restart <app> KEY=VALUE` for values that regressed and `dokku config:unset --no-restart <app> KEY` for variables that came back.
- The storage plugin now treats persistent volumes as named, scheduler-aware first-class resources via `storage:create`, `storage:mount`, `storage:set`, and `storage:destroy`. The legacy `storage:mount <app> <host>:<container>` colon form continues to work on docker-local apps but is deprecated; on k3s apps it is rejected. Existing colon-form mounts are migrated automatically the first time the new storage plugin runs (during the install trigger) - they appear as `legacy-<hash>` entries in `storage:list-entries`. The migration is idempotent and tied to a per-app flag file at `$DOKKU_LIB_ROOT/config/storage/.migrated/<app>`; deleting that file forces a re-scan on the next install. The `storage:ensure-directory` command keeps working but now emits a deprecation warning - prefer `storage:create <name> [<path>]` (the path defaults to the same `$DOKKU_LIB_ROOT/data/storage/<name>` location). Storage entry names must now be DNS-1123 labels of 45 characters or less so they can be used verbatim as Helm release and Kubernetes resource names; underscores and uppercase characters that the older `ensure-directory` validator accepted are rejected for new names. The migration synthesizer always uses lowercase hex hashes so existing data is never locked out.
### TLS handshake behavior change
With the new catch-all installed on nginx 1.19.4+, an HTTPS request to a hostname that matches a configured dokku app but where the app has no TLS certificate configured will have its TLS handshake rejected by the catch-all (via `ssl_reject_handshake on`). Previously, nginx fell through to the lexicographically first port-443 server block and presented that block's certificate, producing a cert-mismatch error on the client. The new behavior is a correctness improvement, but operators who deliberately relied on the old fall-through certificate (for monitoring probes, for example) need to either configure a certificate for the target app or remove the catch-all on that host. Existing apps that already have certificates configured are unaffected: nginx selects the right server block via SNI before TLS completion, so the catch-all is never consulted for legitimate requests.
This change does not apply to nginx older than 1.19.4 (e.g., Debian Bullseye's nginx 1.18.0), where the catch-all is installed as an HTTP-only variant. On those systems, HTTPS handshakes to unknown hosts continue to fall through to the first port-443 server block as before.
### Environment variables migrated to plugin properties
A number of `DOKKU_*` config environment variables have been replaced with properly-namespaced plugin properties. Existing values are migrated automatically the first time `dokku` runs after the upgrade, and the original config variable is unset. No manual action is required.
Going forward, configure these settings using the property commands listed below. Setting the deprecated env vars via `dokku config:set` will no longer have any effect.
| Deprecated Env Var | Replacement Command |
|---|---|
| `DOKKU_APP_PROXY_TYPE` | `dokku proxy:set <app> type <value>` |
`DOKKU_PARALLEL_ARGUMENTS` is removed entirely; it has no replacement.
`DOKKU_SKIP_CLEANUP` continues to be honored when set in `/etc/environment` or `~dokku/.dokkurc/*` so that bootstrap-time configuration keeps working, but the `builder skip-cleanup` property is the canonical interface and takes precedence when set.
- The nginx-vhosts template language is now [sigil](https://github.com/gliderlabs/sigil)
- No need to escape literal `$` characters (or other "bash-isms")
- Template variables are represented as {{ .VARIABLE_NAME }}
- A detailed list of template variables can be found [here](/docs/networking/proxies/nginx.md#available-template-variables)
- No need to escape literal `$` characters (or other "bash-isms")
- Template variables are represented as {{ .VARIABLE_NAME }}
- A detailed list of template variables can be found [here](/docs/networking/proxies/nginx.md#available-template-variables)
- A custom nginx-vhosts template must be named `nginx.conf.sigil`
- The default path for this custom template is the root of your repo (i.e. `/app` in the container or `WORKDIR` if defined in a dockerfile app)
- Dokku no longer looks for this file in `/home/dokku/node-js-app` on the Dokku server
- Check out an example template [here](/docs/networking/proxies/nginx.md)
- The default path for this custom template is the root of your repo (i.e. `/app` in the container or `WORKDIR` if defined in a dockerfile app)
- Dokku no longer looks for this file in `/home/dokku/node-js-app` on the Dokku server
- Check out an example template [here](/docs/networking/proxies/nginx.md)
- Support for server-wide SSL certs have been dropped in favor of using the `certs` plugin
-`dokku certs:add node-js-app < certs.tar`
-`dokku certs:add node-js-app < certs.tar`
- All domains for an SSL-enabled app will be redirected to https by default
- This can be overridden with a custom template
- This can be overridden with a custom template
- Replaced "magic" `NO_VHOST` variable with `domains:enable/disable`
- Simplified zero downtime control
-`checks:enable/disable`
-`checks:enable/disable`
## Dockerfile apps with exposed ports
- Dockerfiles with `EXPOSE` clauses will get [all **tcp** ports proxied by default](/docs/deployment/builders/dockerfiles.md#exposed-ports)
- Note that nginx will proxy the same port numbers to listen publicly
- UDP ports can be exposed by disabling the [nginx proxy](/docs/networking/proxy-management.md) with `dokku proxy:disable node-js-app`
- Note that nginx will proxy the same port numbers to listen publicly
- UDP ports can be exposed by disabling the [nginx proxy](/docs/networking/proxy-management.md) with `dokku proxy:disable node-js-app`
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.