Install on Railway
On Railway, an instance is one service built from the repository's Dockerfile, with one volume mounted at /data, its configuration in Railway variables and sign-in through a GitHub OAuth App.
1. The service
- Create a project and an empty service. Do not connect a repository, or connect it and disable automatic deployments: you deploy a verified build (step 5).
- Add one volume to the service, mounted at
/data. - Generate a domain or attach your own. Its
https://origin is your public URL.
2. Variables
| Variable | Value |
|---|---|
RAILWAY_DOCKERFILE_PATH | deploy/docker/Dockerfile |
RAILWAY_RUN_UID | 0 — the entrypoint gives /data to the gateway's user and drops root |
VAUBAAN_PUBLIC_URL | https://your-domain |
VAUBAAN_STORE_PATH | /data/gateway.db |
VAUBAAN_MASTER_KEY | the output of npm run gen-master-key; keep a copy outside Railway |
VAUBAAN_ADMIN_EMAILS | your address, as GitHub has it as your primary verified email |
VAUBAAN_SIGN_IN_GITHUB_KIND | github |
VAUBAAN_SIGN_IN_GITHUB_CLIENT_ID | from step 3 |
VAUBAAN_SIGN_IN_GITHUB_CLIENT_SECRET | from step 3 |
VAUBAAN_SIGN_IN_GITHUB_INVITATION_ONLY | true (or VAUBAAN_SIGN_IN_GITHUB_ALLOWED_EMAIL_DOMAINS) |
Railway sets PORT; do not set it. With a sign-in provider in the configuration no bootstrap token is needed.
- Leave
VAUBAAN_TRUSTED_PROXIESunset. Railway publishes no address range for its edge, so there is nothing safe to declare; the per-address limits are then one shared window and the activity records no address (accepted risk A2 of the threat model). Never set0.0.0.0/0. VAUBAAN_CLIENT_IP_HEADER=x-real-iponly after you verified it on your instance: the procedure is in the Railway guide.- The instance's own project is never a mission resource. The gateway reads
RAILWAY_PROJECT_IDand refuses that project to every mission; on an account that can see it, Railway's agent tool is unavailable. Still prefer a separate Railway workspace for the gateway, and never connect that workspace's token to the gateway itself.
3. The GitHub OAuth App
At GitHub, in the settings of your organisation or account: Developer settings → OAuth Apps → New OAuth App.
- Homepage URL: your public URL.
- Authorization callback URL:
https://your-domain/auth/callback/github. - Leave device flow off. Generate a client secret; copy the client id and the secret into the variables of step 2.
This app only signs people in. The GitHub App through which missions reach your repositories is created later from the interface: Settings → Administration → Company apps → GitHub (Connect GitHub).
4. Who may sign in
GitHub is open to anyone: the gateway refuses to start with a GitHub provider that has neither allowed domains nor invitation only. With invitation only, the addresses of VAUBAAN_ADMIN_EMAILS are admitted and are administrators; everybody else needs an invitation (Settings → People → Invite). A person is admitted on the primary, verified address of their GitHub account only.
5. Deploy a verified build
Deploy the commit that passed the checks, from a clean archive of it — never railway up from your working copy, which uploads the directory you are in:
git checkout <the verified commit>
npm ci && npm run ci && npm run test:e2e
npm run docker:build && npm run docker:smoke
git archive --format=tar HEAD | (rm -rf /tmp/vaubaan-release && mkdir /tmp/vaubaan-release && tar -x -C /tmp/vaubaan-release)
cd /tmp/vaubaan-release && railway link && railway up --ci
Then open https://your-domain/healthz (it answers the version and the commit) and sign in.
6. Backups
Use Railway's volume backups, or make a consistent copy while the gateway runs (backup and restore). Keep the master key separately, outside Railway: a copy of the volume opens no credential without it.
The whole guide, with the git remote's limits behind Railway's edge and the master key rotation on Railway: deploy/railway.md.