Backup & Recovery
Chinaski runs three cooperating backup layers, each with a different job, so no single failure takes your site with it. This page orients you to the layers and links the detailed pages.
Together they cover the standard resilience stack: frequent local snapshots for fast recovery after mistakes, full in-app archives for complete point-in-time recovery and off-site copies, and, on hosted database tiers, an off-site cloud copy that survives the loss of the machine entirely.
The three layers
- The daily system backup: a systemd timer runs
backup.shonce a day (default 03:17, deliberately off-peak). It takes a WAL-safe SQLite snapshot, integrity-checks it before keeping it, gzips it, and stores it in/var/backups/chinaski<N>/with a 14-day default retention (configurable). The media directory is mirrored separately by rsync, because media files are immutable after upload and a mirror is safe to maintain incrementally. - In-app backups (Admin → Backups): full
.tar.gzarchives containing the database and media and themes and site templates. Created manually, on a daily-or-weekly schedule, and (optionally) pushed automatically to a DigitalOcean Spaces bucket for off-site storage. Each created archive is verified by default before it counts. - Restore flows: the restore side lives with the backups: uploading an archive (with a dry-run preview and confirm step), restoring from a Spaces-stored archive, or restoring from the system’s daily snapshot by hand during disaster recovery.
What’s in a backup
System-level snapshots capture the database (all content, users, settings, logs) plus a media mirror. In-app archives capture the database plus media plus themes plus site templates: everything the site is made of, in one file you can move to another host. The daily-and-Spaces+restore pages walk through each layer’s exact contents.
The paths this section covers
- Schedule & Retention: where the automatic schedules live (system cron/timers and in-app schedule settings), the retention knobs for both database snapshots and local in-app archives, and how pruning behaves.
- Manual Backup: point-in-time archives: what’s in the file, creating, downloading, deleting; the caution that manual flows are part of the same retention/verification pipeline.
- Restore: the in-app restore surface: dry-run previews, schema-version gating, atomic database restore, staged media swap; what “restore refused” means.
- Disaster Recovery: the full-host runbook: rebuilding Chinaski elsewhere from what you are already keeping.
Safety posture worth knowing up front
- Verification is on by default. Every in-app archive is extracted and validated after creation; a failed verify keeps a bad archive from being stored.
- Sensitive by design: archives contain password hashes and encrypted secrets. The backup directory is tightened to mode
0700on every system-backup run, archives are written mode0600, and the restore controls are admin-only with every restore audited. - Protect the credentials, not just the data: restoring a database into an instance whose
CHINASKI_SECRETdiffers loses access to encrypted settings (SMTP passwords, webhook secrets). The env file (CHINASKI_SECRET,LISTEN_URL) is a separate artifact you should copy during any full-host migration; it is not inside the backups. - Everything is audited: creation, restore, deletion, retention pruning all write audit entries with the actor and the filename.
Also in Backup & Recovery
Schedule automatic backups daily or weekly at a set time, see what runs when, and prune old backups with retention to keep disk use bounded.
Restore a backup over your database and media: what gets replaced, and restoring from an upload, a local archive, DO Spaces, or the API.
Recover from a dead host or failed restore using the three backup layers: system timer backups, in-app archives, and uploaded archives.
Take a point-in-time Chinaski backup on demand from the Backups page: what the .tar.gz contains, how it is verified, and how it is stored.