Docker Compose gives a recreated container the old mount at each path
that the image declares with VOLUME, also a volume deleted in Coolify.
Before `up`, remove only containers that still mount a Coolify volume
whose storage entry was deleted. The stale volume delete dialog now
warns when a container still uses the volume.
Closes#6875
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status checks now queue a delayed check for each application, preview,
service part, or database that goes from up to exited. After 2 minutes
it sends the "Resource status changes" notification if the resource is
still stopped, no deployment runs, and Coolify did not stop it. Each
resource sends at most one notification in 15 minutes.
Closes#9493
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.
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>
A single service deploy with an unchanged config keeps the running
container, which is already on the network. The connect then logged a
false "already exists" error and a warning. Check the container's
networks first.
Closes#11295
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Create the containers with --no-start, connect them to the destination
network, then start them. A container that crashed before the late
connect was restarting, the connect failed silently, and it never
joined the network.
Closes#11371
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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
The service start script goes to the server over stdin. When the
configuration of an existing volume changed, docker compose asked to
recreate the volume and read the next script line as the answer. That
line, for example the proxy network connect, did not run.
- Add < /dev/null to the service compose up and pull commands
- Do not use --yes, because it recreates the volume and deletes data
After a start, the UI showed "exited" until the regular status check ran.
That check runs on the shared high queue, which can be busy (60 s on Cloud).
The start job (database) and the start task (service, on the deployment
queue) now inspect only the started containers and store their status
before they broadcast. While a health check reports "starting", they
inspect again for up to about 15 s.
ContainerStatusAggregator now builds the per-container status and the
Compose aggregation for both writers, so GetContainersStatus and the
targeted check store the same strings.
On cloud, StartService and DeployServiceApplication dispatched their
CoolifyTask on the high queue, so service starts competed with all other
high jobs. remote_process() and CoolifyTask now accept a queue (default
high); start paths pass deployment_queue(). The queued RestartDatabase
action also runs on deployment_queue() instead of the default queue.
- Write remote secret values as exact dotenv literals in the service .env
file and escape "$" where they go directly into a generated compose file
(environment, start commands, healthchecks).
- Resolve remote secrets before a service or database restart stops the
running resource, and show the secret manager error instead of a generic
start failure (new RemoteSecretException).
- Cache fetched key names for the autocomplete and rate limit how often a
user can contact the secret manager.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching an external volume from the old <uuid>_<name> volume to the
declared external volume on redeploy could make an app look as if it
lost its data (for example a database that initializes a new, empty
data directory).
- If a resource already has the storage entry with the old generated
name, the parsers keep using that volume and show a warning in the
deployment log and the service start log, with the steps to switch.
- Without that entry (new resources, or external volumes added later)
the external volume is used as declared.
- Deleting the old storage entry (storage page) switches to the
external volume on the next deployment; the storage entry shows a
note about it.
- Legacy Compose applications (parser versions 1 and 2) never stored
their volumes, so they keep the old volume names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Compose content files are written by a queued job. Deployments and
service starts now check all content files with one command before
docker compose up: a missing file or an empty directory (left by
Docker) is written; an existing file is kept; a directory with files
is kept with a visible warning.
- The server file sync that runs after every parse marked a file
storage as a directory and deleted its configured content when a
directory was at its path. A storage with content now keeps its
content; an empty directory is replaced with the file.
- Saving a storage no longer fails for an existing file, replaces an
empty directory, and no longer deletes a directory with files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drop restart-limit fields and enforcement from database resources, clear cached Traefik version data when proxies change, and show missing service environment variables from disabled deploy actions.
Ensure restart actions flow through StartService so pull-latest restarts can
avoid stopping the service before image pulls. Also raise the changelog modal
above the desktop sidebar toggle.
Use config-based queue selection for deployment and scheduled jobs so cloud dispatches deployments to `deployments` and scheduled jobs to `crons`, while self-hosted keeps using `high`.
Add coverage for deployment queue helper, start action routing, and scheduled job manager routing.
Add strict validation for Docker network names using a regex pattern
that matches Docker's naming rules (alphanumeric start, followed by
alphanumeric, dots, hyphens, underscores).
Changes:
- Add DOCKER_NETWORK_PATTERN to ValidationPatterns with helper methods
- Validate network field in Destination creation and update Livewire components
- Add setNetworkAttribute mutator on StandaloneDocker and SwarmDocker models
- Apply escapeshellarg() to all network field usages in shell commands across
ApplicationDeploymentJob, DatabaseBackupJob, StartService, Init command,
proxy helpers, and Destination/Show
- Add comprehensive tests for pattern validation and model mutator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>