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.