Replace the container accordion with Deployment and Service selectors
that show one stream, merging replica containers by timestamp. The
viewer fills the page, opens in text view, keeps whitespace, and only
lets grid rows expand when the detail shows more than the row.
Based on the proposal in discussion #12176 by PhilippMolitor.
Add a /dashboard/canvas page that renders every team server with its
resources and their running or queued deployments, backed by a new
ServerCanvasController::dashboard endpoint and a per-server usage
endpoint for zone headers. The dashboard remembers the list/canvas
choice and each section (projects, servers) its own table/grid view.
- Show Deploying/Queued pills on canvas cards and a foldable recent
deployments panel; add shared CanvasControls component
- Allow backup downloads from the server host via the S3 download
storage (PrepareFileDownloadJob accepts a null container)
- Extract backup toggle/run actions into ManagesDatabaseBackup and
surface them in backup execution headers; merge S3 and retention
sections into the general backup settings
- Move deployments indicator to the top bar and add a main nav
resource menu with submenus; simplify breadcrumbs and settings
layouts
- Add shared variables overview canvas and scheduled task modals
- Add feature tests for dashboard canvas, view modes, navbar
submenus, backup S3 downloads and scheduled task modals
- Runtime logs: add a compact text view, move display options and log level filters into a View menu, move copy and download into an Export menu, and remove the extra top margin.
- Replace spinner loading cards with skeletons on the logs, dynamic configurations, proxy, TLS certificates, Docker images, environment variables, preview deployments, rollback, subscription, cloud provider, and new resource pages.
Malformed JSON in the coolify-log-filters localStorage key threw during
runtime log viewer startup. Read the saved value safely and keep only
boolean values for known levels.
Fixes#12101
The container picker read its options from an Alpine x-data snapshot taken
on the first render, before wire:init loaded the containers. Livewire keeps
the Alpine state when it morphs, so resources with multiple containers
showed an empty picker. Publish the options as a Livewire property and
entangle them in Alpine.
Closes#12110
- refreshEnvs is now sent only to the environment variable list, and
rows no longer listen to it, so adding or removing variables cannot
queue an update for a removed row ("Snapshot missing"). Locking a row
refreshes that row directly; the compose editor gets its own event.
- saveCustomName() no longer saves a custom container name that another
application on the server already uses; it restores the stored value.
- Cancelling a GitHub runner uses the Coolify confirmation modal instead
of a native browser dialog.
Drop the OAuth confirm/callback flow that let users confirm destructive
actions by re-authenticating through a linked provider. This removes the
confirm route and session handling in OauthController, the middleware
bypass for those routes, OauthSetting::providerName(),
User::oauthConfirmationProviders(),
OauthLoginService::identityBelongsToUser() and the
socialite_reauthentication_parameters() helper.
Users with a linked OAuth identity no longer need a password step and
only use the dialog's typed confirmation. Password confirmation is now
required only for users who have a password and no SSO identity. The
confirmation modal and tests are updated to match.
- database import: add keep_owners (restore PostgreSQL owners and
privileges) and sqlite_database (pick the target SQLite file) to the
API, OpenAPI spec, and import form
- oauth: require password confirmation and support team selection on
OAuth login
- remote process: send team broadcast events to the team of the server
that ran the process instead of the causer's user id
- servers API: handle the legacy build server setting
- compose: support parent bind paths and volume driver options
- dns: improve record hints and provider management
- notifications: fix throttling and missing backup notifications
- ui: rework the confirmation modal
- add feature and unit tests for the new behavior
- Delete Blade components, component classes, Livewire components and
views that nothing uses after the redesign.
- Delete tests that only compare Blade/CSS source text; keep the source
checks for authorization gates, stable wire:key values and escaping.
- Update stale tests to the current UI and behaviour.
- Update DESIGN.md to the current navigation and layout.
- Add a lesson: test behaviour, not source markup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the terminal started automatically, the session timeout started
only after a token arrived. If the server returned no token (container
not running, no shell, access denied, terminal disabled), the spinner
stayed on "connecting…" until the page was reloaded.
- Every early return now sends terminal-session-failed with a short
message; denied and unknown servers get the same text.
- Auto-start starts the session timeout in init(), so a missing token
always ends in a visible error with "Reload page".
- With more than one container, auto-start is cancelled, so the
container picker shows no false timeout error.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Traffic analytics:
- Reject enabling unless the server runs a Coolify-managed Traefik or
Caddy proxy, and show the reason in the settings UI
- Save the proxy configuration before the setting so a failure leaves
both unchanged; allow disabling after the proxy was removed
- Skip the proxy restart when the proxy is stopped and report that the
config applies on next start
- Preserve the user's own Traefik --accesslog* flags and restore them
when analytics is disabled
- Rotate the Traefik access log in the sidecar with BusyBox tools
(copytruncate, 5 gzip rotations)
- Create the access log before starting Sentinel, which opens it once
Terminal:
- Detect and surface WebSocket connection rejections in the browser
terminal, with shared helpers in terminal-connection.js and
terminal-utils.js
Database import:
- Restore PostgreSQL backups in a single transaction; SQL replace
restores go into a temporary database and swap in only on success,
leaving the current database untouched on failure
Give the traffic analytics prompt a stable Livewire key and label the server link “Set up on”. Add a browser test for the link and persistent dismissal.
The available tags list now sends only the tag id to the Livewire
action. The component resolves the tag from the current team, so
tag names with special characters, such as apostrophes, work.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add indexing, redirect, and hostname regeneration controls to domain editors. Queue DNS checks only for scheme or hostname changes and show progress consistently across application, service, and preview domains.
Replace the collapsible mobile configuration menu with an always-visible
responsive grid, stack the mobile heading, and swap the domain editor
unsaved bar for a sticky Save footer with a scrollable form body.
Show routing summaries on domain tables below 600px instead of squeezing desktop columns. Scope preview add/edit Livewire events by preview id, authorize preview domain actions, and add search plus unsaved-edit handling.