OUTRIDER docs
v1.0.0
Live demo Get help
● Ship · One server

Deployment
one server, one disk.

OUTRIDER is a long-running process that writes to its data folder. Host it on one small server with a persistent disk, keep the dashboard on localhost, and put a reverse proxy with HTTPS in front if you want to reach it from a browser.

01What the desk needs from a host

  • One always-on process. A VPS or a home server. Serverless platforms do not fit: the desk loops forever, keeps WebSockets open and stores its console in SQLite on disk.
  • A persistent disk for data/: state, journal, recordings, wallet lists and the console database.
  • Node.js 22+ and outbound internet. Run node src/cli.mjs doctor on the server: some APIs answer differently from data-centre addresses.
  • One instance per data folder. Two desks on the same data/ would write over each other.

02Install on the server

  1. Copy the folderUpload the unzipped package, for example to /opt/outrider, and create config.json (Configuration).
  2. Install exact versions
    cd /opt/outrider
    npm ci
    npm test
    node src/cli.mjs doctor
  3. Set the console secret keyRequired on a server. Generate it once and store it in your process manager's environment, never in git:
    openssl rand -hex 32
    If you skip it, the desk writes one to data/.admin-secret-key. Either way, lose the key and the secrets stored in the console cannot be read.

03Run it as a service

Any process manager works. An example systemd unit (adjust the user, paths and variables; not part of the package):

[Unit]
Description=OUTRIDER desk
After=network-online.target

[Service]
User=outrider
WorkingDirectory=/opt/outrider
Environment=ADMIN_SECRET_KEY=<64 hex characters>
Environment=TELEGRAM_BOT_TOKEN=<token>
Environment=TELEGRAM_CHAT_ID=<chat id>
ExecStart=/usr/bin/npm start
Restart=on-failure
KillSignal=SIGINT
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

On stop the desk finishes its cycle, saves state and closes sockets. Read the first log after starting for the one-time setup code (journalctl -u outrider).

04Create the owner before you open it

The dashboard and console always listen on 127.0.0.1 only. Reach them through an SSH tunnel and create the owner account first:

ssh -L 8790:127.0.0.1:8790 <user>@<server>
# then open http://127.0.0.1:8790/admin on your own computer
Why the tunnel

Until the owner exists, the desk answers only requests whose Host is a loopback address, so a browser coming through a public domain gets 403 create the owner at /admin first on the dashboard. /admin itself stays reachable, and creating the owner needs the one-time setup code printed in the server log. Creating the owner through the tunnel is the simplest path. Consider requiring two-factor for owners and managers right after.

05Reverse proxy with HTTPS

If you want the dashboard on a domain, put a reverse proxy on the same server. Three things matter:

  • Allowed hosts. The desk rejects requests whose Host is not a loopback address with 403 host not allowed (protection against DNS rebinding). List your public domain(s) in DASH_ALLOWED_HOSTS, comma-separated, for example DASH_ALLOWED_HOSTS=desk.example.com. The proxy passes the original Host header.
  • HTTPS. Send X-Forwarded-Proto: https so the session cookie is marked Secure.
  • Streaming. The page uses Server-Sent Events on /api/stream; turn off response buffering.

Add the variable to the service (above) and restart:

Environment=DASH_ALLOWED_HOSTS=desk.example.com

nginx example:

server {
  listen 443 ssl;
  server_name desk.example.com;
  # ssl_certificate … (for example from certbot)
  location / {
    proxy_pass http://127.0.0.1:8790;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_buffering off;
    proxy_read_timeout 1h;
  }
}

Caddy example:

desk.example.com {
  reverse_proxy 127.0.0.1:8790 {
    header_up X-Forwarded-Proto https
    flush_interval -1
  }
}

These proxy files are examples and were not tested for this release (unverified). Caddy passes the original Host header by default. The host rule itself was tested with DASH_ALLOWED_HOSTS=desk.example.com before the owner existed: Host 127.0.0.1 got the dashboard, Host desk.example.com got 403 on the dashboard and 200 on /admin/, and any other Host got 403 on both.

06Backups

WhatWhy
data/journal.jsonl, data/state.jsonYour paper track record and the desk's state. The journal is hash-chained; a restored copy still verifies.
data/admin.sqlite*Console users, settings, history and audit log (SQLite with -wal and -shm files).
ADMIN_SECRET_KEY or data/.admin-secret-keyWithout it, secrets stored in the console cannot be decrypted. Keep it separate from the data backup.
config.jsonYour settings; may contain your RPC key.
data/pump-events/, gecko-trades/, wallet filesRecordings and wallet books. Large; back up if you want to replay later.

The simplest safe copy: stop the service, copy data/ and config.json, start it again.

07A public read-only demo

node scripts/export-demo.mjs demo-site                  # sample paper book only
node scripts/export-demo.mjs demo-site --real data     # plus your real liquidation map, wallets, leaderboard and calls
node scripts/export-demo.mjs demo-site --frame-origin https://your-landing.example   # allow your landing page to embed it

It writes a static site (index.html, demo-shim.js, api-static/*.json, SNAPSHOT.txt and a vercel.json with security headers) that shows the real dashboard page fed from snapshots. The paper book is sample data with the banner; the kill switch answers that it only works on your own desk. Host the folder on any static host.

By default the generated vercel.json lets the demo be framed only by its own site (frame-ancestors 'self'). To show it in an iframe on your landing page, pass that page's origin with --frame-origin (an https:// origin).

Before you publish it

With --real, the copied files contain real wallet addresses and positions from public chains; publish only what you are comfortable showing.

08Updating

  1. Read the changelogCheck Changelog for migration notes.
  2. Stop and back upStop the service and copy data/ and config.json.
  3. Replace the codeCopy the new version over the old folder, keeping data/ and config.json.
  4. Install and check
    npm ci
    npm test
    node src/cli.mjs doctor
    node src/cli.mjs verify
  5. StartStart the service and open the dashboard.