Getting started
Step 1 · ~5 min

Tephra on Railway

Three commands. HTTPS and a web address come included.

You'll need A Railway accountNode.js on your computer
Railway project Service · 1 replica reads + writes You browser + Obsidian Your domain notes.yourname.com Railway edge HTTPS + domain Variables session + setup token Tephra web app + sync API Volume /data · your notes
swipe to see it all → your requests settings it reads where your notes live
  1. 1

    Install the Railway CLI and sign in

    npm i -g @railway/cli && railway login
  2. 2

    Grab Tephra and make a project

    git clone https://github.com/championswimmer/tephra && cd tephra && railway init
  3. 3

    Launch it

    This sets up the server, its disk and its secrets in one go.

    npm run deploy:railway
  4. 4

    Copy your setup token

    You'll paste it once, when you create your login. Your server's web address is on the service page in Railway.

    railway variable list --service tephra --kv | grep BOOTSTRAP
Reference

Environment variables

The steps above already set everything Tephra needs. This is the complete list for a manual install, a different host, or a change later on.

Where they live on Railway

Service → Variables in Railway, or railway variable set NAME=value --service tephra.

railway variable list --service tephra --kv | grep TEPHRA_

The deploy command fills in every value below. TEPHRA_PUBLIC_URL tracks the Railway domain; set it yourself once you attach a custom domain. Do not set PORT — Railway injects it.

Variable When Default What it does
TEPHRA_PUBLIC_URL Always none Browser-visible origin, including the scheme (https://notes.yourname.com). Used for redirects, cookies and MCP OAuth discovery. It must match the address people open.
TEPHRA_SESSION_SECRET Always none Signs and protects browser sessions. Use at least 32 random bytes, for example openssl rand -hex 32. Never reuse the bootstrap token here.
TEPHRA_BOOTSTRAP_TOKEN First boot none One-time proof for creating the first admin account at /setup. Delete it from the environment after that account exists.
HOST Optional 0.0.0.0 in the image HTTP bind address. Leave it at 0.0.0.0 inside a container.
PORT Optional 8080 Single port for the API and the web app. Railway injects its own value, so do not set it there.
NODE_ENV Optional production in the image When set to production, session cookies are marked Secure. The container image already sets it.
TEPHRA_DATABASE_DRIVER Optional sqlite Must be sqlite. Tephra refuses to start with any other value: live storage is disk-only.
TEPHRA_SQLITE_PATH Optional /data/tephra.db in the image SQLite database file. Keep it on the persistent disk, never in the container layer.
TEPHRA_BLOB_DRIVER Optional filesystem Must be filesystem, matching the disk-only profile.
TEPHRA_BLOB_PATH Optional /data/blobs in the image Content-addressed attachment store. Must sit next to the database on the same disk.
TEPHRA_MAX_BLOB_BYTES Optional 104857600 (100 MiB) Largest attachment Tephra accepts. Platform request limits can be lower; raise both or neither.
TEPHRA_WEB_ROOT Optional /app/tephra-server/apps/web/dist in the image Directory of the built web app served by the API process. Only change it for custom builds.

Delete TEPHRA_BOOTSTRAP_TOKEN after your first login. It only exists to create the first admin. Run railway variable delete TEPHRA_BOOTSTRAP_TOKEN --service tephra.

Want every detail, every knob? The full Railway guide is on GitHub.