Farther ShoreDocs
Go to Farther Shore
Bring your own backend
Scaffold a backend service
Transport modes
Infrastructure with OpenTofu
Deploy on Railway
Direct HTTPSEmbedded tunnelVerify
Deploy on Render
Deploy on AWS
Deploy on Google Cloud
Metering & verification
Runtime tokens
Storing per-user data
@farthershore/backend
Add a backend
Connect a direct backend
Add a webhook consumer
@farthershore/backend exports
@farthershore/backend/express exports
@farthershore/backend/reflect exports
@farthershore/backend/runtime exports
@farthershore/backend/testing exports
@farthershore/backend/webhooks exports
backend-sdk HTTP contracts
Status
Docs/Connect your application/Deploy on Railway

Deploy on Railway

Run the Node backend on Railway, deliver FS_RUNTIME_TOKEN, and bind its HTTPS origin.

Railway's long-running service model supports either a public direct origin or an embedded outbound tunnel. Start with Scaffold a backend and commit the application before creating the Railway service.

Direct HTTPS

  1. Create a Railway service from the managed business repository.
  2. Set its root directory to the backend folder, for example api/.
  3. Use Node 22 or newer and start the application with its normal production command.
  4. Make the application listen on Railway's PORT.
  5. Generate a Railway public domain and copy its HTTPS URL.

Create the runtime token before the first real request:

bash
farthershore backend tokens create my-business --format json --idempotency-key <persisted-backend-tokens-create-attempt-key>

Add the returned one-time value as Railway variable FS_RUNTIME_TOKEN, then redeploy. Do not make it a frontend/build variable in Farther Shore; this is a secret consumed by the running backend process.

Bind the Railway domain to the production environment:

bash
farthershore backend create my-business \
  --name "Railway API" \
  --slug api \
  --transport direct \
  --origin-url https://your-service.up.railway.app \
  --idempotency-key <persisted-backend-create-attempt-key> \
  --default

By default a branch environment uses the production Railway service. When a branch needs an isolated service, deploy it and create a concrete per-environment override with the same logical slug:

bash
farthershore backend create my-business \
  --name "Railway API" \
  --slug api \
  --env staging \
  --transport direct \
  --idempotency-key <persisted-backend-create-attempt-key> \
  --origin-url https://your-staging-service.up.railway.app

Embedded tunnel

For no public ingress, declare and create a tunnel backend instead:

bash
farthershore backend create my-business \
  --name "Railway Private API" \
  --slug api \
  --transport tunnel \
  --runner embedded \
  --idempotency-key <persisted-backend-create-attempt-key> \
  --default

farthershore backend tokens create my-business \
  --backend <backend-id> \
  --operations gateway_verification,metering,health,tunnel \
  --idempotency-key <persisted-backend-tokens-create-attempt-key> \
  --format json

Set that token as FS_RUNTIME_TOKEN. The application must call await fs.start() after listening locally. Do not generate or bind a public domain for the tunnel path.

Verify

bash
farthershore backend list my-business --format json
farthershore backend tokens list my-business --format json

Call the Farther Shore gateway with a test subscriber key. For direct mode, an unsigned request to the Railway domain should be rejected by strict SDK middleware. Keep Railway health checks on /healthz, mounted before the verifier.

When rotating the token, remember that backend tokens rotate revokes the old token immediately. For planned zero-downtime changes, create a second token, update Railway, wait for every replica to redeploy, and only then revoke the old one. See Runtime tokens.

PreviousInfrastructure with OpenTofuNextDeploy on Render

On this page

Direct HTTPSEmbedded tunnelVerify