Database Backups on Tawa
Every MongoDB database on the platform is backed up automatically every night, and you can take an on-demand backup of your own service's database any time.…
Ruleprovision
About
Every MongoDB database on the platform is backed up automatically every night, and you can take an on-demand backup of your own service's database any time. Backups are stored in platform object storage (MinIO) with grandfather-father-son retention. Nothing to declare in `catalog-info.yaml` — backups are on by default.
Skill Content
This is the raw markdown that gets installed as a Claude Code rule.
# Database Backups on Tawa
## The Short Version
Every MongoDB database on the platform is backed up automatically every night, and you can take an on-demand backup of your own service's database any time. Backups are stored in platform object storage (MinIO) with grandfather-father-son retention. Nothing to declare in `catalog-info.yaml` — backups are on by default.
```bash
koko backup -s my-api -e prod # take a backup now
koko backups -s my-api -e prod # list backups
koko backup-download <id> -s my-api # get a temporary download link
koko restore <id> -s my-api --confirm # restore (admin, destructive)
```
## Automatic Nightly Backups
The builder runs a platform-wide backup every night (02:00 UTC by default). For each database it runs `mongodump --archive --gzip` and uploads the archive to the `tawa-db-backups` bucket.
Each nightly run is tagged with a retention tier (grandfather-father-son):
| Day | Tier | Kept |
|-----|------|------|
| 1st of month | `monthly` | 3 |
| Sunday | `weekly` | 4 |
| Any other day | `daily` | 7 |
Older automated backups beyond the keep count are pruned automatically. **Manual backups are never auto-pruned** — you delete those yourself.
## On-Demand (Self-Service) Backups
Take a backup of your own service's database whenever you want — before a risky migration, a data fix, or a release.
```bash
koko backup -s my-api -e prod
```
This dumps your service's MongoDB database, uploads it, and records it. Requires the `member` org role on the service's org.
### Listing
```bash
koko backups -s my-api -e prod
```
Shows both your manual backups and the nightly automated ones for your database, newest first, with size, tier, who took it, and status.
### Downloading
```bash
koko backup-download <backup-id> -s my-api -e prod
```
Returns a short-lived (15-minute) presigned URL to the gzipped archive. The archive is a standard `mongodump --archive --gzip` file — restore it anywhere with `mongorestore --archive=<file> --gzip`.
## Restore
Restore is **destructive**: it runs `mongorestore --drop`, which drops the target collections and replaces them from the backup. It is scoped to the original database only (`--nsInclude`), so no other database is ever touched.
```bash
koko restore <backup-id> -s my-api --confirm
```
Requires the `admin` org role **and** the explicit `--confirm` flag. Without `--confirm` the request is rejected.
## API Endpoints
Self-service backups are exposed by the builder, mirroring the `tawa db connect` whitelist model:
| Method | Endpoint | Role | Purpose |
|--------|----------|------|---------|
| `POST` | `/services/:name/databases/backup` | member | Take an on-demand backup |
| `GET` | `/services/:name/databases/backups` | viewer | List backups (manual + auto) |
| `GET` | `/services/:name/databases/backups/:id/download` | member | Presigned download URL |
| `POST` | `/services/:name/databases/restore` | admin | Restore (`{ "backupId": "...", "confirm": true }`) |
| `GET` | `/databases/backups` | platform admin | List all backups across orgs |
## Where Backups Live
Backups are stored in the platform MinIO object store, bucket `tawa-db-backups`, keyed:
```
{env}/{service}/{tier}/{db}-{timestamp}.archive.gz
```
## Off-Site Replication (Disaster Recovery)
The platform MinIO runs on the **same host** as MongoDB, so same-box backups protect against bad migrations and accidental data loss — **not** against total host loss. To cover that, the backup bucket is replicated nightly to an **off-site MinIO** on a separate DigitalOcean droplet (`tawa-db-backups`, region **sfo2** — a different region from the builder host in sfo3).
```
02:00 UTC builder dumps all DBs -> tawa MinIO (tawa-db-backups, on the builder host)
03:30 UTC systemd timer: mc mirror -> off-site MinIO droplet (sfo2, 200GB volume)
```
- Replication is an incremental `mc mirror --overwrite --remove`, so the off-site copy tracks retention pruning.
- Script: `iec-builder/scripts/backup-offsite-sync.sh` (reads `/etc/tawa-backup-offsite.env`); units: `tawa-backup-offsite.{service,timer}`.
- The off-site droplet's MinIO port is firewalled to the builder host's IP only.
If the builder host is lost entirely, the latest backups still exist on the off-site droplet and can be restored from there.
## Configuration (Platform Operators)
Controlled by builder environment variables (defaults shown):
| Var | Default | Purpose |
|-----|---------|---------|
| `BACKUP_ENABLED` | `true` | Master switch for the nightly scheduler |
| `BACKUP_BUCKET` | `tawa-db-backups` | MinIO bucket |
| `BACKUP_CRON_HOUR_UTC` | `2` | Nightly run hour (UTC) |
| `BACKUP_RETENTION_DAILY` | `7` | Daily backups kept |
| `BACKUP_RETENTION_WEEKLY` | `4` | Weekly backups kept |
| `BACKUP_RETENTION_MONTHLY` | `3` | Monthly backups kept |
| `BACKUP_DOWNLOAD_TTL_SECONDS` | `900` | Presigned download URL lifetime |
| `BACKUP_TMP_DIR` | `/tmp/iec-backup` | Scratch dir for archives |
| `BACKUP_DUMP_TIMEOUT_MS` | `7200000` | Per-DB mongodump/restore timeout (120 min) — raise for very large databases |
| `BACKUP_EXCLUDE_PATTERNS` | (empty) | Comma-separated globs of DB names to skip in the nightly run (e.g. `migration_*`). Skipped DBs are logged each run. |
Backups require `DB_MONGODB_ADMIN_URI` (admin Mongo access) and MinIO admin credentials in Vault KV (`secret/minio/admin`). If `DB_MONGODB_ADMIN_URI` is unset, the scheduler logs a warning and stays idle.
## What NOT to Do
```bash
# ❌ WRONG: restore without --confirm — rejected (destructive guard)
koko restore <id> -s my-api
# ❌ WRONG: assuming same-box MinIO is full disaster recovery
# It protects against bad data, not host loss. Off-box replication is separate.
# ✅ CORRECT: snapshot before a risky migration, then restore if it goes wrong
koko backup -s my-api -e prod
# ... run migration ...
koko restore <id> -s my-api --confirm # only if needed
```
Install
Copy the skill content and save it to:
~/.claude/rules/tawa-database-backups.mdComing soon via CLI:
tawa chaac install tawa-database-backupsDetails
- Format
- Rule
- Category
- provision
- Version
- 1.0.552
- Tokens
- ~1,481
- Updated
- 2026-08-28
platformdatabasesbackupsmongodbrestoredisaster-recoveryminio