Dolpher

How to manage the database

Dolpher keeps everything in one SQLite database file: accounts, tokens, sessions and the world. This guide covers creating that file and backing it up.

The examples use dolpher.db in the current directory. Run the commands from the repository root, or put a built dolpher binary on your PATH and drop the go run ./cmd/dolpher prefix.

Create a database

go run ./cmd/dolpher db init --db dolpher.db

This prints created dolpher.db (schema version N). Then start the server on the new file:

go run ./cmd/dolpher serve --db dolpher.db

db init is deliberately strict:

serve never creates a database. If the file is missing, it stops with does not exist. When serve opens an older database, it applies any new migrations automatically.

You can also give the path in the environment, as DOLPHER_DB=dolpher.db.

Back up a running server

Use db backup. It reads the live database safely, without stopping the server or blocking players:

go run ./cmd/dolpher db backup --db dolpher.db --to dolpher-2026-10-19.db

This writes a copy to a single file, which includes every change committed so far. It then runs SQLite's integrity check on the copy, and reports an error and deletes the copy if the check fails. Like db init, it refuses to overwrite a file that already exists, and it won't create a missing directory. Put the date and time in the name, so repeated backups don't collide:

go run ./cmd/dolpher db backup --db dolpher.db --to "dolpher-$(date +%Y%m%d-%H%M%S).db"

db backup only reads the database. It doesn't apply migrations, so a backup taken while an older server is running matches that server's schema. It also checks that the file is a Dolpher database before it copies anything.

While the server is running, the database is made up of three files: dolpher.db, dolpher.db-wal and dolpher.db-shm. Recent changes may exist only in the -wal file. Don't copy the files with cp or a file sync tool while the server is running. The copy can be inconsistent and unusable.

If you don't have the dolpher program on hand, the sqlite3 shell also makes a safe copy of a running server's database. It ships with macOS and most Linux distributions:

sqlite3 -readonly dolpher.db "VACUUM INTO 'dolpher-2026-10-19.db'"
sqlite3 dolpher-2026-10-19.db "PRAGMA integrity_check"

The second command should print ok.

Back up a stopped server

db backup works the same way when the server is stopped:

go run ./cmd/dolpher db backup --db dolpher.db --to dolpher-2026-10-19.db

That includes a server that crashed or was killed, which can leave a dolpher.db-wal file with the latest changes in it. db backup folds those changes into the copy.

After a clean shutdown, a plain file copy also works:

  1. Stop the server with Ctrl-C, or send it SIGINT or SIGTERM. Wait for it to log shutting down and exit.

  2. Check that dolpher.db-wal and dolpher.db-shm are gone. A clean shutdown folds the -wal file back into dolpher.db and removes both.

  3. Copy the single file:

    cp dolpher.db dolpher-2026-10-19.db
    

If the -wal file is still there, don't copy just dolpher.db, because the latest changes would be missing. Use db backup instead.

Restore a backup

Stop the server, and move the damaged database and any -wal and -shm files out of the way. Then copy the backup into place and start the server:

cp dolpher-2026-10-19.db dolpher.db
go run ./cmd/dolpher serve --db dolpher.db

You can also start the server directly on the backup file to inspect it. The server writes to whatever file it opens, so use a spare copy for that.

Keep off-line backups

A backup in the same directory, on the same disk or machine, protects you only against small mistakes. It's lost along with the original if the disk fails, the machine is stolen or compromised, ransomware encrypts the disk, or someone runs rm in the wrong place.

Keep at least one recent backup off-line, on a drive or other medium that you disconnect afterwards, or in storage the server can't reach or overwrite. Anything the server, or an attacker on the server, can reach can be destroyed along with the live database.

Some practical rules: