- Add an Axiom edge domain setting (default us-east-1) and use the /v1/ingest endpoint, so EU datasets work
- Remove the Highlight drain (service ended) and stop its running containers
- Update Fluent Bit from 2.0 to 5.1 and use the warn log level
- Restart running drains when the generated files change, with the new image pulled before the old container stops
- Show log drain validation errors under their fields
Closes#9898
Proxies started before v4.4.4 kept the old nginx config after an upgrade:
the upstream IP was resolved only once and IPv6 connections were reset.
- Label new proxies with a configuration version
- Status checks (Sentinel and SSH) recreate a running proxy with an
older or missing version once, at most every 10 minutes
- Remove the old proxy only after the image pull, so a failed pull
keeps it running
Closes#10198
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a "Use path-style URLs" setting to S3 storages. It is detected from
the endpoint (Alibaba OSS, Tencent COS, Volcengine/BytePlus TOS), and the
connection test switches to virtual-hosted style when the provider
rejects path-style requests. Backups pass `--path off` to mc.
Closes#10347
- The restart limit claim sent only one stop. If that stop failed or came
too late, the container kept restarting past the max restart count.
- Sentinel pushes and status checks now dispatch the stop again while a
container still runs; the notification is still sent once.
Closes#10761
The compose parser queued ServerFilesFromServerJob for every volume on
each parse, and pages that only show data parse the Compose file. Each
sync also sent two SSH commands for each file.
- Queue the sync only for a compose deployment, and for each service
resource with file storages when the service starts or deploys.
- Read the compose service names without a parse on the Domains and
scheduled task pages.
- Check all file storages with one remote command, and stop when a
symbolic link, a special file, or an unknown state is at a file path.
- Keep the application path in a file storage when a pull request
preview is parsed. Preview deployments of the current parser write
their `-pr-<id>` copies through LocalFileVolume::forPullRequest().
- Remove the unreachable file sync from the service resource page.
Sending SSH command batches on stdin changes how every remote command
reaches a server, which is too risky for a patch release. Move it to
next and restore the heredoc transport from before 1a2a5362a. The
shared test helpers stay because they work with both transports.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bitbucket Cloud has no pull request refs over git, so a redeploy without
a webhook commit checked out the base branch. Reuse the latest known
commit of the pull request, or fail the deployment when none is known.
Closes#10806
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Compose deployments label each built image with a fingerprint of the build
settings and the resolved build-time variables. A deploy or restart reuses the
commit images when every label matches, so a runtime-only change does not
rebuild.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Docker ignores secret values for the build cache, so the
COOLIFY_BUILD_SECRETS_HASH secret mount never invalidated it. Pass the
hash as a build arg and declare it in each stage instead.
Parse Dockerfile instructions so ARG lines and secret mounts are not
added inside heredoc bodies or continuation lines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The UI service clone iterated relation builders before parse() created
the sub-resources, so no volume copy ever ran. All service clone paths
now use clone_service(), which parses first and matches volumes by
mount path. VolumeCloneJob no longer forces chown 1000:1000.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A user database named coolify-db was backed up as the instance database,
which targeted the wrong container. It was also hidden from the server
database list and from status updates.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Refresh the navbar proxy status on the 30 s poll
- Skip Sentinel and server check auto-start while a proxy start or restart runs
- Use the StartProxy commands in RestartProxyJob, so Caddy restarts keep the
maintenance blocks and remove the Traefik logrotate sidecar
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Traefik and Caddy routes of applications now retry a failed connection
on another container, and the rolling update waits a configurable drain
time (default 5 seconds) after the new container is healthy before it
stops the old containers. The wait is skipped when no old container runs
or when the proxy labels changed, because the proxy drops a route that
two containers define differently.
Fixes#8627
When "docker version --format json" did not return clean JSON (for
example, text from a shell startup file), validation stored 0.0.0 and
said that Docker was older than version 24. Validation now stores no
version and tells the user to run the command on the server. When the
version is too old, the message shows the detected version.
Closes#11089
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The legacy configuration hash encoded serialized environment variable rows,
so hashes from older versions never matched after an upgrade, and the
fallback compared the configuration with an empty one. Apps without a
deployment snapshot now report no pending changes, and their next
deployment rebuilds the image.
Closes#11101
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Laravel runs failed() on a fresh copy of the job, so the in-memory
newVersionIsHealthy flag was always false there and a failure after the
old container stopped removed the only running container. Keep the flag
in the cache, keyed by the deployment UUID.
Closes#12253
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pg_dump ran with --no-acl --no-owner, so single-database backups lost
all GRANTs and a restored Supabase database did not work. The import
already skips owners and privileges unless "Keep owners and privileges"
is selected, so the backup now keeps them.
Closes#12244
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Import:
- Check every uuid in a bundle against a strict id format before any
write, and quote the SSH mux socket and key paths in local shell
commands. A bundle uuid could run commands in the Coolify container.
- Validate bundle fqdns, git source URLs, paths, networks, cron
expressions, and database ports; cap the number of items.
- Do not confirm that another team has a uuid.
- Refuse a project icon path with a uuid that is not a plain id.
Claim, finish, and migrate:
- Pass checklist step keys to wire:click with Js::from (stored XSS).
- Link only to https target server URLs.
- Validate target_instance_url in /transfer/complete; never prefill an
unverified URL for a transfer back; scope the transfer-back token to
write+deploy for 1 hour.
- Release on an owner marker only when it is newer than the own claim.
- Do not touch apps that only use the server as an additional
destination when an archive is released or deleted.
- Give Sentinel a new token on claim.
- Add a checklist step to remove the previous instance's SSH key.
- Block a transfer while backups or scheduled tasks run.
- Authorize refreshMigration and PrivateKey checkConnection, clear
tokens from Livewire state, hide migration log/error from members.
Archives:
- Refuse ip, user, port, private key, and Cloudflare tunnel changes.
- Throttle Enable management and require a free server slot for it and
for a transfer back.
- Skip cloud provider calls.
- Re-read force_disabled before each SSH command, so running jobs stop.
- Probe the import check target at the resolved address only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Rate limit the import check probe and refuse private, loopback, and
link-local targets on Cloud.
- Rate limit the SSH validation that an import starts, like other
server validations.
- Count only managed servers for the server limit, the limit check job,
and the subscription page. Archives of transferred servers are left out.
- Do not show the name of another team's archived server in the import check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Skip TrimStrings and ConvertEmptyStringsToNull on the import route; an empty shared variable failed the whole import
- Keep compose parser versions, static ports, legacy variable keys, and only the bundle's variables and destinations
- Give the transfer back token the deploy permission that the import needs
- Move the Cloudflare tunnel DNS record with the server and park it on the source
- Refuse cloud server deletes, power on, tunnel and DNS changes, and scp for archives; skip their backup alerts and provider polling
- Add a column-level round-trip test, archive guard tests, and a live full-coverage transfer test
- Advance the GitLab App sequence in the dev seeder
- Retry CDN requests only for transient errors and honor Retry-After
(Cloudflare error 1200 sends 60 s), with jitter.
- Read helper and Sentinel versions from the local versions.json, which
the hourly update check refreshes, instead of fetching per job/server.
- Replace the random 0-600 s delay with a stable per-instance offset
inside the cron interval (max 1 h).
- Manual update checks and upgrades make one CDN attempt only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>