Most people find out their backup strategy was wrong on the day they need it, which is the worst possible time to learn that. This is the post for the version of you that hasn't had that day yet. Coolify has a backup feature, and it's genuinely useful, but "Coolify has backups on" and "this server is actually recoverable" are not the same claim, and the gap between them is exactly where people get hurt. It comes down to a single, boring, and completely un-negotiable fact: your server isn't one thing to back up, it's five, and Coolify's own backup only reaches one and a half of them.
What actually has to be backed up?
Break "back up the server" into its actual parts and the scope of the problem stops being vague. There's Coolify's own instance data — the projects, resources, and deployment history that make Coolify itself useful rather than a blank dashboard. There's every application's Docker volumes and bind mounts, which is where uploaded files, generated assets, and anything written to disk at runtime actually lives. There's the databases, which need their own category entirely because a database isn't a folder of files you can copy, it's a live process with its own internal consistency rules. There's environment variables and secrets, which live in Coolify's own database and are easy to assume are covered by 'the instance backup' without checking. And there's TLS state — the certificates Traefik has already issued, which you'd rather not re-request from Let's Encrypt under rate limits during an actual outage. Readers who reach how to back up and restore a coolify server properly through a growth or RevOps role will want XenGrowth's marketing operations practice alongside this.
What | Does Coolify's built-in backup cover it? | What you actually need |
|---|---|---|
Coolify's own config (projects, resources, deployment history) | Yes — this is exactly what instance backup covers | Schedule it, and store the export somewhere other than the same disk |
Application Docker volumes / bind mounts (uploads, generated files) | No — explicitly out of scope per Coolify's own docs | A separate scheduled job (rsync, restic, or similar) to off-box storage |
Databases (Postgres, MySQL, MariaDB, MongoDB, Redis) | Partially — Coolify can schedule real dump-based backups to S3-compatible storage, but only if you configure it per database | Confirm the schedule is actually set per database; don't assume it's on by default |
Environment variables and secrets | Bundled inside instance backup, but easy to overlook as 'covered' without checking | Verify a restored instance actually shows your app's env vars before considering it done |
TLS certificate state (Traefik's issued certs) | Not separately tracked as its own backup category | Either accept re-issuance on restore, or explicitly capture Traefik's cert storage volume |
What Coolify's backup actually does — and where it stops
Coolify's instance backup, as documented, saves Coolify's own data: your projects, your resource configurations, your deployment history, the settings that make the dashboard useful. That's real and it matters — losing it means rebuilding every app's configuration from memory, which on a server running more than one or two things is a genuinely bad afternoon. But read the scope carefully, because it's stated plainly and often skimmed past: instance backup does not back up data stored inside your applications, your databases, or your volumes. Those are three different things sitting right next to the one Coolify actually protects for you, and assuming they're covered because 'Coolify has a backup feature' is the exact gap this post exists to close. The XenGrowth resource library approaches this from the the operations side of this side.
Where Coolify does help more than most self-hosted PaaS tools is database backups specifically. It supports scheduling real dump-based backups — pg_dump for Postgres, mysqldump for MySQL and MariaDB, mongodump for MongoDB, RDB snapshots for Redis — and pushing the result to S3-compatible storage: Amazon S3, MinIO, Backblaze B2, Cloudflare R2, or Wasabi. That's the right mechanism, and it's built in rather than something you have to script from scratch. The catch is that it's opt-in per database, not a blanket setting, and it's worth going and checking right now, on your actual server, whether it's configured on every database that matters — not whether Coolify supports it in principle.
Why a filesystem copy of a live Postgres directory isn't a backup
This is the mistake that trips people up most often, because it looks completely reasonable right up until it fails. Postgres stores its data as a directory of files on disk, so copying that directory — tar it up, rsync it somewhere, whatever — feels equivalent to backing up any other folder. It isn't, and the reason is specific: Postgres is a live process writing to those files continuously, and a filesystem-level copy taken while it's running can capture some files mid-write and others from a slightly different moment, because a plain copy has no concept of database transaction boundaries. The result is a data directory that's internally inconsistent in a way nothing about the copy operation itself will warn you about. Sometimes that inconsistent copy still starts up fine when you try to use it, which is almost worse than it failing outright, because you won't find the actual damage until a query returns wrong data or a table is silently missing rows nobody noticed were gone. Sometimes it refuses to start at all, and you find out exactly when you need it most: mid-recovery, server down, clock running. Postgres does have a correct way to do a filesystem-level backup — pg_basebackup, combined with WAL archiving — but that's a deliberate, consistent snapshot mechanism, not a bare cp or tar of a running data directory, and the two are not interchangeable no matter how similar the resulting file listing looks. XenGrowth on governed AI marketing workflows goes further into AI agents and marketing automation.
A backup you haven't restored is a hypothesis about a backup. The only way to know pg_dump actually captured something usable is to load it into a fresh Postgres instance and query it — not to see the file land in your S3 bucket and call it done.
Setting up the backups that actually matter
Turn on Coolify's instance backup first — it's the cheapest win here and covers the one thing that's genuinely automatic. Schedule it to run daily and confirm the export target isn't the same disk the server itself runs on.
For every database resource, go into its backup settings specifically and confirm a schedule is set with an S3-compatible destination configured — don't assume this inherited from the instance backup, it didn't.
For anything writing to a Docker volume or bind mount outside of a database — uploaded user files, generated PDFs, anything under a path mounted into a container — set up a separate scheduled job. A simple restic or rsync cron job pushing to the same S3-compatible bucket is enough; the point is that it exists and runs on a schedule, not that it's sophisticated.
Export your environment variables and secrets independently of whatever else you're backing up, at least occasionally, and store that export somewhere encrypted and separate from the server itself — if the box is gone, you want the values in hand before you're trying to reconstruct which API key went where from memory.
Decide, explicitly, what you're doing about TLS state. The simplest answer is usually to accept re-issuance: Let's Encrypt certificates are free and fast to reissue, and Traefik requests them automatically the moment DNS resolves to a working box again. The only reason to capture cert storage separately is if you're near Let's Encrypt's rate limits already, which is rare for a normal app.
Write down where every one of these backups lives and how to trigger a restore, somewhere that isn't only on the server itself — a dead server can't tell you where its own backups are stored.
The restore walkthrough: proving it actually works
None of the above matters if the first time you actually run a restore is during a real outage. Do this on a separate, disposable VPS — not the server you're trying to protect — before you ever need it for real.
Provision a fresh, small VPS with nothing on it and install Coolify with the standard one-line installer, exactly as if this were a brand-new server.
Restore the instance backup into this fresh install. You should end up looking at your real projects and resource configurations, not a blank dashboard — if you don't, the instance backup wasn't actually capturing what you assumed.
Pull the most recent database dump from your S3-compatible storage and restore it into a fresh, empty database instance — not the same running instance, a genuinely new one, so you're testing the dump file itself and not the memory of a process that never stopped running.
Run a real query against the restored database that would only return correct results if the data actually came through intact — count a table's rows, check a specific known record, something more meaningful than 'the database started without an error.'
Restore the volume backup for at least one application that stores real files, and confirm a specific known file is present and opens correctly, not just that a folder with the right name exists.
Time the whole exercise. This is the number that actually matters when someone asks 'how long until we're back up' during a real incident — not a guess, an actual rehearsed number from having done it once already.
Tear the test VPS down once you've confirmed all of the above, and put a recurring reminder to repeat this quarterly, or whenever you materially change what's running on the real server.
What this restore drill actually proves, and what it doesn't
A successful restore drill proves your backups are structurally valid and your process for using them works end to end — which is most of what a real disaster recovery actually needs. It doesn't prove your backup frequency is tight enough for your actual tolerance for lost data; if your database backup runs nightly and the server dies at 4pm, you've lost most of a day's writes regardless of how clean the restore process is. That's a separate decision — how often to back up, not whether the backup works — and it's worth setting deliberately rather than accepting Coolify's default schedule without asking whether it matches how much data you can afford to lose. XenGrowth on building one SEO and GEO content system works through AI search, GEO and discovery in more operational detail.
Your situation | What to prioritize |
|---|---|
Solo project, low write volume, downtime is annoying but not costly | Daily instance + database backups, quarterly restore drill is plenty |
A SaaS with paying customers and real user-generated data | Database backups on a tighter schedule (hourly, or WAL-based continuous archiving), plus the volume backup for uploads, tested monthly |
Multiple apps sharing one Coolify server | Confirm every database resource has its own backup schedule set — this is the setting most likely to be silently missing on app number three or four |
Anything already near Let's Encrypt's rate limits | Explicitly capture Traefik's certificate storage volume rather than relying on re-issuance during recovery |
Where this fits with the rest of running a Coolify server
Backup strategy is the part of self-hosting that's easiest to defer, because it produces nothing visible until the day it's the only thing that matters. If you haven't done the earlier, equally unglamorous work of securing the box in the first place, that's worth doing before this, not after — a server that's easy to compromise is a server whose backups you'll need sooner than you'd like. And if the failure mode you're most worried about is running out of headroom rather than losing the whole box, what happens when a VPS runs out of RAM covers the more common, less dramatic way these servers actually go wrong day to day. The deploy pipeline this backup plan is protecting is covered start to finish in the full Next.js-on-Coolify walkthrough, and it's worth reading both together — a working deploy pipeline and a tested restore are the same job looked at from opposite directions, and most people only budget time for one of them.
Further reading from XenGrowth
The XenGrowth resource library — what you'll learn: how the commercial side of this work is run, across search, automation and revenue operations.
XenGrowth on governed AI marketing workflows — what you'll learn: how the teams running AI marketing agents keep them governed and measurable.
XenGrowth on building one SEO and GEO content system — what you'll learn: how search and AI-answer visibility get run as a single content system.
Where this work meets go-to-market
For the marketing and revenue operations view of how to back up and restore a coolify server properly, see XenGrowth's revenue operations work.
Four questions on backing up the thing that manages everything else. The control plane has its own state, and it's easy to back up the applications and lose the setup that ran them.












