
Your apps run on Coolify and a backup schedule shows Success, but what does it cover? A database schedule dumps one database, the instance backup saves Coolify's settings without the key that decrypts them, and every file stays on the server it protects until you add S3. This guide sets up each built-in backup in Coolify 4.5.3 (the stable release on 31 October 2026), copies what they skip and restores all of it, on Ubuntu 24.04 or Debian 12. New to Coolify? Start with our Coolify and Dokploy guide.
Quick answer: Coolify has three backup types, each with its own schedule: Backups on a database dumps that database, Backups on an application or service archives its volumes and directory mounts (Coolify 4.3.0 and later), and Settings > Backup dumps Coolify's own database. Give each an S3 storage and retention limits, because new database schedules keep every dump. None of them saves APP_KEY from /data/coolify/source/.env, the SSH keys in /data/coolify/ssh/keys, File Mounts or Redis data, so copy those yourself. Restore a database with Import Backup, a volume by extracting its archive into the stopped volume, and Coolify with pg_restore and the saved APP_KEY.
What Coolify Backs Up, and What It Skips
| What | Built-in backup | Restore |
|---|---|---|
| PostgreSQL, MySQL, MariaDB, MongoDB | Database schedule | Import Backup |
| SQLite (experimental), ClickHouse | Database schedule | SQLite: Import Backup; ClickHouse: its own tools |
| Redis, Dragonfly, KeyDB | None | Your own copy |
| Volumes and Directory Mounts of apps and services | Storage backup | By hand |
| File Mounts, Host File Mounts | None | Your own copy |
| Coolify's database: projects, settings, credentials | Instance backup | pg_restore |
APP_KEY and SSH keys | None | Your own copy |
The instance backup "does not back up data stored inside your applications, databases, or volumes", and until you add S3, every schedule keeps its files in /data/coolify/backups on the server that runs the resource. Storage backups need Coolify 4.3.0 (12 August 2026) or later; your version is at the top left of the sidebar.
Step 1: Add an S3 Storage
An S3 copy survives the loss of the server. Coolify's S3 storage page lists Amazon S3, Cloudflare R2, Backblaze B2, Hetzner, Wasabi and MinIO among working providers. Create the bucket first, ideally with a different provider than your VPS host, since Coolify validates against an existing bucket:
- Open S3 Storage in the sidebar and select New storage.
- Fill in Name, Bucket, Region, Access Key and Secret Key, and split the endpoint into Protocol, Host and, if needed, Port and Path, without the bucket name.
- Select Validate Connection & Continue. Coolify tests the settings with a
ListObjectsV2request on the bucket.
Step 2: Schedule Database Backups
Open the database, select Backups, then + Add next to Database backups. Enter a Frequency and select Add schedule. It takes a five-field cron expression or every_minute, hourly, daily, weekly, monthly or yearly (cron syntax): daily is 0 0 * * *, and 30 3 * * * runs at 03:30 in the Timezone the schedule shows. Then open the schedule and set:
- Database selection: All databases or Specific databases for PostgreSQL, MySQL and MariaDB. With Specific databases, PostgreSQL gets a
pg_dumpcustom-format file per database, which our PostgreSQL guide can also restore outside Coolify; All databases writes one gzippedpg_dumpallfile (database backups). - S3 storage: choose your storage under S3 storages and select Enable S3. Leave Local copy on Keep local backup unless S3 should hold the only copy.
- Retention: Backups to keep, Days to keep and Maximum storage (GB), for local and S3 copies separately, where
0means no limit. New database schedules start with all six at0(migration, create form), so they keep every dump until you set limits, such as 7 local and 30 S3 backups to keep. - Missing backup alert after: days without a run before Coolify sends a failure notification;
0turns it off.
Select Back up now and open the execution: it should show Success, a size above zero and, with S3 enabled, a successful upload. A schedule only runs while the database runs; a stopped database skips that run.
A database inside a one-click service gets the same settings through New database backup on the service's Backups page; Coolify reads its credentials from the container's environment, such as POSTGRES_PASSWORD.
Step 3: Schedule Volume and Directory Backups
On an application, open Backups and select Add under Storage backups; on a service, use New storage backup on its Backups page. Choose the volume or directory in Backup target, enter a Frequency and select Create schedule. Then open the schedule (storage backups):
- Archive behavior: Keep containers running avoids downtime, but files may change during the archive. Stop containers during archive stops the containers that use the storage, archives it and starts them again, so the app is offline meanwhile.
- S3 storage and Retention work as in Step 2, except that a storage schedule keeps 7 local and 7 S3 archives by default.
- Timeout accepts 60 to 36000 seconds, and a new schedule starts at the maximum, 36000 (source).
Run Back up now and check Executions for Success, with Local Storage or S3 Storage under Backup Availability.
Coolify warns that an archive taken while files change "may be inconsistent or corrupted", so database data belongs in Step 2. File Mounts and Host File Mounts can't be selected, there's no restore button, and deleting a schedule "permanently deletes the schedule and every local and S3 archive created by it".
Step 4: Back Up Coolify Itself
Open Settings > Backup and select Configure backup the first time: Coolify then dumps its own database daily at 0 0 * * * in the instance timezone. If the page says instance backups are disabled, select Open server settings, then Validate connection. Add S3 and retention as in Step 2, since this schedule's limits also start at 0. Since 4.5.0 the page also has Backup before update, enabled by default: Coolify dumps its database before it installs an update and skips the update if that dump fails (settings page).
The dump holds your projects, settings and saved credentials. Coolify encrypts the credentials and private keys in it with the APP_KEY, which the dump doesn't contain. Save the key line in your password manager, together with your Coolify version:
sudo grep '^APP_KEY=' /data/coolify/source/.env
Without it, Coolify can't read restored credentials and private keys. The SSH keys in /data/coolify/ssh/keys/, which Coolify uses to reach its servers, need their own copy too.
Step 5: Copy What the Schedules Miss
Local copies sit in /data/coolify/backups: dumps in databases/, storage archives in volumes/ and instance dumps in coolify/. With S3 on every schedule, you already have an off-server copy. For a second one, copy as root: the installer creates the folder with mode 700 for user ID 9999. If you follow our restic guide, whose job runs as root, add these lines to its /etc/restic/include.txt:
/data/coolify/backups
/data/coolify/ssh/keys
/data/coolify/source/.env
/data/coolify/applications
/data/coolify/services
/data/coolify/databases
The last three hold File Mounts and other per-resource files (file mounts). Any database files in there are covered by the Step 2 dumps, not by this copy.
Redis, Dragonfly and KeyDB get no schedule. If yours holds more than a cache, stop it for a moment and archive its volume as our Docker volume guide shows, or use the engine's own persistence and backup tools, as Coolify's docs suggest.
Local archives share the disk with your apps: Coolify's install docs ask for space "for Docker images, volumes, and backups" on top of 10 GB free. If they outgrow it, you can upgrade a Space-Node VPS to a bigger plan from the client area.
Restore a Database
An import can overwrite data and credentials, so stop your app's writes and back up the target first. Then open Import Backup on the running database and pick a source (restore a database):
- Upload the file from your computer.
- File path on the server: paste the path from the execution and select Check file.
- S3 storage: choose the storage and enter the path in the bucket. Coolify uploads each file under the path it has on the server (DatabaseBackupJob.php), so the execution's path works here too.
Check Backup contents and the options. For a single PostgreSQL database, Replace objects that already exist is off by default, and existing objects can then make the import fail; Restore users and privileges (mysql system database) replaces users and passwords on an all-database MySQL or MariaDB import. Start the restore, follow Database Restore Output to the end, check your tables, let the app write again and take a new backup.
For every engine, Coolify's advice holds: "A successful backup only proves that Coolify created a file." Import one into a throwaway database of the same type now and then; our restore test guide turns that into a routine.
Restore a Volume or Directory
Coolify can download a storage archive, but it "does not provide a dashboard restore action". The archive is a gzip-compressed tar of the volume's contents (VolumeBackupJob.php), so it extracts straight into an empty volume. Stop the resource in Coolify. Then run this with the volume's full name, from Persistent Storage or sudo docker volume ls (Coolify puts the resource UUID in front), and the archive path from the execution:
V=VOLUME_NAME
A=/data/coolify/backups/volumes/PATH/FROM/EXECUTION.tar.gz
sudo docker volume inspect "$V" >/dev/null && sudo test -f "$A" && echo ready
sudo mkdir -p /root/restore
sudo docker run --rm -v "$V":/data:ro -v /root/restore:/backup ubuntu:24.04 \
tar czf /backup/before-restore.tar.gz -C /data .
sudo docker run --rm -v "$V":/data -v "$A":/backup.tar.gz:ro ubuntu:24.04 \
sh -c 'find /data -mindepth 1 -delete && tar xzf /backup.tar.gz --numeric-owner -C /data'
Go on only when the third line prints ready: Docker creates a missing volume without asking, and -v turns a missing host path into an empty directory. The first docker run keeps the current contents in /root/restore in case you picked the wrong archive. find -mindepth 1 -delete empties the volume but keeps its top folder, and --numeric-owner restores owners by user ID. Start the resource and read its logs.
For a Directory Mount, or an older Volume Mount with a Source Path, the data is a folder on the server:
A=/data/coolify/backups/volumes/PATH/FROM/EXECUTION.tar.gz
D=/srv/my-app/uploads
sudo test -f "$A" && sudo mv "$D" "$D.before-restore" && sudo mkdir "$D" \
&& sudo tar xzf "$A" --numeric-owner -C "$D"
If S3 holds the only copy, download the archive from your provider and copy it to the server first.
Restore Coolify Itself
Coolify's restore guide swaps its database for a dump while your apps keep running. On the same server, work as root (sudo -i) and take the dump's path from Executions, or list the dumps newest first with ls -lt /data/coolify/backups/coolify/*/. After a failed update, use the one Backup before update made just before it.
docker ps --filter name=coolify-db --format '{{.Names}} {{.Status}}'
export BACKUP_PATH=/data/coolify/backups/coolify/coolify-db-SERVER_IP/FILE.dmp
test -s "$BACKUP_PATH" && ls -lh "$BACKUP_PATH"
docker stop coolify coolify-redis
grep '^APP_KEY=' /data/coolify/source/.env
coolify-db must be running; on releases before 4.4, also stop coolify-realtime. If the APP_KEY line differs from your saved one, put the saved value in with nano /data/coolify/source/.env. Then load the dump and start Coolify with the installer, using your version instead of 4.5.3:
docker exec -i coolify-db pg_restore --clean --if-exists --exit-on-error \
--no-acl --no-owner --username=coolify --dbname=coolify < "$BACKUP_PATH"
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash -s 4.5.3
--clean --if-exists drops each object before restoring it, and --exit-on-error stops at the first error (pg_restore). The installer starts Coolify and applies any database migrations. Check that the dashboard opens without an encryption error, your projects are listed and Servers > localhost validates. If the files in /data/coolify/ssh/keys/ were lost, put your copy back before you run the installer.
On a new server, the guide adds three steps: install the same version first, keep the new .env except for APP_KEY, and swap in the old SSH keys with their public key in ~/.ssh/authorized_keys. Your app data then comes back through the two sections above, and our Coolify migration guide walks through the whole move.
If It Still Fails
Back up now creates no execution. The database isn't running, or a service database lacks its database-name variable, such as MYSQL_DATABASE or MARIADB_DATABASE.
Success (S3 Warning). The file is on the server, but the upload failed. Read the execution's message and validate the S3 storage again; Coolify also retests unusable storages every hour.
An encryption or "Invalid MAC" error after a Coolify restore. The active APP_KEY isn't the one that encrypted the dump. Stop coolify, put the saved value in .env and run the installer again. Don't add APP_PREVIOUS_KEYS: current Coolify reads APP_KEY.
Permission denied in the app after a volume restore. The files got the wrong owner. Run the restore again with sudo and --numeric-owner: without root, tar extracts files as yourself.
The disk keeps filling up. A retention of 0 keeps everything: set Backups to keep, or Delete after S3 upload. Don't free space with Delete unused volumes under Docker Cleanup: it deletes every Docker volume not attached to a container, and a stopped resource can leave its data in one (Docker cleanup).
FAQ
Is the instance backup enough to restore my apps? No. It restores Coolify's projects, settings, saved credentials and deployment history, not your apps' or databases' data. Restore those from their own backups.
Can I keep backups only in S3? Yes: set Local copy to Delete after S3 upload; a failed upload keeps the local file. The dashboard can't download a remote-only instance backup, so fetch that one from your S3 provider.
Should I add a database's volume to a storage backup? Not instead of a database schedule: an archive of a database that is writing can be inconsistent. As an extra copy, pick Stop containers during archive.
Are backups included with a Space-Node VPS? Not in the plan price; you can arrange them through a support ticket. Coolify's own schedules with an S3 copy give you backups you control either way.
Sources
All opened on 31 October 2026:
- Coolify docs: Database backups, Restore a database, Storage mount backups, Persistent storage overview, Volume mounts, Bind mounts, File mounts, Service persistent storage, Back up Coolify, Restore Coolify, S3 storage, Cron syntax, Automated Docker cleanup, SQLite, Start with self-hosted, Choose your path, Update Coolify, Reverb migration
- Coolify releases and versions: v4.3.0, v4.4.0, v4.5.0, versions file
- Coolify source at v4.5.3: VolumeBackupJob.php, BackupCompression.php, DatabaseBackupJob.php, CreateScheduledBackup.php, ScheduledVolumeBackup.php, volume backup timeout migration, database retention migration, volume backup migration, SettingsBackup.php, settings-backup.blade.php, UpdateCoolify.php, shared.php, install.sh, docker-compose.prod.yml
- Docker docs: Volumes, Bind mounts, docker volume ls, docker volume inspect
- Docker Official Images: ubuntu image definition
- PostgreSQL: pg_restore
- Man pages (Debian 12): tar(1), find(1), pigz(1), ls(1), test(1), mkdir(1), sudo(8)