Deploy to Railway
Tevrin runs on Railway as one project with two environments, preview and production. Each has a public web, a private api with a /data volume, and its own Postgres 18. The project is defined as code in .railway/railway.ts. The Railway project and service names keep the internal name aide.
How deploys happen
| Environment | Trigger |
|---|---|
preview |
.github/workflows/deploy.yml runs after green CI on main |
production |
Manual dispatch of the same workflow, with approval |
Each deploy runs the read-only railway config plan (drift fails the deploy) and then the smoke test. You don’t deploy from your machine. These two commands are the ones to run by hand:
railway config plan # read-only diff of Railway vs .railway/railway.ts
bash deploy/scripts/smoke-remote.sh <web-url> # smoke test a deployed environment
One-time human steps
- Create a Railway account on the Hobby plan or higher, and install the Railway CLI (5.49.1 or newer).
- Create the project and the
previewenvironment, then link the folder. - Create one project token per environment. Store each as the
RAILWAY_TOKENsecret of the matching GitHub environment (preview,production). - Create a workspace token and store it as
RAILWAY_API_TOKENin both GitHub environments. It is used only by the drift check. - Set the secrets and optional variables per environment in Railway. Literals and references come from the IaC.
- After an environment’s first deploy, register the first user straight away. The first registered user becomes Admin.
The full procedure, with every command, is in the Railway ops guide below.
Railway reference
The ops docs stay beside the deploy files in the repo.
| Document | Covers |
|---|---|
deploy/railway/README.md |
First-time setup, secrets, the first Admin, the smoke account, GitHub App URLs, backups (Postgres and the /data volume), rollback and costs |
deploy/railway/variables.md |
Every Railway variable per service, and whether it is a literal, a reference or a secret |
The /data volume holds the Data Protection keys that encrypt stored credentials. Back it up with Postgres. Losing it makes those secrets unreadable.
For the variables themselves, see Configuration.