Back to Article List

Automated database backups in Coolify

Automated database backups in Coolify

Most Coolify users find out about the built-in database backup feature about thirty seconds after deciding they really need a backup. There's something specific about the moment your Postgres container falls over or you accidentally drop the wrong table that makes you appreciate having a recent dump sitting somewhere else.

This guide walks through setting up automated, scheduled backups for Coolify-managed databases (PostgreSQL, MySQL, MariaDB, MongoDB and Redis), shipping them to S3-compatible external storage and verifying that the restore actually works. The full thing, not the half-version where you set up backups and never test that they're recoverable. Written against Coolify v4.0.0.

If you're new to Coolify, the getting started guide covers the basics of the dashboard and the localhost server connection. Past that, the rest of this is sequential.

What Coolify can and can't back up out of the box

Two things to clarify before clicking around. There's a difference between database backups (your application data) and Coolify instance backups (the configuration of Coolify itself, which includes your projects, applications, environment variables and resource definitions).

Database backups

For each database resource (Postgres, MySQL, MariaDB, MongoDB), Coolify has a Backups tab where you configure scheduled dumps. Coolify runs the appropriate dump command (pg_dump, mysqldump, mongodump) on a cron schedule, stores the result locally and optionally pushes it to S3-compatible external storage. Restore is manual but documented. This is what most people mean when they say "Coolify backups."

Coolify instance backups

Coolify itself stores its state in a Postgres database that runs alongside the dashboard, plus configuration files in /data/coolify on the host. To back up your Coolify configuration (so you can restore your full setup to a new server if the current one dies), you back up /data/coolify as a whole. This is a separate process from the per-database backups above.

Both matter. Database backups protect your application data. Instance backups protect your ability to recreate the Coolify setup itself. We'll cover both.

Step 1, decide where backups live

Local-only backups (stored on the same VPS as the database) are not really backups. If the VPS dies, you lose both the database and the backup. Treat local storage as a convenience for fast restores, not as your safety net.

For real backups you want S3-compatible external storage. Three sensible options:

Cloudflare R2 has a generous free tier (10 GB free), zero egress fees, good for nightly database dumps. The catch is regional availability of features but for plain object storage it's fine.

Backblaze B2 is cheap per-GB ($0.005/GB/month for storage), low egress, runs at scale. The dashboard isn't pretty but the API is solid.

Wasabi uses flat pricing ($6.99/TB/month), no egress fees inside reasonable use limits. Slightly more expensive per-GB at low volumes than R2 or B2 but predictable.

Self-hosted MinIO is also an option if you have a separate VPS or NAS, but the whole point of off-VPS backup is that the backup target isn't dependent on infrastructure you already have. Run MinIO somewhere different from your Coolify host or use a managed S3-compatible service.

Pick one, create a bucket called something like your-domain-coolify-backups, generate access credentials and note the endpoint URL, region, access key and secret. We'll plug these into Coolify in a moment.

Step 2, set up an S3 destination in Coolify

From the Coolify dashboard, click Servers in the left sidebar, then your server's name, then the S3 Storage tab (or it might be under Settings depending on your Coolify version). Click Add new S3 Storage.

Fill in the fields:

  • Name: a descriptive label like "R2 backups" or "B2 prod"
  • Endpoint URL: from your S3 provider (R2's looks like https://YOUR-ACCOUNT-ID.r2.cloudflarestorage.com, B2's like https://s3.us-west-002.backblazeb2.com)
  • Region: from your provider (R2 uses auto, B2 has region codes)
  • Bucket: the bucket name you created
  • Access Key: the access key ID from your provider
  • Secret Key: the secret access key from your provider

Save. Coolify validates the credentials by attempting a small test upload. If validation fails, double-check the endpoint URL (the most common typo is missing the https:// or wrong region in B2).

Once saved, this S3 destination is available for any database backup configuration on this server. You only need to set it up once per server.

Step 3, configure backups for a database

Open the database resource you want to back up. Go to the Backups tab. You'll see a section for scheduled backups.

Configure:

  • Frequency: how often to run the backup. Common options are daily, weekly or a custom cron expression. For most production databases, daily at off-peak hours (something like 0 3 * * * for 3 AM) is the right starting point
  • Save locally: keeps the backup on the same VPS for fast restore. Useful for the most recent few backups
  • Save to S3: pushes the backup to the S3 destination you set up in step 2. This is the actual safety net
  • Number of backups to keep: retention. Coolify deletes older backups beyond this count. For daily backups, 7 to 14 days is reasonable for local, 30 to 90 days for S3
  • Database to back up: for Postgres and MySQL resources, you can usually pick "all databases" or a specific one. For Postgres, you can also include or exclude specific schemas

Save. Coolify will run the next backup according to the schedule. To verify it works, click Run Backup Now and watch the Backups tab list update with a fresh entry. If the entry shows a green status with a file size, it worked. If it shows red, click into it and read the error log, the most common cause is wrong S3 credentials or insufficient disk space for the local copy.

Cron expression cheat sheet

If you need a custom schedule, the cron format is minute hour day-of-month month day-of-week. Common examples:

  • 0 3 * * * runs daily at 3:00 AM
  • 0 */6 * * * runs every 6 hours
  • 0 3 * * 0 runs weekly on Sunday at 3:00 AM
  • 0 3 1 * * runs monthly on the 1st at 3:00 AM
  • 30 2 * * 1-5 runs on weekdays at 2:30 AM

Pick a time when database load is low. For consumer-facing apps that's usually the early morning hours of your largest user timezone.

Step 4, verify the backup actually works (the part everyone skips)

A backup that hasn't been tested is not a backup. The whole point of this exercise is that when you eventually need to restore, the file is intact, the format is right and your restore procedure works. Test before you need to.

The cleanest test is to spin up a temporary database, restore the backup into it and run a count query against a known table. Inside your Coolify project, click Add a new resource → Database → PostgreSQL, name it something like postgres-restore-test, accept default credentials, click Start.

Now download the most recent backup file. From the database's Backups tab, click the most recent entry and download the file. SCP it onto your VPS, then restore into the test database from a temporary container on the Coolify Docker network:

docker run --rm -it \
  --network coolify \
  -v /path/to/backup.dump:/tmp/backup.dump \
  postgres:16 \
  pg_restore -h postgres-restore-test -U your-test-db-user -d your-test-db-name --no-owner --no-acl /tmp/backup.dump

Substitute the hostname and credentials with what Coolify generated for the test database. The restore takes seconds for small databases, minutes for larger ones.

Run a sanity check query. Connect to the restored database and count rows on a known table:

docker run --rm -it \
  --network coolify \
  postgres:16 \
  psql -h postgres-restore-test -U your-test-db-user -d your-test-db-name \
  -c "SELECT COUNT(*) FROM your_known_table;"

If the count matches what you'd expect on production, the backup is good. Delete the test database from Coolify (it served its purpose). Document the restore procedure somewhere (a note in your repo, a runbook in your wiki) so the next person doesn't have to figure it out at 3 AM.

For MySQL, the restore command uses mysql instead of pg_restore. For MongoDB it's mongorestore. The pattern is the same, spin up a temporary database, run the restore command from a container on the same Docker network, count rows.

Step 5, set up Coolify instance backups

Database backups protect your data. Coolify instance backups protect your configuration (projects, applications, env vars, resource definitions, the lot). If your Coolify VPS dies, you want to be able to provision a new VPS, restore Coolify's config and have your applications back without rebuilding everything from scratch.

Coolify stores its own state in two places. The coolify-db Postgres container holds projects, applications, env vars, deployment history. Files in /data/coolify on the host hold configuration files, persistent volume data and SSH keys.

Back up the coolify-db

The Coolify control plane has a built-in self-backup feature. From the dashboard, go to Settings → Backup (or Servers → your-server → Backup depending on UI version). Configure a daily backup of the Coolify database with the same S3 destination you used for application databases. The dump goes to S3 like any other backup.

Back up /data/coolify

This is the file-level part. The simplest path is a small cron job on the host that tars up /data/coolify nightly and pushes it to your S3 bucket using the aws CLI or rclone.

Install rclone on the host (apt install rclone), configure a remote with your S3 credentials (rclone config, follow the prompts), then add a cron entry:

# /etc/cron.d/coolify-backup
0 4 * * * root tar -czf /tmp/coolify-data.tar.gz -C /data coolify && rclone move /tmp/coolify-data.tar.gz remote:bucket/coolify-instance/$(date +\%Y-\%m-\%d).tar.gz

This runs at 4 AM, tars the entire /data/coolify directory, ships it to S3 with a date-stamped filename and removes the local tar after upload. Adjust the bucket and remote name to match your rclone config.

Test the restore by replicating onto a fresh VPS, untarring into /data/coolify, then running the Coolify install script which detects the existing data and rebuilds the dashboard around it.

Special cases worth knowing about

Backing up large databases

For databases over 50 GB, the default pg_dump approach gets slow and starts running into the maintenance window. Two improvements help.

Use pg_dump's parallel option (-j N where N is the number of CPU cores). This parallelizes the dump across tables. Coolify's built-in backup may not expose this flag in the UI, but you can run the dump manually with the flag and ship it yourself.

For really large databases (terabytes), file-level base backups via pg_basebackup with WAL archiving are the right pattern. This goes well beyond what Coolify's UI offers, but the Postgres documentation on continuous archiving walks through the setup.

Encrypting backups

S3 buckets should have encryption-at-rest enabled by default in 2026, but for an extra layer (and to protect against the S3 provider seeing your backup contents), encrypt the dump file before uploading. The pattern is pg_dump | gzip | gpg --symmetric --cipher-algo AES256, then upload the encrypted output. You'll need to keep the GPG passphrase somewhere accessible (a password manager, a sealed env var) because without it the backups are unreadable, including by you. There's a real cost to this if the passphrase ever gets lost.

Cross-region redundancy

If your application is critical enough that S3 region failure would matter, configure the S3 bucket to replicate to a second region (R2 has automatic replication, B2 doesn't yet, AWS S3 has cross-region replication). Or push to two different S3 destinations from Coolify, R2 plus B2 for example. The cost is small and the upside is non-trivial during the rare-but-real S3 outages.

Restore scenarios you should plan for

Single table accidentally dropped

The fastest fix is to spin up a temporary Postgres in Coolify, restore the most recent backup into it, dump just the affected table from the temp database, then load that into the production database. Total restore time on a moderate database, 5-15 minutes.

Whole database corruption

Stop the corrupted Coolify Postgres resource. Provision a new one with a different name. Restore the most recent good backup into it. Update your application's DATABASE_URL to point at the new resource. Redeploy the application. Total time, 15-45 minutes depending on database size.

Whole VPS unavailable

Provision a new VPS. Install Coolify (or use the LumaDock Coolify VPS with it pre-installed). Restore /data/coolify from the instance backup. Restore each application's database from S3. Redeploy applications. Update DNS to point at the new VPS IP. Total time, a few hours, mostly waiting for application redeploys to complete.

Common errors and how to fix them

Backup completes locally but never appears in S3

The S3 credentials are wrong, the bucket doesn't exist or the access key doesn't have permission to write. Check the backup logs in the Backups tab for the actual error. Verify the credentials by running aws s3 ls s3://your-bucket/ from your laptop with the same access key, if it errors there it'll error from Coolify too.

Backups disabled despite the schedule being set

The Coolify scheduler runs as part of the main Coolify container. If the scheduler crashed or never started, scheduled backups don't fire. Check docker logs coolify | grep -i schedule for errors. Restart the Coolify container if needed (docker restart coolify).

Backup file is suspiciously small (a few KB)

The dump command failed but the empty file was uploaded anyway. Check the backup logs for the dump command exit code. Common causes are out of disk space on the local /tmp path during the dump phase, the database user lacks permission to read all schemas or the dump command timed out.

Restore fails with "permission denied" or "role does not exist"

You used pg_restore without the --no-owner --no-acl flags and the dump references roles that don't exist on your new database. Re-run with both flags. They strip ownership and ACL information from the dump, which lets the restore land cleanly on a fresh database with a different user.

Restore appears to succeed but data isn't there

The schema was created but the data wasn't loaded. Most often this is because pg_restore hit errors during the data load phase but exited 0 anyway (because Postgres considered them non-fatal). Re-run with --exit-on-error and read the actual errors. Common causes are constraint violations from out-of-order table loading, fix with --disable-triggers as a last resort.

Where to go from here

Once backups are running and tested, set up monitoring so you find out about failed backups before you need them. The Coolify monitoring guide covers the monitoring stack and Coolify's notification system can alert you on backup failures via Slack, Discord or email. The production server security guide covers SSH hardening and Fail2ban, both of which apply to the VPS regardless of what's on it.

If you're managing multiple Coolify-hosted apps, the consolidated backup story across all of them stays the same, one S3 bucket, one schedule, one tested restore procedure per database type.

Your idea deserves better hosting

24/7 support 30-day money-back guarantee Cancel anytime
Ciclo de Facturación

1 GB RAM VPS

$3.99 Save  25 %
$2.99 Mensual
  • 1 vCPU AMD EPYC
  • 30 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Gestión de firewall
  • Monitoreo gratis

2 GB RAM VPS

$5.99 Save  17 %
$4.99 Mensual
  • 2 vCPU AMD EPYC
  • 30 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Gestión de firewall
  • Monitoreo gratis

6 GB RAM VPS

$14.99 Save  33 %
$9.99 Mensual
  • 6 vCPU AMD EPYC
  • 70 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P1

$7.99 Save  25 %
$5.99 Mensual
  • 2 vCPU AMD EPYC
  • 4 GB memoria RAM
  • 40 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P2

$14.99 Save  27 %
$10.99 Mensual
  • 2 vCPU AMD EPYC
  • 8 GB memoria RAM
  • 80 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P4

$29.99 Save  20 %
$23.99 Mensual
  • 4 vCPU AMD EPYC
  • 16 GB memoria RAM
  • 160 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P5

$36.49 Save  21 %
$28.99 Mensual
  • 8 vCPU AMD EPYC
  • 16 GB memoria RAM
  • 180 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P6

$56.99 Save  21 %
$44.99 Mensual
  • 8 vCPU AMD EPYC
  • 32 GB memoria RAM
  • 200 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

AMD EPYC VPS.P7

$69.99 Save  20 %
$55.99 Mensual
  • 16 vCPU AMD EPYC
  • 32 GB memoria RAM
  • 240 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

EPYC Genoa VPS.G1

$4.99 Save  20 %
$3.99 Mensual
  • 1 vCPU AMD EPYC Gen4 AMD EPYC Genoa de 4ª generación 9xx4 con 3.25 GHz o similar, basado en la arquitectura Zen 4.
  • 1 GB DDR5 memoria RAM
  • 25 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

EPYC Genoa VPS.G2

$12.99 Save  23 %
$9.99 Mensual
  • 2 vCPU AMD EPYC Gen4 AMD EPYC Genoa de 4ª generación 9xx4 con 3.25 GHz o similar, basado en la arquitectura Zen 4.
  • 4 GB DDR5 memoria RAM
  • 50 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

EPYC Genoa VPS.G4

$25.99 Save  27 %
$18.99 Mensual
  • 4 vCPU AMD EPYC Gen4 AMD EPYC Genoa de 4ª generación 9xx4 con 3.25 GHz o similar, basado en la arquitectura Zen 4.
  • 8 GB DDR5 memoria RAM
  • 100 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

EPYC Genoa VPS.G6

$48.99 Save  31 %
$33.99 Mensual
  • 8 vCPU AMD EPYC Gen4 AMD EPYC Genoa de 4ª generación 9xx4 con 3.25 GHz o similar, basado en la arquitectura Zen 4.
  • 16 GB DDR5 memoria RAM
  • 200 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

EPYC Genoa VPS.G7

$74.99 Save  27 %
$54.99 Mensual
  • 8 vCPU AMD EPYC Gen4 AMD EPYC Genoa de 4ª generación 9xx4 con 3.25 GHz o similar, basado en la arquitectura Zen 4.
  • 32 GB DDR5 memoria RAM
  • 250 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

1 vCPU AMD Ryzen 9

$13.99 Save  29 %
$9.99 Mensual
  • CPU dedicada 4.5GHz AMD Ryzen 9 7950X con una frecuencia nativa de CPU de 4.5 GHz.
  • 4 GB DDR5 memoria RAM
  • 50 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

2 vCPU AMD Ryzen 9

$25.99 Save  19 %
$20.99 Mensual
  • CPU dedicada 4.5GHz AMD Ryzen 9 7950X con una frecuencia nativa de CPU de 4.5 GHz.
  • 8 GB DDR5 memoria RAM
  • 100 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

8 vCPU AMD Ryzen 9

$92.99 Save  30 %
$64.99 Mensual
  • CPU dedicada 4.5GHz AMD Ryzen 9 7950X con una frecuencia nativa de CPU de 4.5 GHz.
  • 32 GB DDR5 memoria RAM
  • 400 GB NVMe disco
  • Ilimitado ancho de banda
  • IPv4 e IPv6 incluidos El soporte IPv6 no está disponible en Francia, Finlandia o Países Bajos.
  • 1 Gbps red
  • Copia automática incluida
  • Gestión de firewall
  • Monitoreo gratis

Frequently asked questions

How do I back up a Coolify Postgres database to S3?

Open the database resource in Coolify, go to the Backups tab, set up the schedule (daily at 3 AM is a sensible default), check Save to S3, pick the S3 destination you configured under your server's S3 Storage settings. Coolify runs pg_dump on the schedule and uploads the result. Set retention with the "Number of backups to keep" field. Cloudflare R2, Backblaze B2 and Wasabi are all good S3-compatible targets, R2 has the most generous free tier for small databases.

Stop installing. Start shipping.

LumaDock Coolify plans come with the dashboard pre-installed, unmetered bandwidth and a flat monthly bill. Try the server risk free with a 30-day refund guarantee.

GPU products are in high demand at the moment. Fill the form to get notified as soon as your preferred GPU server is back in stock.