Add scheduled backups of database and uploads
Build and Push Lunchtime Images (Kaniko) / build-and-push (push) Successful in 7m9s

The backend now writes a timestamped tar.gz of the SQLite snapshot and all
per-order files to BACKUP_DIR on a cron schedule (default 03:00), keeps the
newest BACKUP_KEEP archives, and catches up once on start if a slot was
missed. Configurable via BACKUP_CRON / BACKUP_KEEP / BACKUP_DIR / TZ.
Includes user-facing restore docs in docs/backups.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
simandClaude Sonnet 5.5 committed 2026-11-05 22:31:28 +00:00
1 parent 1df83afab1
commit 9d80e6d06e
8 files changed
+203 -1

No files matched your search

+48
View File
@@ -0,0 +1,48 @@
# Backups
The backend backs itself up. By default, every night at 03:00 it writes one archive containing the SQLite database and all uploaded/per-order files (`configs/`, `descriptions/`, `templates/`, `payments/`, `images/`, `notifications/`) to `/app/backups`, and keeps the newest 14.
Mount `/app/backups` to a host folder (the compose files use `./.backups`) and copy or mount that wherever you like.
Archives are named `lunchtime-YYYYMMDD-HHMMSS.tar.gz` (local time of the container, see `TZ`). The database inside is a consistent snapshot taken while the app is running.
## Configuration
Environment variables of the `backend` service:
| Variable | Default | Meaning |
|---------------|---------------|---------|
| `BACKUP_CRON` | `0 3 * * *` | Standard 5-field cron expression. Empty disables backups. An invalid value is logged as an error and disables backups. |
| `BACKUP_KEEP` | `14` | Number of archives to retain; older ones are deleted after each run. |
| `BACKUP_DIR` | `/app/backups`| Where archives are written. Keep it outside `/app/data`. |
| `TZ` | container default (UTC) | Timezone the cron expression is evaluated in, e.g. `Europe/Vienna`. |
If the container was down at the scheduled time, it takes one backup on the next start instead of waiting for the next slot. Failures are logged (`backup failed`) and retried at the next slot; they never affect the app.
## Restoring
This replaces the current data. To keep it, copy `.data` aside first.
```bash
# 1. Stop the backend so nothing writes while you restore
docker compose stop backend
# 2. Empty the data folder (host path mounted at /app/data) and extract the archive into it
rm -rf .data/*
tar -xzf .backups/lunchtime-20261105-030000.tar.gz -C .data
# 3. Start again
docker compose start backend
```
The archive's top level is the contents of the data folder (`burger_orders.db`, `configs/`, `images/`, ...), so extracting into the data folder restores everything. Do not leave old `burger_orders.db-wal` / `-shm` files from the previous data in place; the `rm -rf` in step 2 removes them.
To restore into a fresh install, create the data folder, extract the archive into it, then start the stack.
To restore only a single file (for example one order's image), extract just that path:
```bash
tar -xzf .backups/lunchtime-20261105-030000.tar.gz -C .data images/<file>
```
Restoring only part of the database is not possible this way; the database is restored as a whole.