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.
4.2 KiB
0.38.0 Migration Guide
Changes
-
Dokku now generates a minimal nginx configuration for apps without running
webprocesses (undeployed apps, apps with nowebprocess type, or apps with stopped web processes). This configuration returns502 Bad Gatewayresponses, 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 runningwebprocesses. See the nginx documentation for more details. -
Users with custom
nginx.conf.sigiltemplates that referenceDOKKU_APP_WEB_LISTENERSshould 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:location / { {{ if $.DOKKU_APP_WEB_LISTENERS }} proxy_pass http://{{ $.APP }}-{{ $upstream_port }}; {{ else }} return 502; {{ end }} } -
The path on disk to both the global
ENVfile and appENVfiles have been moved. Users should reference environment variables via the provided plugin triggers rather than directly sourcing the ENV files. Existing ENV files are left untouched and will be removed on the subsequent Dokku install. -
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 aduplicate default server for 0.0.0.0:80error. Operators with local customizations can recover them by inspecting the.dokku-disabledsiblings. 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.confthat rejects requests with unknown Host headers usingssl_reject_handshake on(HTTPS) andreturn 444(HTTP). This replaces the manual workaround previously documented in the nginx docs. The behavior can be opted out at install time via thedokku/install_default_sitedebconf prompt. See the Default site documentation. -
The
docker-localscheduler now sendsSIGTERMto old containers immediately after a successful deploy, rather than waitingwait-to-retireseconds before signaling. This matches Heroku's graceful-shutdown contract and lets applications begin draining in-flight work as soon as proxy traffic switches. Thewait-to-retiregrace period andstop-timeout-secondshard-stop continue to apply as before. See the zero downtime deploys documentation for more details. -
The
docker-localscheduler no longer queues an image for retirement when another running container of the same app still uses it. This fixes the case where aps:rebuildagainst an image-based deploy (git:from-image) produced an identical-SHA image and thedokku-retirecron timer would logImage ... has running containers, skipping rmon every run. Stuck entries from prior versions are pruned automatically on the nextps:retirerun.
TLS handshake behavior change
With the new catch-all installed, 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.