Deploy to Railway¶
Railway is the simplest all-in-one path: it runs your FastAPI container, a managed PostgreSQL, and the static app + landing from one project, redeploying on every git push.
Outcome: API at api.yourdomain.com, app at app.yourdomain.com, landing at yourdomain.com.
1. Create the project + database¶
- Create a Railway project from your repo — it detects
backend/Dockerfile. - Add a PostgreSQL service (New → Database → PostgreSQL); Railway provisions its connection string.
2. Deploy the backend (API)¶
- In the backend service → Variables, set the FastSvelte env (full list in Configuration):
FS_DB_URL— reference the Postgres service's connection stringFS_ENVIRONMENT=prod,FS_BASE_API_URL=https://api.yourdomain.com,FS_BASE_WEB_URL=https://app.yourdomain.comFS_JWT_SECRET_KEY,FS_CRON_SECRET, plus Stripe/email keys as needed
- Run migrations once against the prod database —
./sqitch.sh prod deploy(with your prod sqitch target pointed atFS_DB_URL), or from a one-off Railway shell. - Under Settings → Networking, add the custom domain
api.yourdomain.com.
3. Deploy the app + landing (static)¶
frontend/ and landing/ are static SvelteKit builds. Add a static service for each that runs npm install && npm run build and serves the build output:
- Set
PUBLIC_API_BASE_URL=https://api.yourdomain.com(and any otherPUBLIC_*) before the build. - Attach
app.yourdomain.comto the frontend andyourdomain.comto the landing.
Prefer Vercel for the static sites? The Vercel steps in Fly.io + Neon + Vercel apply to any backend host.
4. Wire it together¶
- Point DNS for
api,app, and the apex at the Railway domains. - Confirm
FS_BASE_API_URL/FS_BASE_WEB_URLmatch the live URLs so CORS and cookies work (Configuration). - Add the Stripe webhook at
https://api.yourdomain.com/webhooks/stripe(Billing & Subscriptions). - Review the Security checklist before launch.