---
title: "Railway"
description: "Deploy Fabro to Railway from the Dockerfile, with a persistent Volume for state"
---

<Warning>
  The server interface is in private early access. Contact [bryan@qlty.sh](mailto:bryan@qlty.sh) if you're interested in trying it.
</Warning>

[Railway](https://railway.com) can host the Fabro server directly from this repository's `Dockerfile`. A single deploy button spins up a container, and a Railway Volume keeps your runs, checkpoints, and sessions across redeploys.

## One-click deploy

[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/new/template?template=https%3A%2F%2Fgithub.com%2Ffabro-sh%2Ffabro)

The button launches Railway's new-project flow pointed at this repo, with `railway.toml` telling Railway to build the image from `Dockerfile` and restart on failure.

## First-deploy checklist

The template covers the build; a few pieces still need to be wired up after the first deploy.

### 1. Attach a Volume for `/storage`

Fabro writes all persistent state — run history, checkpoints, sessions, the default token, and JWT keys — under `/storage`. Railway containers have ephemeral filesystems, so without a Volume that directory is wiped on every redeploy.

In the Railway dashboard: **Service → Settings → Volumes → New Volume**, mount path `/storage`. 10 GB is a reasonable starting size; grow as needed.

### 2. Confirm the target port

Railway sets `$PORT` automatically and expects the container to bind to it. The Fabro image honors `$PORT` and falls back to `32276`, and the `Dockerfile` exposes `32276`, so Railway's default HTTP routing works without any manual port configuration.

If you override the port in **Service → Settings → Networking → Target Port**, match the value to `$PORT`.

### 3. Set required environment variables

Add variables in **Service → Variables** as needed. The [Server Configuration](/administration/server-configuration) reference has the full list; the minimum useful set:

| Variable | Purpose |
|---|---|
| `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GEMINI_API_KEY` / ... | At least one LLM provider key for the models you'll run |
| `FABRO_DEV_TOKEN` | Optional — pre-set the dev token instead of reading the one written to `/storage` on first boot |
| `SESSION_SECRET` | 64-character hex string; required when the web UI is enabled |
| `GITHUB_APP_CLIENT_SECRET`, `GITHUB_APP_WEBHOOK_SECRET`, `GITHUB_APP_PRIVATE_KEY` | Only if you enable GitHub OAuth or the GitHub App integration |

No `.env` file is auto-loaded inside the container; everything comes from Railway's environment.

## Accessing your Fabro server

Once the deploy is healthy, Railway exposes a `*.up.railway.app` URL (or your custom domain). Two things to grab:

1. **The dev token** — on first boot, Fabro writes one to `/var/fabro/dev-token` and logs it. Find it in the Railway deploy logs or run `railway run cat /var/fabro/dev-token` from the Railway CLI.
2. **Point your local CLI at the server** — add the Railway URL to `~/.fabro/settings.toml`:

   ```toml title="~/.fabro/settings.toml"
   [server]
   target = "https://<your-service>.up.railway.app/api/v1"
   ```

   Then commands like `fabro model list --server <url>` will hit your Railway instance.

See [Running the Fabro Server](/administration/deploy-server) for the full auth and CLI-pointing story.

## Redeploys and updates

Railway rebuilds the image on every push to the connected branch. The `/storage` Volume survives redeploys, so runs and checkpoints persist. If you change the Dockerfile or add new env vars, redeploy from the Railway dashboard or push a commit.

## Caveats

- **Volume is load-bearing.** Without a Volume mounted at `/storage`, a redeploy silently wipes all state — including the dev token and JWT signing keys. Attach it before submitting any real runs.
- **Single replica.** Fabro's server currently assumes one process owns `/storage`. Don't scale the service to multiple replicas.
- **Build context size.** The `Dockerfile` expects pre-built binaries under `docker-context/`, which are generated by the release workflow. Railway's default source-based build runs from scratch and takes longer than pulling an image. For faster deploys, switch the service to an image-first deploy and point it at the published multi-arch image at `ghcr.io/fabro-sh/fabro` (`:latest`, `:nightly`, or a specific `:<version>` tag).

## Next steps

<Columns cols={2}>
  <Card title="Running the Fabro Server" icon="server" href="/administration/deploy-server">
    Auth, dev tokens, submitting runs, and pointing the CLI at your deployment.
  </Card>
  <Card title="Server Configuration" icon="gear" href="/administration/server-configuration">
    Full `settings.toml` reference — TLS, auth methods, concurrency, and more.
  </Card>
</Columns>
