56 lines
1.9 KiB
Markdown
56 lines
1.9 KiB
Markdown
|
|
# Meezi database backup & restore
|
||
|
|
|
||
|
|
## How backups work
|
||
|
|
The `meezi-backup` container (in `docker-compose.yml`) runs a nightly `pg_dump`
|
||
|
|
of the whole `meezi` database at **02:00 Asia/Tehran**, gzips it, and keeps the
|
||
|
|
**last 14 days** in the host `./backups` directory (override with `BACKUP_DIR`).
|
||
|
|
Filenames: `meezi_YYYYMMDD_HHMMSS.sql.gz`. One backup is also taken immediately
|
||
|
|
when the container first starts.
|
||
|
|
|
||
|
|
Check it's running / list backups:
|
||
|
|
```bash
|
||
|
|
docker logs meezi-backup --tail 20
|
||
|
|
ls -lh ./backups
|
||
|
|
```
|
||
|
|
|
||
|
|
## ⚠️ Copy backups OFF the server
|
||
|
|
The bind-mounted `./backups` survives a container/volume wipe, but **not a disk
|
||
|
|
failure**. Add an off-box copy (run from the host via cron), e.g.:
|
||
|
|
```bash
|
||
|
|
# rsync to another host nightly at 03:00
|
||
|
|
0 3 * * * rsync -az --delete /path/to/meezi/backups/ user@backup-host:/srv/meezi-backups/
|
||
|
|
```
|
||
|
|
or `rclone copy ./backups remote:meezi-backups` to object storage.
|
||
|
|
|
||
|
|
## Restore
|
||
|
|
1. Pick a dump:
|
||
|
|
```bash
|
||
|
|
ls -lh ./backups # choose e.g. meezi_20260615_020000.sql.gz
|
||
|
|
```
|
||
|
|
2. (Recommended) stop the API so nothing writes mid-restore:
|
||
|
|
```bash
|
||
|
|
docker stop meezi-api
|
||
|
|
```
|
||
|
|
3. Restore into the running Postgres container:
|
||
|
|
```bash
|
||
|
|
gunzip -c ./backups/meezi_20260615_020000.sql.gz \
|
||
|
|
| docker exec -i meezi-db psql -U meezi -d meezi
|
||
|
|
```
|
||
|
|
For a clean restore into an empty DB, drop & recreate first:
|
||
|
|
```bash
|
||
|
|
docker exec -i meezi-db psql -U meezi -d postgres -c "DROP DATABASE meezi;"
|
||
|
|
docker exec -i meezi-db psql -U meezi -d postgres -c "CREATE DATABASE meezi OWNER meezi;"
|
||
|
|
gunzip -c ./backups/<dump>.sql.gz | docker exec -i meezi-db psql -U meezi -d meezi
|
||
|
|
```
|
||
|
|
4. Start the API again (it runs EF migrations on boot, which is a no-op if the
|
||
|
|
dump is current):
|
||
|
|
```bash
|
||
|
|
docker start meezi-api
|
||
|
|
```
|
||
|
|
|
||
|
|
## Manual one-off backup
|
||
|
|
```bash
|
||
|
|
docker exec meezi-db pg_dump -U meezi --no-owner --no-privileges meezi \
|
||
|
|
| gzip -9 > ./backups/meezi_manual_$(date +%Y%m%d_%H%M%S).sql.gz
|
||
|
|
```
|