The MinIO client rejects endpoints such as `/storage/v1/s3`. Transfers to
these endpoints now use curl with a presigned URL that Coolify signs, for
database backups, volume backups, and S3 restores.
Closes#8530
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
remote_process() stored the full shell command as plain text in
activity_log and kept it for 60 days. Database starts store the compose file
with the database passwords, imports store S3 keys, and the Cloudflare
tunnel setup stores its token.
- Store the command encrypted. The queue worker decrypts it right before the
SSH call and still reads plain commands of tasks queued before the upgrade.
- Remove the command when the task is finished: after a successful run, in
failed() when no attempt is left, and for a stopped import. A failed attempt
that the queue retries keeps it.
- Do not write a command preview into the error log.
- Migration: remove stored commands from activities that no longer run.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A Coolify restart now fails queued or running database imports, so
they no longer block all later imports with 409.
- An import without progress for the SSH command timeout plus 30
minutes (at least 2 hours) is stale and no longer blocks.
- The import sets its operation property when the activity is created,
so a worker cannot save the activity without it.
- Start and restart refuse a second operation while a start, restart,
or import is in progress, in the UI, the API (409), and actions.
- DatabaseStartJob runs only while its activity is still queued and
the newest one, and holds a lock per database during the commands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Detect the backup format before any database is changed. "All databases"
imports no longer drop everything when the file cannot be restored.
- PostgreSQL: restore custom and tar archives with pg_restore and SQL with
psql in both modes, including gzip; restore the #11481 custom-archive fix.
Replacing existing data recreates the database for SQL backups.
- MySQL/MariaDB: accept a tar with one dump; reject dumps with more than one
database in single mode instead of restoring them partially.
- MongoDB: restore plain and gzip archives and dump directories packed as
tar; "Replace collections" maps to --drop.
- Prepare bz2, xz, and zip backups in the helper image, because database
images do not ship those tools; stream S3 backups from the S3 helper.
- Show the exact restore script in the import form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>