Roamarr runs as one Node.js process with a persistent MongrelDB database and attachment directory. This repository contains the application source. It does not contain the production image or compose stack.
- Node.js 24 or newer.
- npm and the checked-in
package-lock.json. - Persistent local storage writable by the Roamarr process.
- A stable
ROAMARR_SECRET. - One Roamarr process for a database. Do not run multiple replicas against the same MongrelDB path.
- HTTPS and a reverse proxy for an internet-facing installation.
Native npm packages may need the platform's standard C/C++ build toolchain
during npm ci.
git clone https://github.com/visorcraft/Roamarr.git
cd Roamarr
npm ci
npm run build
npm startThe production entry point is the build directory generated by
@sveltejs/adapter-node. It listens on PORT, defaulting to 3000.
Maintainer worktrees may include a gitignored compose.local.yml. It
bind-mounts the source, runs Vite with hot reload, and exposes
127.0.0.1:3002. It is not distributed in the public repository and is not a
production deployment template.
Generate the application secret once:
openssl rand -base64 32Store that output in a protected environment file or secret manager:
ROAMARR_SECRET=replace-with-the-generated-value
DATABASE_PATH=/var/lib/roamarr/database
ATTACHMENTS_PATH=/var/lib/roamarr/attachments
EMBEDDINGS_CACHE_PATH=/var/lib/roamarr/models
PORT=3000
ORIGIN=https://travel.example.com
BODY_SIZE_LIMIT=InfinityROAMARR_SECRET must decode to exactly 32 bytes. Roamarr uses it to unlock the
encrypted database and to derive encryption for protected fields and
attachments. Losing or changing it makes existing data unreadable. A backup
does not contain this value.
Optional DATABASE_USER and DATABASE_PASS add MongrelDB credential
authentication. Set both before the database is created, then preserve both
with the secret. Setting only one is invalid. Changing or omitting either later
prevents the database from opening.
| Variable | Required | Default | Purpose |
|---|---|---|---|
ROAMARR_SECRET |
Yes | None | Base64-encoded 32-byte encryption key. |
DATABASE_PATH |
No | ./roamarr-db |
MongrelDB directory or supported database file path. |
DATABASE_USER |
No | None | Optional MongrelDB administrator name. Requires DATABASE_PASS. |
DATABASE_PASS |
No | None | Optional MongrelDB administrator password. Requires DATABASE_USER. |
ATTACHMENTS_PATH |
No | See below | Encrypted receipt attachment directory. |
EMBEDDINGS_CACHE_PATH |
No | roamarr-models beside the database |
Optional semantic-search model cache. |
PORT |
No | 3000 |
Node listen port. |
ORIGIN |
No | None | Exact public origin used for URLs, redirects, cookies, OAuth, and WebAuthn. |
For a directory database, attachments default to
<DATABASE_PATH>/attachments. For a database path ending in .db, .sqlite,
or .kitdb, they default to an attachments directory beside the file. An
explicit relative ATTACHMENTS_PATH is resolved from the process working
directory.
The optional globe texture is stored in a maps directory beside the resolved
database path. It is downloaded through the Maps administration page. The
GeoNames city catalog is stored in the database.
The generated server also supports the standard adapter-node runtime variables:
| Variable | Default | Purpose |
|---|---|---|
SOCKET_PATH |
None | Unix socket path. When set, HOST and PORT are unused. |
HOST |
0.0.0.0 |
Listen address. |
PORT |
3000 |
Listen port. |
ORIGIN |
None | Public origin, also described above. |
BODY_SIZE_LIMIT |
512K |
Maximum request body accepted by adapter-node. |
SHUTDOWN_TIMEOUT |
30 |
Seconds before graceful shutdown closes remaining connections. |
IDLE_TIMEOUT |
0 |
Seconds without requests before shutdown when using socket activation; 0 disables it. |
KEEP_ALIVE_TIMEOUT |
Node.js default | HTTP keep-alive timeout in seconds. |
HEADERS_TIMEOUT |
Node.js default | HTTP header timeout in seconds. |
ADDRESS_HEADER |
None | Trusted proxy header containing the client address. |
XFF_DEPTH |
1 |
Number of trusted entries in X-Forwarded-For when ADDRESS_HEADER is configured. |
PROTOCOL_HEADER |
None | Trusted proxy header containing the original protocol. |
HOST_HEADER |
None | Trusted proxy header containing the original host. |
PORT_HEADER |
None | Trusted proxy header containing the original port. |
LISTEN_PID, LISTEN_FDS |
0 |
Unprefixed systemd socket-activation variables. One socket is supported. |
The adapter default body limit is smaller than Roamarr's supported uploads.
Use a limit of at least 10M for receipt attachments. Browser backup restore
has no Roamarr application size cap by default, so set BODY_SIZE_LIMIT (and
the reverse proxy) to the largest archive you intend to upload, or
Infinity to leave it to disk space. ROAMARR_MAX_RESTORE_BYTES can add an
application cap. Only trust forwarded headers from a proxy you control.
Preserve these paths across every deployment:
| Data | Location |
|---|---|
| MongrelDB data | DATABASE_PATH |
| Encrypted attachments | ATTACHMENTS_PATH or its derived default |
| Optional semantic model | EMBEDDINGS_CACHE_PATH or its derived default |
| Optional globe texture | maps/ beside the database |
Also preserve ROAMARR_SECRET and any database credentials outside the data
volume. The built application, .svelte-kit, node_modules, logs, and local
Playwright output are replaceable and should not be stored with user data.
Give the service account read/write access only to its runtime directories. Protect backups and environment files as secrets.
Set ORIGIN to the exact browser-visible origin, including scheme and any
non-default port:
ORIGIN=https://travel.example.comThe proxy should:
- terminate TLS;
- preserve the request host and protocol;
- pass WebSocket and streaming HTTP traffic without buffering that breaks MCP;
- allow the configured upload limit;
- use timeouts long enough for backup download/restore and map imports;
- forward shutdown signals to the Node process during deploys.
HTTPS is required for passkeys outside loopback development. A wrong ORIGIN
also causes incorrect OAuth discovery, redirect validation, cookies, and
WebAuthn relying-party checks.
Roamarr sends HSTS, CSP, X-Frame-Options: DENY,
X-Content-Type-Options: nosniff, and a restrictive referrer policy.
On process start Roamarr:
- validates
ROAMARR_SECRETand optional database credentials; - applies a validated pending restore, if one exists;
- opens the encrypted MongrelDB database;
- applies schema migrations;
- creates required settings and insurance benefit templates;
- warms semantic search when enabled;
- starts the guarded in-process scheduler.
An invalid or missing secret leaves only setup or boot-error diagnostics available. A migration or database failure stops ordinary application access. Do not start another Roamarr process to work around a failed boot.
Use:
GET /health
GET /health/deep
/health is a lightweight public JSON check of database-path and scheduler
state. /health/deep runs database integrity and read diagnostics and returns
HTTP 503 when unhealthy. The deep check is rate-limited. Use /health for a
frequent container liveness check and /health/deep for a less frequent
readiness or external monitor.
Neither endpoint proves that external SMTP, IMAP, map, weather, parser, or tile services are available. Check those connections from their administration pages.
Before upgrading:
- Download a fresh full backup.
- Verify that
ROAMARR_SECRET,DATABASE_USER, andDATABASE_PASSare recoverable. - Record the running Roamarr version.
- Stop the sole Roamarr process.
Then update and rebuild:
git fetch --tags
git checkout <release-tag>
npm ci
npm run build
npm startMigrations run automatically before the scheduler starts. After startup:
- check
/health/deep; - sign in and inspect Maintenance → Job History;
- open representative trips, attachments, maps, and integrations;
- retain the pre-upgrade backup until the installation has been verified.
Do not run old and new versions simultaneously against the same database.
Database migrations may make a simple code rollback unsafe. The reliable rollback is:
- stop Roamarr;
- install the previous application version;
- restore the backup taken before the upgrade;
- start with the same secret and database credentials;
- verify
/health/deep.
Restoring replaces the current database and attachment directory. Read Backup and restore before doing it.
Use the service manager's normal stop command and allow adapter-node to finish
graceful shutdown. Avoid kill -9 unless the process cannot terminate. The
scheduler is process-local and resumes on the next start. Due reminders are
processed by the next scheduler tick.
Roamarr MCP session IDs are also process-local and last at most one hour. Restarting invalidates active MCP sessions; clients should initialize a new session.
- One process owns the database.
- Stable secret and optional database credentials are stored separately.
- Database, attachments, models, and map assets use persistent storage.
- Service account permissions are narrow.
ORIGINis the exact HTTPS URL.- Proxy and adapter upload limits support required uploads.
/healthand/health/deepare monitored.- Backups are downloaded, protected, and restore-tested.
- Outbound network access matches the enabled integrations.
- Administrators review Job History and Audit Logs after changes.