Repository navigation
Data and backup
Everything is stored in data/ (gitignored), mounted as /app/data in Docker:
-
data/hobbyhoops.db— SQLite (collection, references, accounts, sessions, rate limiting) viabetter-sqlite3 -
data/card-photos/— card front/back images (JPEG / PNG / GIF / WebP as uploaded) -
data/backups/— local database backups (gitignored)
This file and its WAL journals are local and must never be committed. Card photos live next to the database on the same volume — back up data/ as a whole if you want images included.
On first launch, an empty database is created; create the administrator account from the login screen.
The SQLite file is the single source of truth. The database runs in WAL mode (hobbyhoops.db plus optional -wal / -shm sidecar files). Back it up on the host (the production container has no sqlite3 CLI). Keep a local script or cron on the server — it is not versioned in this repository.
Use SQLite’s online backup API (consistent snapshot, safe while the app is running). Do not copy hobbyhoops.db with cp while the application is open; that can produce an incomplete file.
# Prerequisite: sqlite3 (apt install sqlite3)
mkdir -p data/backups
sqlite3 data/hobbyhoops.db ".backup 'data/backups/hobbyhoops-$(date +%Y-%m-%dT%H-%M-%S).db'"
# Optional: delete backups older than 14 days
find data/backups -maxdepth 1 -name 'hobbyhoops-*.db' -mtime +14 -deleteDaily cron example:
0 3 * * * cd /path/to/hobbyhoops && mkdir -p data/backups && sqlite3 data/hobbyhoops.db ".backup 'data/backups/hobbyhoops-$(date +\%Y-\%m-\%dT\%H-\%M-\%S).db'" && find data/backups -maxdepth 1 -name 'hobbyhoops-*.db' -mtime +14 -delete >> /var/log/hobbyhoops-backup.log 2>&1Stop the application first, replace the database file, then delete stale WAL journals. Skipping the last step (or restoring while the app is still running) can corrupt the database (SQLITE_CORRUPT / database disk image is malformed).
Production:
docker compose stop app
cp data/backups/hobbyhoops-YYYY-MM-DDTHH-MM-SS.db data/hobbyhoops.db
rm -f data/hobbyhoops.db-wal data/hobbyhoops.db-shm
docker compose start appLocal development (npm run dev):
# Stop the dev server (Ctrl+C), then:
cp data/backups/hobbyhoops-YYYY-MM-DDTHH-MM-SS.db data/hobbyhoops.db
rm -f data/hobbyhoops.db-wal data/hobbyhoops.db-shm
npm run devIf the database is already corrupted after a bad restore, stop the app and run:
node scripts/recover-sqlite.mjsThis copies readable tables into a fresh file, rebuilds references_state from cards, and recreates the FTS index. The broken file is kept as data/hobbyhoops.db.corrupt-<timestamp>.
CSV export (Admin → CSV import / export) complements the SQLite backup:
- SQLite — full instance (sessions, accounts, wanted, etc.)
- CSV — portability and spreadsheet editing of the collection only
See CSV-import-export. Also SECURITY.md.