Webhook secrets are stored settings, so a token with the write ability can
set or change them, the same as GitHub App and GitLab App webhook secrets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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
Cloning a clone added another "-clone-<id>" to the name, so after about
seven clones the name was longer than 255 characters and the insert failed.
Closes#9976
The log endpoints found containers with `docker ps -a`, then rejected
every container that was not running. Remove that check, so failed
deployments can be diagnosed through the API. Without service_name,
the application endpoint prefers a running container. The old error
stays when no container exists.
Closes#9972
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The analytics page fetched each server's dashboard bundle over SSH one
after another, so the skeleton stayed until every server answered. Start
all fetches at the same time and remember failures, so the page waits
only for the slowest server.
Closes#12347
Provider errors now return 502 with a safe message, the provider status, and
the provider error code instead of a bare 500. Hetzner no longer sends a create
request again after a 5xx, and a VPS that Coolify did not save is deleted.
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 deploy key flow saved the base directory only for Docker Compose.
All repository flows now validate the base directory, and the GitLab
and Gitea flows reject destinations on servers that cannot deploy.
Closes#10319
Install, build, and start commands saved before they were validated
blocked every save of the General tab, and the fields are hidden for
build packs other than Nixpacks and Railpack, so users could not fix
them. Validate these commands only when they change; deployments pass
them to the builder as one escaped argument.
Closes#10055
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Laravel app on a sibling subdomain with SESSION_DOMAIN=.example.com sets
a second XSRF-TOKEN cookie that the browser also sends to Coolify. The
terminal server forwarded only the first one, so Laravel answered 419 and
the terminal closed with 4401. Try each distinct token (at most five) and
keep the accepted one for the requests that follow on the connection.
Closes#10397
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The terminal server built the Laravel session cookie name from APP_NAME
with its own regex and ignored SESSION_COOKIE. When the name differed
from Laravel's, every connection closed with "Missing required tokens".
Forward the browser Cookie header so Laravel reads its own session.
Also remove the text rejection messages kept for terminal clients from
before close codes; the server and client now ship in the same image.
Closes#10549
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a Database schema and use it for GET /databases and
GET /databases/{uuid}, type the GET /resources items, and stop
requiring both environment_name and environment_uuid on create
endpoints. KeyDB now returns database_type like the other engines.
Closes#10449
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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
Only revoke a member's team tokens when the role goes down. Promotions
and ownership transfers on account deletion keep the tokens.
Closes#12342
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
The dialog checkboxes used both Alpine selectedActions and wire:model.
After the dialog closed, the two could differ, so a click did not change
the checkbox. Alpine now holds the state, and the dialog sends it to
Livewire on submit.
Closes#12338
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The searchResources() x-data wrapper was outside the type-step @if that
renders its script, so a direct load of a later step (for example the
PostgreSQL image picker from global search or a reload) threw
"searchResources is not defined".
Closes#12337
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>
Replace the inactive Soketi profile with a zero-replica placeholder so Compose
removes old coolify-realtime containers. Update packaging tests to verify the
merged service configuration.
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>
Open root registration for ten minutes after startup, then require a Coolify restart to reopen it. Update installer credential handling and explain the setup window in the registration UI.