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 doctoron 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
- Copy the folderUpload the unzipped package, for example to
/opt/outrider, and createconfig.json(Configuration). - Install exact versions
cd /opt/outrider npm ci npm test node src/cli.mjs doctor - Set the console secret keyRequired on a server. Generate it once and store it in your process manager's environment, never in git:
If you skip it, the desk writes one toopenssl rand -hex 32data/.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
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) inDASH_ALLOWED_HOSTS, comma-separated, for exampleDASH_ALLOWED_HOSTS=desk.example.com. The proxy passes the original Host header. - HTTPS. Send
X-Forwarded-Proto: httpsso the session cookie is markedSecure. - 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
| What | Why |
|---|---|
data/journal.jsonl, data/state.json | Your 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-key | Without it, secrets stored in the console cannot be decrypted. Keep it separate from the data backup. |
config.json | Your settings; may contain your RPC key. |
data/pump-events/, gecko-trades/, wallet files | Recordings 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).
With --real, the copied files contain real wallet addresses and positions from public chains; publish only what you are comfortable showing.
08Updating
- Read the changelogCheck Changelog for migration notes.
- Stop and back upStop the service and copy
data/andconfig.json. - Replace the codeCopy the new version over the old folder, keeping
data/andconfig.json. - Install and check
npm ci npm test node src/cli.mjs doctor node src/cli.mjs verify - StartStart the service and open the dashboard.