Skip to Content
Deploying FudFi

Deploying FudFi

FudFi deploys as three independently hosted pieces:

PieceHostProjectRoot directory
Backend APIRailwayfudfi / service backendrepo root
AppVercelfudfi-nextfrontend
MarketingVercelfudfi-landingmarketing

Backend on Railway

Railway uses the Railpack builder, which builds the repo root as a monorepo and ignores most of railway.json. So the root package.json MUST have a start script and MUST NOT have a build script (otherwise Railpack tries to build the Next.js frontend for the backend and fails).

Root package.json requirements:

  • "start": "npm run start:backend" — exists today.
  • No root build script. Web builds live in frontend/ only.
  • "engines": { "node": ">=20.9.0" } — Next 16 + Railpack’s default Node 18 otherwise.

Deploy:

railway up --service backend

Verify the new code is live:

curl -X POST https://<backend-host>/api/auth/evm/challenge \ -H "Content-Type: application/json" -d '{}' # expect HTTP 400 (validation), not 404

Environment

DATABASE_URL=postgres://... # Railway Postgres proxy — NO ?sslmode= (db/client.js handles TLS) ALLOWED_ORIGINS=https://app.fudfi.com,https://fudfi.com,https://www.fudfi.com,http://localhost:3001 NODE_ENV=production GEMINI_API_KEY=... HF_API_KEY=... TWITTER_CLIENT_ID=... TWITTER_CLIENT_SECRET=... TWITTER_CALLBACK_URL=... CLOUDINARY_CLOUD_NAME=... CLOUDINARY_API_KEY=... CLOUDINARY_API_SECRET=... SOLANA_RPC_URL=https://api.mainnet-beta.solana.com

Redis

The backend supports Redis via REDIS_URL and falls back to an in-memory cache. Production uses a Railway service named Redis, wired on backend as:

REDIS_URL=${{Redis.REDIS_URL}}

Omit REDIS_URL locally; in-memory is fine.

App on Vercel

  • Project fudfi-next (team team_VOLeewSIrAYhkcVM9HBePF3N). Its Root Directory is baked to frontend in project settings.
  • Deploy from the repo root (vercel --prod), never from inside frontend/.
  • Commits must be authored fortunesayspump <fortuneze0@gmail.com>. Any other author gets the deployment blocked (seatBlock TEAM_ACCESS_REQUIRED).
  • The first vercel --prod attempt often says “Not authorized” — just retry; it passes.
  • Custom domain: vercel alias set <deployment-url> app.fudfi.com.
  • SSO protection must stay deploymentType: preview; anything stricter walls app.fudfi.com behind a Vercel login page.

Required env on the project:

NEXT_PUBLIC_API_URL=https://backend-production-03de6.up.railway.app/ NEXT_PUBLIC_REOWN_PROJECT_ID=... NEXT_PUBLIC_EVM_CHAIN=testnet # or mainnet

Docs on Vercel

docs/ is a standalone Nextra app with its own package.json and package-lock.json. It is not part of the root npm workspaces. To host it, create a separate Vercel project with Root Directory = docs (install and build run inside docs/).

cd docs && npm install && npm run build # local verification

Native binaries (the recurring deploy killer)

This repo is developed on Windows but deployed on Linux. npm writes the lockfile for the local platform, so Linux-only native modules go missing remotely. If a deploy fails with Cannot find module '../*.node' or Could not load the "sharp" module, pin the Linux packages in optionalDependencies and regenerate the root lockfile:

  • frontend: lightningcss-linux-x64-gnu, @tailwindcss/oxide-linux-x64-gnu (Tailwind v4), plus @x402/core, @x402/evm, @x402/svm.
  • backend: @img/sharp-linux-x64 (pinned to sharp’s exact version).

After any dependency change:

npm install # at repo root node -e "Object.keys(require('./package-lock.json').packages).filter(p=>/linux-x64/.test(p)).forEach(console.log)" # commit BOTH package.json AND package-lock.json

There is intentionally no frontend/package-lock.json. Do not recreate it — it was stale and confused Next/Vercel. The root lockfile is the only lockfile.