# Restore Kvitt from a Drive backup (SPEC §10.9) Run on the Kvitt Pi, in `~/kvitt` (`/home/jacobhagstedt/kvitt`), as `jacobhagstedt`. The files in `data/` and `backups/` are yours (both containers run as your uid, D-125), so they are moved with plain `mv` and `cp`; only `rclone` and `sqlite3` come from the running `backup` container. Nothing is deleted: the current database and pictures are moved aside. Do not run it around 03:30, when the nightly backup runs. ```bash cd ~/kvitt FOLDER=$(sed -n 's/^RCLONE_FOLDER_ID=//p' .env) ``` ## 1. Stop the server ```bash docker compose stop server ``` ## 2. Download the chosen backup from Drive to the Pi List what is on Drive (newest last) and pick a stamp: ```bash docker compose exec -T backup sh -c 'c=$(mktemp); cp /config/rclone/rclone.conf "$c"; RCLONE_CONFIG=$c rclone lsf gdrive: --drive-root-folder-id "$1" --files-only; rm -f "$c"' sh "$FOLDER" | sort STAMP=20261102T013000Z # the stamp of the pair you chose ``` Download both files into `backups/restore/`: ```bash mkdir -p backups/restore docker compose exec -T backup sh -c 'set -e; c=$(mktemp); cp /config/rclone/rclone.conf "$c" for f in "kvitt-$2.sqlite.gz" "pictures-$2.tar.gz"; do RCLONE_CONFIG=$c rclone copy "gdrive:$f" /backups/restore/ --drive-root-folder-id "$1" done; rm -f "$c"' sh "$FOLDER" "$STAMP" ls -l backups/restore ``` (A file downloaded in the browser instead: copy it from the Mac with `scp jacobhagstedt@:kvitt/backups/restore/`.) ## 3. Unpack and check ```bash gunzip -f "backups/restore/kvitt-$STAMP.sqlite.gz" docker compose exec -T backup sqlite3 "/backups/restore/kvitt-$STAMP.sqlite" "PRAGMA integrity_check" ``` It must print `ok`. Anything else: stop here and pick another backup. ## 4. Move the current data aside and put the backup in place ```bash aside="data/pre-restore-$(date -u +%Y%m%dT%H%M%SZ)"; mkdir "$aside" for f in data/kvitt.sqlite data/kvitt.sqlite-wal data/kvitt.sqlite-shm data/pictures; do [ -e "$f" ] && mv "$f" "$aside/" done cp "backups/restore/kvitt-$STAMP.sqlite" data/kvitt.sqlite tar -xzf "backups/restore/pictures-$STAMP.tar.gz" -C data echo "previous data kept in $aside"; ls -l data ``` ## 5. New sync epoch ```bash docker compose run --rm server rotate-epoch ``` It prints the new epoch. The phones see it and re-push their data (§14.4.8). ## 6. Start the server and check health ```bash docker compose start server docker compose ps server # healthy within a minute curl -fsS http://localhost:8080/health ``` The last line prints `{"status":"ok",...}` (the server's own port; the path through Nginx Proxy Manager is unchanged by a restore). ## 7. The phones Open Kvitt on both phones (owner's and partner's) and leave it open for a minute; the next sync detects the new epoch and re-pushes the phone's data (if nothing seems to happen, close the app and open it again). Check that both phones show the same balances on Översikt (yes/no). ## Afterwards When the phones agree, the downloaded files can go: `rm -r backups/restore`. The `data/pre-restore-/` folder stays until you decide otherwise. Run `docker compose exec backup /backup.sh` once to put the restored state on Drive.