v4.2 - #10872
Merged
Merged
v4.2#10872
Conversation
Authorize cloud provider token access, audit sensitive operations, and standardize public IDs across deployment and resource flows.
Prevent users without update permission from reading notification credentials and manual webhook secrets in Livewire state or rendered forms.
Require read:sensitive for nested server logdrain and sentinel fields in application and database API responses. Limit deployment configuration column migration SQL to PostgreSQL.
Introduce a shared status badge component and reuse it across resource status views, service cards, and the server navbar. Replace icon-only refresh controls with consistent badge buttons and cover the new status layout with feature tests.
Unify application, database, and service headings with mobile-friendly resource menus, route-aware configuration tabs, and confirmation triggers for advanced actions. Standardize restart warnings with status badges and cover the responsive menu and badge rendering behavior with feature tests.
Move GitHub App JWT generation and slug synchronization into shared helpers so installation URLs use the canonical GitHub slug. Encode GHE organization path segments and keep the app-scoped fallback for blank organizations.
Normalize GitHub organization values and derive API URLs for GitHub.com, GHE.com, and enterprise hosts when creating or updating GitHub Apps.
Replace the legacy sync:bunny flags with an interactive CDN sync flow for service templates and release metadata. Serve official service templates from the Coollabs CDN, update version metadata, and remove obsolete helper scripts.
Bumps [web-auth/webauthn-lib](https://github.com/web-auth/webauthn-lib) from 5.3.3 to 5.3.5. - [Commits](web-auth/webauthn-lib@5.3.3...5.3.5) --- updated-dependencies: - dependency-name: web-auth/webauthn-lib dependency-version: 5.3.5 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com>
Persist DigitalOcean, Hetzner, and Vultr servers before public IP assignment, then backfill placeholder addresses from provider state. Treat partial Sentinel snapshots as non-authoritative and document the destinations API with OpenAPI schemas.
Track provider state independently, skip SSH work for placeholder IPs, and clean up failed cloud server provisioning.
5 tasks done
Expand configuration snapshots, handle defaults from older snapshots, and refresh configuration state after Livewire setting changes.
Add service database CRUD, logs, and lifecycle actions, and document service application operations with OpenAPI tests.
Enable scheduled ClickHouse backups across the job, API, and UI, and guard unsupported database types via isBackupSolutionAvailable(). Convert Stripe subscription sync from a job to an action with clearer discrepancy resolution, and add cloud:export-users plus cloud:cleanup-unverified-users with tests.
Wrap Vultr server creation in DB transactions and delete the remote instance when local persistence fails (API and Livewire). Scope plus/dot email normalization to gmail.com/googlemail.com only. Use throw:false on DigitalOcean/Vultr HTTP retries, and normalize service log line counts via normalizeLogLines.
This was referenced Jul 16, 2026
Keep the dev container as root for s6 init so composer can create vendor/ on root-owned mounts, then chown writable paths to www-data. Move init-setup into a shell script and expose VITE_HOST/PORT for remote HMR (LAN/Tailscale) with Vite listening on 0.0.0.0.
Make start/stop/restart, deploy, enable/disable, and server validate POST-only, with GET returning 405. Server validate accepts optional install and uses ValidateAndInstallServerJob. Update OpenAPI and tests.
StuMason
added a commit
to StuMason/coolify-mcp
that referenced
this pull request
Jul 29, 2026
Coolify v4.2 (coollabsio/coolify#10872) requires POST on state-changing endpoints and returns a hard 405 for GET. Six client call sites still sent GET: service start/stop/restart, deployByTagOrUuid, enableApi/disableApi, and validateServer (which passed no method, so it defaulted to GET). Checked upstream routes/api.php at v4.1.2, v4.0.0 and older betas to work out whether fixing this breaks anyone still on 4.1. It splits in two: - Service start/stop/restart and /deploy were already registered Route::match(['get','post']) well before v4.2, so they now send POST unconditionally. Application and database start/stop have been POSTing against 4.1 estates all along, which is the same route shape, so this is proven rather than assumed. - /enable, /disable and /servers/{uuid}/validate genuinely diverge: Route::get only up to v4.1.2, Route::post only from v4.2. Neither method works everywhere, so these send POST and retry once with GET on a 405, caching the resolved method per endpoint. The retry is safe because a 405 is raised by the router before the controller runs, so nothing executed and no state change can double-fire. Only 405 triggers the fallback; every other status propagates untouched, and a failed GET retry is not cached so it re-probes rather than trusting an unproven fallback. request() now throws CoolifyApiError carrying the HTTP status, since the fallback needs to distinguish 405 from everything else and the message text alone could not. The message is unchanged, so anything matching on error.message is unaffected. Also from #292: PrivateKey.private_key, EnvironmentVariable.value and EnvVarSummary.value are now optional, because v4.2 (coollabsio/coolify#9893) withholds secrets unless the token has sensitive-read scope, and a required type made that arrive as a silent undefined. Create*Request types are unchanged, as request payloads are unaffected. 405 now carries an error hint explaining the method move, and the 401/403 hint mentions v4.2 Member-role tokens being read-only. Reported by @StreamlinedStartup with the call sites already identified. Closes #292
StuMason
added a commit
to StuMason/coolify-mcp
that referenced
this pull request
Jul 29, 2026
) * fix: Coolify v4.2 compatibility without breaking pre-4.2 instances Coolify v4.2 (coollabsio/coolify#10872) requires POST on state-changing endpoints and returns a hard 405 for GET. Six client call sites still sent GET: service start/stop/restart, deployByTagOrUuid, enableApi/disableApi, and validateServer (which passed no method, so it defaulted to GET). Checked upstream routes/api.php at v4.1.2, v4.0.0 and older betas to work out whether fixing this breaks anyone still on 4.1. It splits in two: - Service start/stop/restart and /deploy were already registered Route::match(['get','post']) well before v4.2, so they now send POST unconditionally. Application and database start/stop have been POSTing against 4.1 estates all along, which is the same route shape, so this is proven rather than assumed. - /enable, /disable and /servers/{uuid}/validate genuinely diverge: Route::get only up to v4.1.2, Route::post only from v4.2. Neither method works everywhere, so these send POST and retry once with GET on a 405, caching the resolved method per endpoint. The retry is safe because a 405 is raised by the router before the controller runs, so nothing executed and no state change can double-fire. Only 405 triggers the fallback; every other status propagates untouched, and a failed GET retry is not cached so it re-probes rather than trusting an unproven fallback. request() now throws CoolifyApiError carrying the HTTP status, since the fallback needs to distinguish 405 from everything else and the message text alone could not. The message is unchanged, so anything matching on error.message is unaffected. Also from #292: PrivateKey.private_key, EnvironmentVariable.value and EnvVarSummary.value are now optional, because v4.2 (coollabsio/coolify#9893) withholds secrets unless the token has sensitive-read scope, and a required type made that arrive as a silent undefined. Create*Request types are unchanged, as request payloads are unaffected. 405 now carries an error hint explaining the method move, and the 401/403 hint mentions v4.2 Member-role tokens being read-only. Reported by @StreamlinedStartup with the call sites already identified. Closes #292 * fix: self-heal the v4.2 method cache and tighten the fallback contract Addresses review feedback on #296. The remembered-GET path was terminal: once an endpoint was cached as legacy-GET, a Coolify instance upgraded to v4.2 mid-session would 405 on every subsequent call until the MCP server restarted. The cache now self-heals in both directions — a 405 from a remembered GET drops the stale preference and re-probes POST. A non-405 failure from the remembered GET still propagates without re-probing, so a genuine error never triggers a second state-changing request. The fallback key is now a closed union (LEGACY_GET_ENDPOINTS) instead of a bare string, so a future call site cannot silently reuse another endpoint's cache entry. Documented why the key is an endpoint identifier rather than the request path: version compatibility is a property of the instance, not the resource, so keying on the path would re-probe per uuid. The 405 hint no longer asserts the v4.2 GET-to-POST story for every 405. It led with that explanation regardless of endpoint, which would mislead anyone hitting a genuine 405 elsewhere. Also recorded three Coolify API gotchas in CLAUDE.md: the non-uniform v4.2 method split, v4.2 secret-hiding plus Member-role read-only, and the preview-twin env var hook (see #257) with the warning never to dedupe env vars by key alone. * docs: trim the 405 error hint Review feedback on #296: the hint led with an explanation of the client's own retry internals, which reads as noise to anyone hitting a 405 on an endpoint the fallback does not cover. Says what changed and what to check, without narrating the implementation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Team members with the Member role now have read-only access. They can continue to view team resources and configuration, but can no longer create, update, delete, deploy, start, stop, or otherwise modify resources. Review your team roles before upgrading and promote users who still require write access.
State-changing API endpoints now require POST. Legacy GET requests return
405 Method Not Allowed. Update API clients and deploy webhooks that use these endpoints:/enable/disable/deploy/servers/{uuid}/validate/applications/{uuid}/start/applications/{uuid}/restart/applications/{uuid}/stop/databases/{uuid}/start/databases/{uuid}/restart/databases/{uuid}/stop/services/{uuid}/start/services/{uuid}/restart/services/{uuid}/stop/services/{uuid}/applications/{app_uuid}/start/services/{uuid}/applications/{app_uuid}/restart/services/{uuid}/applications/{app_uuid}/stopWhat's Changed
Features
Fixes
force=falsekeeps the build cache (fix(deploy): cast force param as boolean to prevent cache bust on every deploy #9909)./github-apps/path and 404s #10573).Improvements
Breaking Changes
Issues fixed by this release
Fixes #5293
Fixes #6407
Fixes #6488
Fixes #6518
Fixes #6881
Fixes #7232
Fixes #7989
Fixes #8104
Fixes #9204
Fixes #9211
Fixes #9495
Fixes #9943
Fixes #9860
Fixes #10280
Fixes #10525
Fixes #10556
Fixes #10573
Fixes #10597
Fixes #10632
Fixes #10633
Fixes #10692
Fixes #10732
Fixes #10736
Fixes #10769
Fixes #10827
Fixes #10830
Fixes #10870