Run from source
Requirements
- Node 22.18 or newer, 24, or 26 with npm. Linux, macOS or Windows.
- Build tools for native modules on a bare system (Python 3 and a C++ compiler); most distributions have them, and prebuilt binaries cover common platforms.
- About 2 GB of disk for the app, its dependencies, the content pack and the embedding model.
Quick start
Clone the repository, or download the release archive to track a fixed version, then:
cd open-dungeon-master
npm install
npm run setup # database key, content pack, memory model, production build
npm run start:lan # 0.0.0.0:3005, reachable by your party on the LANWhen it starts, the server prints a link with a one-time setup code. Open it on the same computer and create the first account, which becomes the administrator; the guided setup then takes it one question at a time. It looks for llama.cpp, Ollama, LM Studio, vLLM, KoboldCpp, TabbyAPI and Jan on the machine and lists their models, or takes an API key, an agent program or a person at the table; then pictures and voice, players, and your own agent over MCP, testing each choice as a campaign would. Run it again any time from Admin, Guided setup.
npm run setup is safe to run again: it keeps an existing key, content pack and model, and refuses to make a new key for a database that already exists. npm run setup -- --no-build skips the build for npm run dev:lan. By hand, the same steps are:
# The database is encrypted at rest. Generate a key once and keep it safe.
echo "DB_ENCRYPTION_KEY=$(openssl rand -hex 32)" > .env.server
# The content pack: spells, feats, items, subclasses, monsters.
node scripts/import-open5e.mjs
# The local embedding model (about 86 MB) for story recall and lore search.
npm run fetch-model
npm run buildFor development, npm run dev serves http://localhost:3000 and npm run dev:lan serves 0.0.0.0:3005.
The content pack
The import script builds a read-only database from Open5e with retries, caching the raw pages under data/content/raw/ so later runs need no network; --refresh re-downloads. Every server release also attaches the prebuilt pack as open5e.sqlite.gz: unpack it and point CONTENT_DB_PATH at the file to skip the import. Without a pack the app boots on the much smaller bundled SRD and says so in the character builder.
Secrets and settings
Secrets belong in .env.server: the encryption key, API keys, Discord credentials. The file is read by the server itself, not by Next.js, and is ignored by git. Non-secret settings can live there too, or in the admin panel, which wins. Copy .env.example for the full list with comments. See Settings and admin.
Optional services
Each is a separate program on the same machine or another one, pointed at by a URL. All of them are optional and the server runs without them:
- A text backend: llama.cpp on
:8001, Ollama on:11434, LM Studio, vLLM, or a remote key. Local models. - ComfyUI on
:8188for pictures. Art, narration and speech. - Kokoro on
:8880, or any OpenAI-compatible speech server, for narration; faster-whisper on:8870, or the built-in Whisper installed from Admin, Speech, for push-to-talk and dictation. - The sound library ships in
public/ambience;npm run fetch-ambiencecurates more.
Keeping it running
Run npm run start:lan under your init system. A minimal systemd unit:
[Unit]
Description=Open Dungeon Master
After=network.target
[Service]
WorkingDirectory=/opt/open-dungeon-master
ExecStart=/usr/bin/npm run start:lan
Restart=on-failure
User=odm
[Install]
WantedBy=multi-user.targetThe server reads .env.server from its working directory. Put the web port behind HTTPS for anyone outside the LAN: Reverse proxy and HTTPS.
Updating
git pull # or unpack the newer release archive over the old one
npm install
npm run build
# restart the serviceSchema changes apply on start. Take a backup first: Backups and restore.
Migrating an unencrypted database
A database from before encryption is migrated in place: stop the server, set the key in .env.server, run node scripts/migrate-encrypt-db.mjs. The original is kept as *.pre-encryption.bak.