Backups and restores
Schedule backups, send them off-site, verify they can actually be restored, and restore to a point in time.
A backup captures your applications’ data directories, your managed databases and your named volumes into one encrypted archive. It can run on a schedule, land off-site in S3, and — the part most panels skip — be tested without touching anything live.
A definition, and its runs
Two different objects wear the word “backup”, and the distinction saves confusion later:
- A definition
- The configuration — what to capture, where to send it, on what schedule. It never holds data, is never restorable, and does not count against your project’s backup quota.
- A run
- One realized archive on disk or in a bucket, produced by the schedule or by Back up now. This is the thing you restore, verify, export or delete.
Editing a definition changes what the next run captures. It never rewrites an archive that already exists — an old backup stays exactly what it was when it was taken.
What goes in
A backup is scoped either to one project or to a whole server, and four independent switches decide what it captures:
| Switch | Captures |
|---|---|
| Applications | Each application’s data directory on the host. |
| Databases | A logical dump per managed database — pg_dump, mysqldump, mongodump, or the engine’s equivalent. |
| Volumes | Named Docker volumes, as a tar per volume. |
| Linux instances | The /root, /home and /data of each instance. Its own switch because an instance is a whole machine and can be an order of magnitude larger than an application’s data dir. |
A project-scoped backup captures only that project. A server-scoped one captures every project on the machine — useful for an operator snapshot, wrong as a per-tenant default.
Scheduling
A definition takes @hourly, @daily, @weekly, or a cron expression of the form <minute> <hour> * * *:
@daily
@weekly
30 4 * * *Runs are limited in width: a couple execute at a time and the rest wait their turn. A queued backup is not a failed backup, and letting twenty dumps compete for the same disk makes all twenty slow.
How many are kept
A schedule that never deletes anything fills a disk on a timer. Three independent limits decide what survives, each of them settable per project and falling back to the platform default when left unset:
| Limit | Applies to | Off when |
|---|---|---|
| Keep last N | Runs of one schedule. The oldest are deleted once the newest N are in place. | 0 |
| Age in days | Completed backups older than the window, whatever produced them. Capped at 3650. | 0 |
| Max per project | Every backup the project holds, manual and scheduled together — a ceiling, not a sweep. | 0 |
This is separate from the history the panel keeps about itself — metrics, deployments, the audit log. Those are rows in a database; these are archives on a disk.
Where it lands
- Local
- A file in the platform’s backup directory, mode 0700. Fine for convenience, useless against the failure where the host itself is lost.
- S3, R2 or B2
- Any S3-compatible bucket, configured per project. This is the one that survives losing the server.
Encryption and integrity
- Archives are AES-256-GCM encrypted at rest with the install’s backup key, kept separate from database access.
- A
sha256of the final on-disk file is recorded at write time and re-verified before every restore. A mismatch refuses the restore rather than replaying a corrupt or tampered archive over live data. - Reading backups needs
backups:view; creating thembackups:create; restoring and exportingbackups:restore. Restore is its own permission because it overwrites.
Proving a backup is restorable
Verify replays every database dump in the archive into a throwaway scratch container, waits for that container to accept connections, and counts the objects it ends up holding. Then it throws the container away. Live data is never touched.
The same readiness probe and object count run at the end of a real restore, so “ready” means the same thing on both paths. A restore that replays cleanly into a database nobody can reach reports a warning rather than a green tick — the worst thing this feature could say is “Restore completed” over a database that is down, because then you stop looking.
Restoring
A restore takes a COMPLETED run and replays it. You can narrow it to specific applications, databases or volumes rather than replaying the whole archive — useful when one database was dropped and the rest of the project is fine.
Taking a backup elsewhere
Export produces a .dcbak — a portable copy of a realized backup, encrypted with a passphrase you choose rather than with the install’s key. That is what makes it readable by a different DockBoard install:
- 01Export the run, choosing a passphrase. Store the passphrase somewhere other than next to the file.
- 02On the target install, Import the
.dcbak, supplying the same passphrase and the server to restore onto. - 03The import restores immediately — it is a restore, with all of a restore’s consequences.
Backing up DockBoard itself
Everything above backs up your data. The platform’s own database — which projects exist, which servers, which credentials — is backed up separately, from Admin → Backups:
- Control-plane dump
- A daily logical dump of the platform database. Small — schema and rows, no blobs — so a fortnight of history costs almost nothing and covers a corruption noticed late.
- Point-in-time recovery
- A weekly physical base backup plus WAL archiving. Together they recover any instant in between. Either alone recovers nothing useful — which is why the status page reports both, separately.
servers:manage) and are never reachable by a project member or an API key. Treat the downloaded file with the same care as the platform database itself.