git / moonbite-network / deploy/PERSISTENCE.md · raw
# Persistent storageA container's filesystem is discarded on every redeploy. Without a mountedvolume, MoonBite's durable state goes with it:| File | What is lost ||-----------------------|-------------------------------------------------|| `chain.db` | Every block. The chain restarts at height 0 and every balance goes to zero. || `wall.db` | Every certificate on `/wall`. || `wallet_history.db` | Transaction history, address books, preferences. |The chain is the one that matters. A coin whose entire history is deleted byits own deploy is not a coin.## What the application expectsOne directory. Everything durable lives in it, resolved in this order:1. `MOONBITE_DATA_DIR` if set.2. `/data` if that directory exists — the conventional mount point.3. Otherwise the application directory, which is the local-development case.So on a host where a volume is mounted at `/data`, there is nothing toconfigure: the files land on the volume by themselves. Chain persistence alsoswitches on automatically when a volume is detected, and stays off locally sotests and development still get a clean in-memory chain.## Railway1. Open the service, then **Settings → Volumes → Add Volume**.2. Set the mount path to **`/data`**.3. Size it for the chain. Blocks accumulate and are never pruned: at ~1 KB per block and 144 blocks a day, a year is roughly 50 MB. 1 GB is ample and leaves room for the wall and wallet history.4. Redeploy. `/data` now exists, so the app uses it with no further settings.To confirm it took, check the deploy logs after a restart:```Replayed N persisted block(s); height=N```That line only appears when blocks were loaded from disk. If the height is 0after a redeploy that had mined blocks, the volume is not mounted where the appis looking.## The moonbite.org dropletIt is set up already, and deliberately not at /data: MOONBITE_DATA_DIR=/var/lib/moonbite-dashboardset through a systemd drop-in at/etc/systemd/system/moonbite-dashboard.service.d/persistence.conf, created bydeploy/setup-persistence.sh.Do **not** point it at /var/lib/moonbite. That is moonbited's datadir, owned bya different user, and putting the dashboard's databases there means chowning atree the Core daemon needs — it keeps running on open handles and fails on itsnext restart, which is a fault that appears hours later with no obvious cause.Keeping the databases outside /opt/moonbite-dashboard also means a deploycannot take them with it: the cutover swaps that directory wholesale.## Other hostsMount any persistent disk and point the app at it:```bashMOONBITE_DATA_DIR=/var/lib/moonbite```The directory is created if missing. Individual files can still be redirectedwith `MOONBITE_CHAIN_DB`, `MOONBITE_WALL_DB` and`MOONBITE_WALLET_HISTORY_DB`, which override the data directory — useful forputting the chain on a different disk from everything else.## BackupsA volume protects against redeploys, not against deletion or corruption. Thedatabases are ordinary SQLite files, so the standard tooling works:```bashsqlite3 /data/chain.db ".backup '/data/backup/chain-$(date +%F).db'"```Use `.backup` rather than copying the file: these run in WAL mode, and aplain `cp` of a live database can capture a torn write.## Migrating existing dataDatabases used to be committed to git, so a deployment may already hold datawritten before this change. Copy it onto the volume once, before the firstdeploy that uses it:```bashrailway run cp wall.db wallet_history.db /data/```Afterwards the copies beside the code are ignored — the app reads only thevolume.