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.
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.
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>
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
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>
- Build a valid compose device request (device_ids list, options mapping, blank driver)
- Map --gpus N to count and drop --gpus when GPU settings are enabled
- Validate only changed GPU values so stored legacy values keep working
- Detect NVIDIA GPUs and the container toolkit with the server details
- Show detected GPUs with a refresh button in the application GPU section
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rollback now also lists the commit images of the last 10 successful
deployments when the application pushes to a Docker registry. The
deployment pulls such an image when the server no longer has it.
The page and the API share GetRollbackImages, and the API returns a
source field (local or registry).
Skip the pre-stop pull when a custom build command runs without a build server, and pull only services whose image does not come from a build, including services that reuse the image of a build service.
Closes#11773
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Retry the installation token request on GitHub 5xx and connection errors,
and report the HTTP status when GitHub sends no error message. Retry the
repository import when SSH drops the connection (exit code 255), after
stopping the interrupted clone and removing the partial checkout.
Closes#8004
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Fetch every page of pull request files so watch paths match PRs with more than 30 files.
- Deploy the preview and log a warning when the changed-file list is unknown (API error or truncated compare list).
- Log when watch paths decline a preview deployment.
- Keep the GitHub App installation token in memory per instance, so a deployment requests one token instead of 3-5.
Closes#12169
Use the helper's RAILPACK_VERSION, falling back to the installed CLI
version, instead of a hardcoded frontend version. Add regression tests
for both version sources and application-variable isolation.
Store server IPs in one form (no brackets, short lower-case IPv6) and
write each address in the form its context needs:
- URLs and host:port (Sentinel, database URLs, SFTP backup download,
DNS servers, SMTP, webhook base URLs, links, health checks) get
brackets through formatHostForUrl().
- Traefik Host() rules use the address without brackets, so IPv6
domains no longer return 404; saved labels are fixed at deploy.
Caddy keeps the brackets.
- SSH keeps the plain address.
- Hetzner gives an IPv6 /64 network; IPv6-only servers now get the
server address (prefix::1) instead of the unusable prefix::64.
- sslip labels, registry image names with an IPv6 host, the API domain
list, allowlist matching and duplicate checks handle IPv6.
A migration normalizes stored IPv6 server addresses, repairs Hetzner
servers saved as ::64 that are not reachable, and adds brackets to
saved Sentinel URLs.
The commit message was read only during the repository clone. Deployments
that skipped the build or failed before the clone showed only the commit
hash. They now reuse the message stored by an earlier deployment of the
same application and commit.
Closes#12116
Pull request deployments sent every non-railpack build pack to build_image(),
which no longer handles the static build pack since it was moved to
build_static_image(). Static preview deployments then failed with
"open Dockerfile: no such file or directory".
Closes#8238