|
<div class="docs-content" data-render>
|
|
# Backups
|
|
|
|
> Audience: administrators. This page is hidden from members and guests in the sidebar, the search
|
|
> index, and the documentation export. It describes the backup service, where archives live, and how
|
|
> to schedule and rotate them.
|
|
|
|
DevPlace ships an enterprise-grade backup service that captures point-in-time copies of platform
|
|
data as compressed `tar.gz` archives. Every backup runs as an asynchronous job in a subprocess off
|
|
the request path, so creating a backup never blocks the server or slows requests.
|
|
|
|
## Targets
|
|
|
|
A backup captures one of four targets:
|
|
|
|
- **Database** - a consistent SQLite snapshot of the main database plus the Devii task and lesson
|
|
databases. The snapshot uses SQLite's online backup API, so it is consistent even while the server
|
|
is writing under WAL.
|
|
- **Uploads** - every attachment and project file under the uploads directory. This is normally the
|
|
largest target.
|
|
- **Keys and config** - the VAPID notification keys and other small config artifacts.
|
|
- **Full data directory** - the database snapshot, uploads, and keys in one archive. Regenerable and
|
|
volatile data (job staging, locks, zip archives, container workspaces, search caches) is excluded
|
|
because it can be rebuilt and would only bloat the archive.
|
|
|
|
## Where backups live
|
|
|
|
Archives are written under the runtime data directory at `data/backups/`, sharded into a two-level
|
|
`xx/yy` tree taken from the random tail of each backup's identifier so no single directory grows
|
|
without bound. Each archive is named `target-YYYYMMDD-HHMMSS-id.tar.gz` and recorded with its size,
|
|
file count, and a SHA-256 checksum for integrity verification. Staging happens under
|
|
`data/backup_staging/` and is removed as soon as the archive is built.
|
|
|
|
Because everything lives under the single data directory, pointing `DEVPLACE_DATA_DIR` at a mounted
|
|
volume in production places backups on that volume automatically.
|
|
|
|
## Creating a backup
|
|
|
|
Open **Admin -> Backups**, choose a target, and select **Create backup**. The dashboard shows the
|
|
job moving from pending to running to done; when it completes a download link appears. Backups can
|
|
also be created from the command line with `devplace backups run <target>` (the running server
|
|
processes the enqueued job), or by asking Devii to back up a target.
|
|
|
|
**Downloading is restricted to the primary administrator** - the earliest-created Admin, resolved by
|
|
`database.get_primary_admin_uid` / `utils.is_primary_admin`. `GET /admin/backups/{uid}/download`
|
|
returns `403` for every other administrator, and the `download_url` is withheld from them at every
|
|
endpoint (their Download control renders disabled). Any admin may still create, schedule, and delete
|
|
backups.
|
|
|
|
## Scheduling and rotation
|
|
|
|
A backup schedule fires backups automatically. Each schedule has:
|
|
|
|
- a **target** (database, uploads, keys, or full),
|
|
- a **trigger** - either an interval in seconds or a 5-field cron expression
|
|
(`minute hour dom month dow`),
|
|
- a **keep_last** retention count - after each scheduled backup completes, older backups created by
|
|
the same schedule beyond this count are deleted to reclaim space (0 keeps them all).
|
|
|
|
Schedules are evaluated by the backup service, which runs only on the worker holding the service
|
|
lock, so each scheduled backup fires exactly once. Create, edit, enable, disable, run, and delete
|
|
schedules from the dashboard.
|
|
|
|
## Storage visibility
|
|
|
|
The dashboard reports the size and file count of every major data area (database, uploads,
|
|
attachments, project files, keys, zip archives, search data, container workspaces, and the backups
|
|
themselves), the total data-directory footprint, the total size and count of stored backups, and the
|
|
underlying disk usage (total, used, free, and percent). The scan runs in a worker thread and is
|
|
cached briefly so it never blocks page rendering.
|
|
|
|
## Retention and deletion
|
|
|
|
Backup archives are permanent operational artifacts: unlike the async job rows that track them, an
|
|
archive is never swept away by job retention. It is removed only when an administrator deletes it,
|
|
when a schedule rotates it out via keep_last, or by the `devplace backups clear` command. Deleting a
|
|
backup is a hard delete that unlinks the archive file and reclaims its disk space immediately, and is
|
|
recorded in the audit log.
|
|
|
|
## Restore
|
|
|
|
This service creates and stores backups; it does not restore them into a live server, because
|
|
overwriting the database or uploads while the application is running risks corruption. To restore,
|
|
stop the server, unpack the relevant archive over the data directory (each archive is rooted at
|
|
`database/`, `uploads/`, or `keys/`), verify the SHA-256 checksum recorded for the backup, and start
|
|
the server again.
|
|
|
|
## Command line
|
|
|
|
- `devplace backups list` - list recorded backups with target, status, size, and filename.
|
|
- `devplace backups run <database|uploads|keys|full>` - enqueue a backup for the running server.
|
|
- `devplace backups prune` - remove backup records whose archive file is missing.
|
|
- `devplace backups clear` - delete every backup archive and record.
|
|
</div>
|