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
- Applications: is_container_label_readonly_enabled (turning it back on
regenerates labels), include_coolify_default_variables, and
dockerfile_target_build on create.
- Databases: save is_log_drain_enabled on update instead of dropping it,
include_coolify_default_variables, and disable_local_backup on backups
(only with save_s3).
- Services: include_coolify_default_variables, and redirect on service
applications (www/non-www needs both hosts).
- Servers: wildcard_domain, server_timezone,
backup_compression_cpu_percentage, and the proxy error page.
Closes#11092
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).
Resolve conflicts between main's security fixes and v4.5 features:
- Keep v4.5 features (log redaction, multi-S3 backups, transfer flow,
scheduled task modal, sidebar) and port main's fixes into them.
- Reuse RequiresDeployAbility for the Hostinger create endpoint.
- Align MCP tool abilities and descriptions with main's new deploy
requirements, and use deploy tokens in the affected MCP tests.
- Drop the duplicate DockerCleanupJobTest helper and tests, and the
exportBundle test for a method v4.5 removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Require deploy permission for API changes that trigger server side effects, including resource deletion, storage access, provider operations, and database imports. Also escape Docker cleanup filters and sanitize log drain server names.
The repository URL rule rejected ssh://user@host:port/path, so deploy-key
resources on servers with a custom SSH port needed a manual URL edit after
creation. Accept ssh:// URLs and keep them unchanged for deploy keys so the
port reaches the clone. Rename scpStyleGitUrlToHttps to sshGitUrlToHttps and
let it convert ssh:// URLs too, so public flows, repository links and GitHub
App repository slugs handle them.
Closes#12161
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Applications and service applications can now use the server resolver,
no resolver ("none"), or a custom resolver name. This allows servers
that mix Let's Encrypt domains with domains that use their own
certificates, such as Cloudflare Origin CA. The setting is available in
the UI and the API.
Closes#12138
- Stop the Redis username accessor from creating REDIS_USERNAME on read
- Keep source values when cloning applications (no duplicate NIXPACKS_NODE_VERSION)
- Match exact keys when adding default database environment variables
- Write content files before database containers start
- Resolve the database proxy upstream through Docker DNS on each connection
- Remove existing duplicate REDIS_USERNAME and NIXPACKS_NODE_VERSION rows
Sentry self-hosted (getsentry/self-hosted 26.8.0) could not be deployed
as a Docker Compose application. Three separate problems blocked it:
- YAML collection aliases: the first fix raised the limit to 256 only in
Application::oldRawParser(). The safety check added in v4.4.0
(validateDockerComposeForInjection) and all other Compose parse calls
still used the Symfony default of 128, so the Sentry file (133 aliases)
failed with "Maximum number of collection aliases (128) exceeded".
Add parseDockerComposeYaml() and use it for every Compose parse.
- Argument list too long: the deployment job sent the generated Compose
file as base64 inside the SSH command. Linux limits one argument to
128 KiB, and the Sentry file is about 370 KB. execute_remote_command()
now accepts an 'input' key that streams content over SSH stdin, and
the job writes the Compose file with it.
- A list-style build arg without a value (build.args: [SENTRY_IMAGE])
merged into a map environment kept its numeric key, so Docker Compose
rejected the file with "non-string key in ...environment: 0". It now
becomes NAME with no value, as in Compose.
Closes#11725
Since 50268139b the API returned 422 for custom_internal_name without
is_consistent_container_name_enabled. v4.3.23 accepted it, so clients
such as `coolify app update --custom-internal-name` broke.
- A custom_internal_name sent without the flag turns the flag on, the
same rule as the migration for existing applications
- Keep the 422 only when the request sends the flag as false
A pull request id above 2147483647 caused a database error and a 500.
- Previews store: validate max 2147483647 (422)
- /deploy: return 400 for pr or pull_request_id out of range
- Preview show, logs, update, and delete: return 422 for ids out of range
- Document the maximum in the OpenAPI spec
Container names use custom_internal_name only when consistent container
naming is on. The API accepted the name and then ignored it.
- Return 422 with a message that says to set
is_consistent_container_name_enabled to true
- Accept the name when the request or the application turns the setting on
- Document the requirement in the OpenAPI spec
Require deploy or root token access when creating managed mounts outside
resource directories or changing their file contents through the API.
Synchronize KeyDB and Dragonfly passwords with local and shared
REDIS_PASSWORD values while preserving secret manager resolution.
Allow validated host file and directory mounts outside resource directories
while protecting external paths from deletion.
Clean up cancelled deployment containers and clear tracked process IDs.
Preserve legacy KeyDB and Dragonfly password parsing, accept server backup
paths without extension restrictions, and allow Compose variable proxy ports.
A stop or delete no longer queues a full cleanup each time. It skips the
cleanup when one finished on the server in the last hour, and the queued
run only cleans when disk usage is at or above the server cleanup
threshold. The docker_cleanup API flag keeps its default of true.
New or changed manual webhook secrets (GitHub, GitLab, Bitbucket,
Gitea) must have at least 16 characters, in the Webhooks page and in
the application API. Stored secrets keep working: an unchanged value
passes, and an empty value still disables the webhook. Each secret
field gets a Generate button that fills a random 40-character secret;
the user saves it after adding it to the Git provider.