mc keeps one --resolve IP per host, and Coolify always pinned the IPv4
address of a dual-stack endpoint. On servers without IPv4, uploads failed
with "network is unreachable". A helper container on the upload network
now connects to each validated IP, IPv4 first, and the first IP that
connects is pinned. S3 restores are now pinned in the same way.
Closes#12397
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Once Coolify is healthy, install.sh switches the instance to that update channel with php artisan app:update-channel
- The command and the update page share the rule that keeps the updates of the old channel after a switch to a more stable one
- Every channel has a block of its own, every version after this one reads only these blocks
- Every stable sync also fills the coolify and traefik keys older instances read
- An instance keeps a copy of versions.json and reads upstream.json of the image until it has one
- Removes coolify-testing-host.yml too, it published the testing host to Docker Hub for docker-compose.windows.yml alone, the development setup builds it locally
- Adds the channels stable, preview, nightly and custom
- Preview and nightly read /coolify/release.json on the CDN and take the newest version of their channel and the more stable ones, nightly gets a new build of next or the release branch twice a day
- Custom installs any image tag of ghcr.io by hand, such as pr-1234 for the build of pull request 1234
- After a switch to a more stable channel, the instance keeps the updates of the channel it left until the stable release of its version is out
- The local versions.json moves to storage/app and is replaced in one step, a channel change replaces it without the version of the old channel
- Docker Compose builds the development helper from the main branch of that repository, scripts/dev-helper from there or from a local checkout
- Remove buildHelperImage from the settings, nothing calls it since its button was removed
- The upgrade script removes COOLIFY_VERSION from .env, so a tag such as nightly or pr-1234 is never taken for the version
- install.sh still takes a version such as 4.6.0-beta.1, LATEST_IMAGE in .env picks the image and the image carries its version
- Remove other/nightly, the nightly channel uses the production files, so there are no longer two copies to keep in sync
- sync-cdn.sh --nightly syncs the files of the commit the nightly is built from to /coolify/nightly on the CDN, with the nightly version in its versions.json and in /coolify/release.json, and pushes them straight to main of coollabs-cdn
- version.sh picks the branch the nightly comes from, the release branch of the next version after the newest stable one or next, and names the version <preview>.<YYYYMMDD>.<N>
- The image is labeled with its version and commit, the nightly workflow reads both from the image nightly points at to count up N and to skip a run without a new commit
- config/constants.php reads the Coolify and helper versions from them
- The image and sync-cdn.sh write versions.json from upstream.json, install.sh reads it by key
phpdotenv trims whitespace around an unquoted value, including the \r of
CRLF line endings. The repair quoted such values, which broke valid lines in
CRLF files and kept spaces that phpdotenv drops. Trim the value first and
quote it only when a space is still inside it.
Closes#12375
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Installers before 4.5.1 and manual edits could leave ROOT_USERNAME (or the
root email or password) with spaces and no quotes. The running container
ignores .env because its config is cached, so the next upgrade recreated it
and phpdotenv failed, which made every page return HTTP 500. The upgrade now
quotes these values before it restarts Coolify.
Closes#12375
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Public pull request previews no longer get production values, and no
preview falls back to production variables. Existing previews were
deployed with these values; for example, their databases were
initialized with the production password, so they broke on redeploy.
Previews that exist at the upgrade get keeps_production_values and
keep the earlier behavior. Previews created later do not. Server
transfer moves the flag.
- 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
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
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 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.
The server Metrics page now uses SentinelMetricsClient::rootMountName():
/, else /app/db (Sentinel 1.1.2 and older), else /data/coolify or /data
(Sentinel 1.1.3 and newer). Before, it kept only /, so the disk chart was
empty when Sentinel did not report a / mount.
Send bucket_ms on the Sentinel metric history reads so Sentinel averages
the rows and sends far fewer of them over SSH. Older Sentinels ignore the
param and return raw rows, which Coolify still buckets and downsamples.
Also quote the history URL in the single-fetch curl command, because the
URL now has an & in it.