Commit Graph
17705 Commits
Author SHA1 Message Date
Andras Bacsai d28bc91ff5 fix(scheduler): read fresh server state in each job and log scheduling decisions
Horizon workers kept Server::findCached() results between jobs, so scheduled
database backups used stale reachability and subscription state. A backup that
was skipped with the stale state counted as done for that day. Flush the
Server identity map before each queue job.

Add debug logs for the full path of a scheduled run, so a multi-node cloud
instance shows where a run is lost:
- manager start delay, gap since the previous start, host, pid, memory, and
  a warning when the start is later than the catch-up window
- skip logs with the server state that was used and the current database state
- occurrence enqueued, claimed, rejected, completed and failed, with host and
  the delay since the due time; a warning when the previous run is still open
- count of occurrences still open after 15 minutes on each manager run
- database backup runs that end without a backup
- server connection state changes with the checking node and the SSH error

Also keep publishing pending occurrences when one of them fails.
2026-09-28 16:15:00 +02:00
Andras BacsaiandClaude Opus 5.5 86402ef926 fix(ui): clean up the server rows of multi-server applications
- Show the status summary next to the server name on the primary and additional server rows.
- Move Deploy, Make primary, Stop and Remove into one Actions dropdown per server row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:39:00 +02:00
Andras BacsaiandClaude Opus 5.5 7bd8baa7f0 fix(multi-server): make applications on several servers consistent
- Stop the application on every server, also when one server is not functional.
- Write file mounts on every server of the application, not only on the main server.
- Deploy the exact commit, rollback flag and image tag of the main deployment to the
  additional servers, so a rollback reverts all servers.
- Pull the pushed image on additional servers for inline Dockerfile applications
  instead of building it again on each server.
- Fail multi-server deployments without a Docker image name, also from webhooks and the API.
- Send one deployment notification after all servers finish (parent_deployment_uuid).
- Block persistent volumes on multi-server applications (API, Livewire, SQLite connect)
  and warn in the deployment log for existing applications that have both.
- Remove dead code in push_to_docker_registry().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:38:57 +02:00
Andras BacsaiandClaude Opus 5.5 1f0e2f74d0 fix(ui): replace native browser dialogs with confirmation modals
Use the Coolify confirmation modal instead of wire:confirm for server
management, server transfer and import, resource migration, and S3
backup disabling. Show a toast instead of alert() for a missing GitHub
App webhook endpoint. Add a test that blocks native dialogs in views.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:37:20 +02:00
Andras BacsaiandClaude Opus 5.5 15909fa641 feat(server): move management toggle to connection header and show connection first
Replace the dev-only management ownership section with an Enable/Disable
management button in the Connection section header, and place the
Connection section above the Server overview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:56:42 +02:00
Andras Bacsai 2e67b70eec Merge remote-tracking branch 'origin/main' 2026-09-28 14:29:56 +02:00
Andras BacsaiandClaude Opus 5.5 f008e0593b fix(server): hide server IP addresses on the servers list
The dashboard redesign added an IP address column to the servers list
and put each server IP into the Alpine data, so the IP showed in the
page source. Remove the column and the value, and render the component
in the test instead of matching template strings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:28:01 +02:00
Andras Bacsai 1e5cc98ef7 feat(server): add Docker images page with per-image delete (#11689)
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
2026-09-28 14:25:41 +02:00
Andras Bacsai 0fec411b72 feat(server): confirm Docker image deletion with a typed reference modal
Replace the browser confirm on the Delete button with a two-step
confirmation modal. To delete, users now type the image reference.
The modal is shown only to users who can update the server. delete()
now accepts an optional password argument so it works with the modal's
submit action.
2026-09-28 14:21:17 +02:00
badnikhil 2e2d1d321c feat(server): add Docker images page with per-image delete
Adds an Images entry to the server sidebar that lists the Docker images
stored on that server: repository, tag, image ID, age, size and the
containers using each one. Images no container references are labelled
Unused and can be deleted individually; Docker's own reported total and
reclaimable size are shown above the table.
2026-09-28 14:21:17 +02:00
Andras BacsaiandClaude Opus 5.5 81af5892d7 test(api): cover the team update audit event
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:06:14 +02:00
Andras BacsaiandClaude Opus 5.5 7c21c330c9 fix(gitlab): check the private key before using it for git commands
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 14:06:14 +02:00
Andras BacsaiandClaude Opus 5.5 739d9e9d23 fix(permissions): show logs and task output only to admins and read:sensitive tokens
Container logs and scheduled-task commands and output are now shown only to
users who can edit the resource. The API returns them only to tokens with
the read:sensitive or root ability, the same as the MCP tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:20:59 +02:00
Andras BacsaiandClaude Opus 5.5 1ecd927ca3 fix(api): return the saved proxy configuration only with read:sensitive
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 13:10:25 +02:00
Andras BacsaiandClaude Opus 5.5 5ab6e1b245 fix(storage): show file mount content only to users who can edit the resource
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:53:39 +02:00
Andras BacsaiandClaude Opus 5.5 c6fd0a0b0d fix(shared-variables): show server variable values only to admins
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:40:16 +02:00
Andras BacsaiandClaude Opus 5.5 1e910394fd fix(compose): show compose content only to users who can edit the resource
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:30:47 +02:00
Andras Bacsai 4ab0e89e24 feat(server): add dev-only toggle for server management ownership
Add a Management ownership switch to the server page, shown only in
development, that lets a user with update permission release or claim
control of a server from this Coolify instance. Claiming is blocked for
localhost and when the team is over its server limit. Both actions are
recorded in the audit log.

When ServerTransferClaimer claims a server, it now clears force_disabled
if the team is within its server limit, and it always saves settings,
not only when the sentinel is rebound.
2026-09-28 12:14:56 +02:00
Andras BacsaiandClaude Opus 5.5 350d8a6571 fix(databases): refresh database form values consistently
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:07:02 +02:00
Andras BacsaiandClaude Opus 5.5 0448c6ca51 refactor(http): remove the TrustHosts middleware that never checked the host
TrustHosts skipped its check while the cache key instance_settings_fqdn_host
was empty, and only the skipped check filled that key. So since e1fe58639
(October 2025) no release restricted the Host header. Turning it on now would
lock out users who reach Coolify by server IP or another name when the domain
or proxy is broken.

Links in emails and notifications do not use the Host header: base_url()
uses the configured FQDN or the server IP (see ResetPasswordUrlTest). So
remove the middleware, its cache key and its tests. TrustProxies is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 12:00:16 +02:00
Andras Bacsai 1f4006ac49 test: remove tests that do not exercise app code
Remove tests that copy app logic into the test, grep PHP source as
text, only check literals, constants, class_exists or PHP built-ins,
duplicate other tests, or are always skipped. Keep source checks that
guard security and authorization rules.

Rename a duplicate Pest helper so the full suite loads, drop the
missing v5/Browser path, and remove the CLAUDE.md symlink in favor of
AGENTS.md. Correct AGENTS.md: Dusk is not installed and the upgrade
script is scripts/upgrade.sh.
2026-09-28 11:55:56 +02:00
Andras BacsaiandClaude Opus 5.5 59788c59f0 fix(storage): refresh storage form values consistently
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:51:53 +02:00
Andras BacsaiandClaude Opus 5.5 dd7ad91ba2 fix(cleanup): delete old rows in batches and report the real count
cleanup:database used orderBy()->skip(10)->delete(). Laravel drops the offset
in a DELETE, so it deleted all old rows anyway, and the count query with the
offset printed 0 on PostgreSQL. Count without the offset, delete in batches of
1000 rows so a large table is not locked by one long DELETE, and write the
output through the command so it is captured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:50:32 +02:00
Andras BacsaiandClaude Opus 5.5 4145261b6e fix(api): validate delete_from_provider before deleting a server
Reject delete_from_provider values that are not booleans, and reject the
request when the team has no token for a linked cloud provider. Before,
both cases removed the server from Coolify but kept the cloud VM running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:42:48 +02:00
Andras BacsaiandClaude Opus 5.5 f885e1eeeb fix(deployments): do not print build-time values in development debug lines
With APP_ENV=local the deployment log showed every build-time value (raw,
stripped and escaped) and the old and new value of overrides. Print only the
key, the type and the value length.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:42:03 +02:00
Andras BacsaiandClaude Opus 5.5 f540c49f68 fix(security): encrypt stored remote commands and remove them after the final attempt
remote_process() stored the full shell command as plain text in
activity_log and kept it for 60 days. Database starts store the compose file
with the database passwords, imports store S3 keys, and the Cloudflare
tunnel setup stores its token.

- Store the command encrypted. The queue worker decrypts it right before the
  SSH call and still reads plain commands of tasks queued before the upgrade.
- Remove the command when the task is finished: after a successful run, in
  failed() when no attempt is left, and for a stopped import. A failed attempt
  that the queue retries keeps it.
- Do not write a command preview into the error log.
- Migration: remove stored commands from activities that no longer run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:41:56 +02:00
Andras Bacsai aa61214233 feat(api): add delete_from_provider option to server delete endpoint (#12026) 2026-09-28 11:38:31 +02:00
Andras BacsaiandClaude Opus 5.5 f8b320ab40 fix(servers): validate the selected private key when adding a server
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:35:46 +02:00
Andras BacsaiandClaude Opus 5.5 6c3249d324 fix(logs): track the All lines state locally and show loading in the lines control
The All button read $wire.numberOfLines, which does not update while the user
types or pastes a new number, so All stayed highlighted. Keep the state in
Alpine instead: All loads set it, and any input in the number field clears it
unless the value is -1.

Show a spinner in the All button while all logs load, and in place of the
Lines label while a new line count loads. Both keep their width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:18:57 +02:00
Andras BacsaiandClaude Opus 5.5 eed50d6781 fix(github): check the private key before generating app tokens
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:18:29 +02:00
Andras BacsaiandClaude Opus 5.5 af19bd0a50 fix(sources): validate the selected private key on source settings
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:12:48 +02:00
Andras BacsaiandClaude Opus 5.5 1f7a011767 docs(ai): add lessons for browser test output and shared storage
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:09:13 +02:00
Andras BacsaiandClaude Opus 5.5 986e93445e test: remove production seeder test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:09:13 +02:00
Andras BacsaiandClaude Opus 5.5 e778d99e9d feat(logs): render runtime logs in a virtualized list
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:09:13 +02:00
Andras BacsaiandClaude Opus 5.5 d59bcf5ae3 fix(logs): show container lookup errors and reload containers after status checks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:09:13 +02:00
Andras BacsaiandClaude Opus 5.5 e62658467f feat(ui): add app icons and web manifest
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:09:13 +02:00
Andras BacsaiandClaude Opus 5.5 1712fb393a fix(transfer): reuse or create the private key in the target team only
The import looked up the key in all teams and stopped with "already exists
on another team", which also told the user that another team has the key.
Keys are unique per team, so reuse a key of the target team or create one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:02:19 +02:00
Andras BacsaiandClaude Opus 5.5 df9f1555b3 fix(auth): keep the current team only in the session
Login, registration and OAuth set a currentTeam attribute on the user model
that is not a database column, so a save of the user in the same request
would fail. Keep the team in the session and read it with currentTeam().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 11:02:19 +02:00
Andras BacsaiandClaude Opus 5.5 f09de9c359 feat(ui): link healthcheck status row to the healthcheck page
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:47:01 +02:00
Andras Bacsai e2f75393e5 test: clarify onboarding coverage 2026-09-28 10:46:44 +02:00
Andras BacsaiandClaude Opus 5.5 16ccc929b6 chore(deps): update league/commonmark to 2.10.3
Fixes the denial of service advisory GHSA-8rr7-cvq3-gmfh (affected
versions >=1.5.0,<2.10.0). nette/schema moves to 1.3.6 with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:36:25 +02:00
Andras BacsaiandClaude Opus 5.5 a70f882f7b fix(dev): show the Lima VM start command on the localhost server page
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:29:01 +02:00
Andras BacsaiandClaude Opus 5.5 714b09fa24 fix(ssh): never disable the SSH command timeout
SSH_COMMAND_TIMEOUT=0 (or an invalid value) removed the time limit of every
remote command, and imports could then be marked stale while still running.
Use the default of 3600 seconds for values that are not positive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:29:01 +02:00
Andras BacsaiandClaude Opus 5.5 575a97b6b7 chore(deps): update resend-laravel to 1.5 (resend-php 1.16)
resend-php 1.x reads the statusCode of Resend errors and knows more error
names. Coolify only uses emails->send and the exception classes, which did
not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:29:01 +02:00
Andras Bacsai 6656ab5ea6 fix: keep existing SSH keys out of onboarding state 2026-09-28 10:22:44 +02:00
Andras BacsaiandClaude Opus 5.5 7e4fbc3499 fix(service): show the selected resource status in the service heading
A merge (9ef1ab764) lost the resource-aware status from #11566.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00
Andras BacsaiandClaude Opus 5.5 9c6a8e4767 fix(profile): close the email change modal after verification
A merge (253e59e73) lost the close-email-change-modal dispatch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00
Andras BacsaiandClaude Opus 5.5 75976d9882 fix(keys): check duplicate private keys in the key's own team
The duplicate check used the signed-in user's current team, or all teams
when there was none. Check the team the key belongs to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00
Andras BacsaiandClaude Opus 5.5 e755f4c9e0 fix(webhooks): always verify manual webhook signatures
GitHub, Gitea and Bitbucket manual webhooks accepted any signature when
APP_ENV=local. GitLab and the GitHub App webhook already did not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00
Andras BacsaiandClaude Opus 5.5 9c7f2dc412 fix(templates): keep local service templates when the CDN bundle is unusable
A 200 response with an empty body or an error page replaced the local
templates and the shared cache, so the service list became empty.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 10:13:20 +02:00