Commit Graph

4694 Commits

Author SHA1 Message Date
Dokku Bot
029e98673f Release 0.38.3
# History

## 0.38.3

Install/update via the bootstrap script:

```shell
wget -NP . https://dokku.com/install/v0.38.3/bootstrap.sh
sudo DOKKU_TAG=v0.38.3 bash bootstrap.sh
```

### Bug Fixes

- #8602: @josegonzalez Reject per-app sets for global-only proxy properties
- #8601: @josegonzalez Rename app-json:report flags to match property
- #8600: @josegonzalez Report info-flag should not error when app undeployed

### New Features

- #8599: @josegonzalez Add docker healthcheck to dokku container
2026-05-11 08:04:48 +00:00
Jose Diaz-Gonzalez
3ddce21aef Merge pull request #8602 from dokku/8597-caddy-haproxy-traefik-accept-per-app-set-but-report-only-returns-global-value 2026-05-11 01:04:14 -04:00
Jose Diaz-Gonzalez
cdce68f8a2 Merge pull request #8601 from dokku/8598-app-json-set-appjson-path-succeeds-but-app-json-appjson-path-is-not-a-valid-report-flag
Rename app-json:report flags to match property
2026-05-10 23:58:05 -04:00
Jose Diaz-Gonzalez
822b7dddcd fix: reject per-app sets for global-only proxy properties
`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.
2026-05-10 22:42:57 -04:00
Jose Diaz-Gonzalez
4eee229bbc fix: rename app-json:report flags to match property
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.
2026-05-10 22:32:16 -04:00
Jose Diaz-Gonzalez
7b515ea129 refactor: drop unused value_exists from report functions
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.
2026-05-10 22:23:46 -04:00
Jose Diaz-Gonzalez
bd748052a1 fix: report info-flag should not error when app undeployed
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.
2026-05-10 22:15:27 -04:00
Dokku Bot
a553f04966 Release 0.38.2
# History

## 0.38.2

Install/update via the bootstrap script:

```shell
wget -NP . https://dokku.com/install/v0.38.2/bootstrap.sh
sudo DOKKU_TAG=v0.38.2 bash bootstrap.sh
```

### Security

- #8590: @josegonzalez Restrict app names to prevent command injection
- #8591: @josegonzalez Harden archive extraction against symlink traversal
- #8589: @josegonzalez Enforce 0600 permissions on .netrc credentials file
- #8588: @josegonzalez Sanitize openresty include filenames to prevent eval injection

### Bug Fixes

- #8593: @josegonzalez Gate ssl_reject_handshake behind nginx 1.19.4
- #8578: @josegonzalez Reference SOURCECODE_WORK_DIR in builder core-post-extract

### Documentation

- #8592: @josegonzalez Add security section to release changelog
- #8587: @vixalien Correct buildkit builder code block syntax
- #8580: @othercorey Set issue type in bug report template

### Tests

- #8586: @josegonzalez Count assert_output_contains matches as fixed strings
- #8581: @dependabot[bot] chore(deps): bump golang from 1.26.2 to 1.26.3 in /tests/apps/go-fail-predeploy
- #8582: @dependabot[bot] chore(deps): bump golang from 1.26.2 to 1.26.3 in /tests/apps/gogrpc
- #8584: @dependabot[bot] chore(deps): bump golang from 1.26.2 to 1.26.3 in /tests/apps/go-fail-postdeploy
- #8583: @dependabot[bot] chore(deps): bump golang from 1.26.2 to 1.26.3 in /tests/apps/zombies-dockerfile-tini
- #8585: @dependabot[bot] chore(deps): bump golang from 1.26.2 to 1.26.3 in /tests/apps/zombies-dockerfile-no-tini
- #8574: @dependabot[bot] chore(deps): bump node from 25-alpine to 26-alpine in /tests/apps/dockerfile-noexpose
- #8575: @dependabot[bot] chore(deps): bump node from 25-alpine to 26-alpine in /tests/apps/dockerfile-procfile-bad
- #8577: @dependabot[bot] chore(deps): bump node from 25-alpine to 26-alpine in /tests/apps/dockerfile-app-json-formations
- #8576: @dependabot[bot] chore(deps): bump node from 25-alpine to 26-alpine in /tests/apps/dockerfile
- #8573: @dependabot[bot] chore(deps): bump node from 25-alpine to 26-alpine in /tests/apps/dockerfile-procfile

### Dependencies

- #8579: @josegonzalez Use type prefix for dokku-bot dependency label
2026-05-10 20:17:51 +00:00
Jose Diaz-Gonzalez
9adf6e5f36 Merge pull request #8593 from dokku/fix-debian-bullseye-ssl-reject-handshake 2026-05-10 16:16:16 -04:00
Jose Diaz-Gonzalez
392ac73d33 fix: gate ssl_reject_handshake behind nginx 1.19.4
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.
2026-05-09 16:32:30 -04:00
Jose Diaz-Gonzalez
dbac12e9f1 refactor: route bash app name validation through go
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.
2026-05-09 16:00:51 -04:00
Jose Diaz-Gonzalez
93f87a0f07 fix: restrict app names to prevent command injection
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.
2026-05-09 16:00:51 -04:00
Jose Diaz-Gonzalez
e78d3bcc78 Merge pull request #8591 from dokku/arbitrary-file-write
Harden archive extraction against symlink traversal
2026-05-09 15:58:31 -04:00
Jose Diaz-Gonzalez
33dd8005dd Merge pull request #8589 from dokku/netrc-permissions 2026-05-09 15:36:10 -04:00
Jose Diaz-Gonzalez
9decf16ea1 feat: configure archive limits via git properties
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.
2026-05-09 13:08:23 -04:00
Jose Diaz-Gonzalez
2df0791fcd fix: prevent tar symlink traversal in archive extraction
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.
2026-05-09 12:54:42 -04:00
Jose Diaz-Gonzalez
6eb8b8632c fix: enforce 0600 permissions on .netrc credentials file
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.
2026-05-09 12:22:17 -04:00
Jose Diaz-Gonzalez
a70728f61e fix: sanitize openresty include filenames to prevent eval injection
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.
2026-05-09 12:20:50 -04:00
Jose Diaz-Gonzalez
47c8141148 Merge pull request #8578 from dokku/8566-core-post-extract-in-four-builder-plugins-fails-under-bash-5-3
Reference SOURCECODE_WORK_DIR in builder core-post-extract
2026-05-08 17:06:10 -04:00
Dokku Bot
983c462904 Release 0.38.1
# History

## 0.38.1

Install/update via the bootstrap script:

```shell
wget -NP . https://dokku.com/install/v0.38.1/bootstrap.sh
sudo DOKKU_TAG=v0.38.1 bash bootstrap.sh
```

### Bug Fixes

- #8563: @josegonzalez Source property-functions where fn-plugin-property-* helpers are used
- #8559: @josegonzalez Install cnb pack from github releases instead of ppa
- #8558: @josegonzalez Chown migrated legacy storage entries to dokku
- #8545: @josegonzalez Deflake haproxy bats tests

### Refactors

- #8546: @josegonzalez Consolidate nginx.conf.sigil server blocks

### Documentation

- #8548: @josegonzalez Use explicit type property in proxy:set examples
- #8547: @josegonzalez Document plugin properties migrated from env vars
- #8544: @josegonzalez Fix reference to when the build plugin was introduced

### Tests

- #8565: @dependabot[bot] chore(deps): bump google.golang.org/grpc from 1.80.0 to 1.81.0 in /tests/apps/gogrpc
- #8568: @dependabot[bot] chore(deps): bump gunicorn from 25.3.0 to 26.0.0 in /tests/apps/multi
- #8572: @dependabot[bot] chore(deps): bump django from 5.2.13 to 5.2.14 in /tests/apps/dockerfile-release
- #8570: @dependabot[bot] chore(deps): bump gunicorn from 25.3.0 to 26.0.0 in /tests/apps/dockerfile-release
- #8567: @dependabot[bot] chore(deps): bump gunicorn from 25.3.0 to 26.0.0 in /tests/apps/python-flask

### Dependencies

- #8571: @dependabot[bot] chore(deps): bump traefik from v3.6.15 to v3.7.0 in /plugins/traefik-vhosts
- #8569: @dependabot[bot] chore(deps): bump github.com/traefik/traefik/v2 from 2.11.44 to 2.11.45 in /plugins/scheduler-k3s
- #8561: @dokku-bot chore: bump pack to 0.40.4
- #8555: @dependabot[bot] chore(deps): bump github.com/mattn/go-isatty from 0.0.20 to 0.0.22 in /plugins/app-json
- #8556: @dependabot[bot] chore(deps): bump github.com/Masterminds/semver/v3 from 3.4.0 to 3.5.0 in /plugins/scheduler-k3s
- #8550: @dokku-bot chore: bump docker-container-healthchecker to 0.15.2
- #8553: @dokku-bot chore: bump dokku-event-listener to 0.19.1
- #8552: @dokku-bot chore: bump lambda-builder to 0.9.3
- #8551: @dokku-bot chore: bump procfile-util to 0.20.7
- #8554: @dependabot[bot] chore(deps): bump peter-evans/create-pull-request from 7 to 8
2026-05-07 17:29:53 +00:00
Jose Diaz-Gonzalez
eb17a383c6 fix: reference SOURCECODE_WORK_DIR in builder core-post-extract
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`.
2026-05-07 12:39:46 -04:00
Jose Diaz-Gonzalez
c676a09bd5 Merge pull request #8571 from dokku/dependabot/docker/plugins/traefik-vhosts/traefik-v3.7.0
chore(deps): bump traefik from v3.6.15 to v3.7.0 in /plugins/traefik-vhosts
2026-05-07 07:08:53 -04:00
dependabot[bot]
494c42428f chore(deps): bump traefik in /plugins/traefik-vhosts
Bumps traefik from v3.6.15 to v3.7.0.

---
updated-dependencies:
- dependency-name: traefik
  dependency-version: v3.7.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-06 13:55:24 +00:00
dependabot[bot]
d573054731 chore(deps): bump github.com/traefik/traefik/v2
Bumps [github.com/traefik/traefik/v2](https://github.com/traefik/traefik) from 2.11.44 to 2.11.45.
- [Release notes](https://github.com/traefik/traefik/releases)
- [Changelog](https://github.com/traefik/traefik/blob/v2.11.45/CHANGELOG.md)
- [Commits](https://github.com/traefik/traefik/compare/v2.11.44...v2.11.45)

---
updated-dependencies:
- dependency-name: github.com/traefik/traefik/v2
  dependency-version: 2.11.45
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-05 13:55:27 +00:00
Jose Diaz-Gonzalez
aea322be6f chore: use old path 2026-05-04 13:17:49 -04:00
Jose Diaz-Gonzalez
473bcce688 fix: use inline source instead of global source
Ensure property-functions are sourced only if not already defined.
2026-05-04 09:32:09 -04:00
Jose Diaz-Gonzalez
964c0fc4e9 fix: source property-functions where fn-plugin-property-* helpers are used
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.
2026-05-04 06:11:22 -04:00
Jose Diaz-Gonzalez
179d09fdd5 fix: chown migrated legacy storage entries to dokku
`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.
2026-05-02 05:37:11 -04:00
Jose Diaz-Gonzalez
ea807bb46e chore: bump go modules 2026-05-02 03:46:40 -04:00
dependabot[bot]
2c3ed3ad14 chore(deps): bump github.com/mattn/go-isatty in /plugins/app-json
Bumps [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) from 0.0.20 to 0.0.22.
- [Commits](https://github.com/mattn/go-isatty/compare/v0.0.20...v0.0.22)

---
updated-dependencies:
- dependency-name: github.com/mattn/go-isatty
  dependency-version: 0.0.22
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-02 03:46:23 -04:00
Jose Diaz-Gonzalez
4f0a7e63f3 Merge pull request #8556 from dokku/dependabot/go_modules/plugins/scheduler-k3s/github.com/Masterminds/semver/v3-3.5.0
chore(deps): bump github.com/Masterminds/semver/v3 from 3.4.0 to 3.5.0 in /plugins/scheduler-k3s
2026-05-02 03:45:40 -04:00
dependabot[bot]
3bf2478393 chore(deps): bump github.com/Masterminds/semver/v3
Bumps [github.com/Masterminds/semver/v3](https://github.com/Masterminds/semver) from 3.4.0 to 3.5.0.
- [Release notes](https://github.com/Masterminds/semver/releases)
- [Changelog](https://github.com/Masterminds/semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Masterminds/semver/compare/v3.4.0...v3.5.0)

---
updated-dependencies:
- dependency-name: github.com/Masterminds/semver/v3
  dependency-version: 3.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-01 16:31:06 +00:00
Jose Diaz-Gonzalez
e8d8b0683a fix: preserve info flag in plugin reports with --global
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.
2026-04-30 21:05:46 -04:00
Jose Diaz-Gonzalez
53ef8c7780 fix: deflake haproxy bats tests
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.
2026-04-30 18:40:57 -04:00
Jose Diaz-Gonzalez
465de6cc71 refactor: consolidate nginx.conf.sigil server blocks
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.
2026-04-30 16:36:45 -04:00
Dokku Bot
7dfe8dd336 Release 0.38.0
# 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
2026-04-30 17:38:51 +00:00
Jose Diaz-Gonzalez
c0794abc30 Merge pull request #8538 from dokku/6814-k3s-plugin-add-pv-option
Add scheduler-aware named storage entries
2026-04-30 12:10:30 -04:00
Jose Diaz-Gonzalez
f020b76e11 Merge pull request #3697 from dokku/track-deploys
Migrate builds plugin to go and track per-build records
2026-04-30 12:08:11 -04:00
Jose Diaz-Gonzalez
7cd4493cc7 Merge pull request #8541 from dokku/dependabot/docker/plugins/traefik-vhosts/traefik-v3.6.15
chore(deps): bump traefik from v3.6.14 to v3.6.15 in /plugins/traefik-vhosts
2026-04-30 10:15:10 -04:00
dependabot[bot]
2210307e42 chore(deps): bump traefik in /plugins/traefik-vhosts
Bumps traefik from v3.6.14 to v3.6.15.

---
updated-dependencies:
- dependency-name: traefik
  dependency-version: v3.6.15
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-30 13:54:23 +00:00
Jose Diaz-Gonzalez
f0d088bc1d test: cover the legacy -v migration with go and bats tests
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.
2026-04-30 02:37:01 -04:00
Jose Diaz-Gonzalez
ea25c5b6e2 fix: keep operator stdout when teeing build output to file 2026-04-30 02:02:02 -04:00
Jose Diaz-Gonzalez
67e4cf04ab feat: migrate builds plugin to go and track per-build records
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.
2026-04-30 01:18:03 -04:00
Jose Diaz-Gonzalez
e9a53ac82d fix: propagate storage:exec exit codes and route legacy mounts to attachments
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.
2026-04-30 01:10:00 -04:00
Jose Diaz-Gonzalez
cdbc91048a fix: chown the storage registry tree to the dokku user
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.
2026-04-30 00:01:54 -04:00
Jose Diaz-Gonzalez
58042b9330 feat: delegate storage:exec to scheduler plugins, harden the flow
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.
2026-04-29 23:29:30 -04:00
Jose Diaz-Gonzalez
d75228f165 fix: storage:list reads from attachments, deprecate storage-list trigger
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.
2026-04-29 22:51:50 -04:00
Jose Diaz-Gonzalez
6a5d568944 fix: remove the per-app property folder on app delete and rename
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.
2026-04-29 22:39:12 -04:00
Jose Diaz-Gonzalez
89afd09087 fix: storage plugin install setup and post-delete permissions
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.
2026-04-29 22:36:00 -04:00
Jose Diaz-Gonzalez
1ca961251d feat: add storage:set, storage:exec, storage:wait, storage:report --global
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.
2026-04-29 14:51:49 -04:00