AI-generated Vite/Express/tRPC app deployed to Railway, but managed runtime env variables are missing
ecwoxkr-cmyk
FREEOP

a month ago

Hi everyone,

I’m trying to deploy a full-stack WebDev app generated in Manus to Railway.

The app is a React/Vite + Node/Express + tRPC project.

Railway deployment itself succeeds, but the app does not work correctly because several runtime environment variables from the original Manus runtime are missing.

Project stack:

  • Frontend: React / Vite
  • Backend: Node / Express
  • API: tRPC at /api/trpc
  • OAuth callback: /api/oauth/callback
  • Build command: pnpm build
  • Start command: pnpm start
  • Deployment target: Railway same-origin full-stack Node app

What works:

  • GitHub repository is connected to Railway
  • Build succeeds
  • Deploy succeeds
  • Server starts on Railway

Current Railway log:

OAUTH_SERVER_URL is not configured

The missing variables are:

  • DATABASE_URL
  • OAUTH_SERVER_URL
  • OWNER_OPEN_ID
  • VITE_APP_ID
  • VITE_OAUTH_PORTAL_URL

There are no .env files in the exported GitHub repository or code package:

  • no .env
  • no .env.local
  • no .env.production
  • no .env.example

There is a railway-env.template file, but it only lists required variables and does not contain actual values.

My understanding:

  • The original app was running in a managed Manus WebDev runtime.
  • GitHub export only contains the code.
  • The original runtime database, OAuth configuration, and environment variables were not exported to GitHub.
  • Railway can build and run the code, but it does not have the original managed runtime env values.

The app also already uses Supabase for some core features:

  • Supabase Auth session
  • Supabase direct repositories
  • profiles
  • workers
  • businesses
  • jobs
  • applications
  • deletion requests

The newer core lifecycle features, such as job posting, application, confirmation, and completion, appear to use Supabase direct paths. However, part of the production auth flow still depends on the older Manus OAuth / tRPC auth.me path.

My questions:

  1. In this kind of situation, is there any way on Railway to recover or infer missing managed-runtime environment variables? I assume the answer is no, but I want to confirm.

  2. If the original platform does not expose DATABASE_URL and OAuth-related variables, is the correct Railway approach to replace those dependencies with my own external services?

  3. Would it be better to:

    • keep the app on Manus hosting and use a custom domain,
    • migrate auth to Supabase Auth and remove the Manus OAuth dependency,
    • or create a new Railway MySQL database and try to keep the existing server structure?
  4. For a Vite + Express + tRPC app, is it normal that VITE_* variables must exist during Railway build time, while server-only variables must exist at runtime?

  5. If I move toward Supabase Auth, should I remove the old tRPC auth.me dependency first, or keep the backend running and only replace the frontend auth adapter?

I am not sharing any secrets. I’m mainly looking for architecture advice on the safest production migration path from a managed AI/WebDev runtime to Railway.

Thanks in advance.

$10 Bounty

3 Replies

Railway
BOT

a month ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway • about 1 month ago


a month ago

Hey, I'll do my best to answer your questions!

.1. Railway doesn't inherit and cannot recover env vars from other platforms. You'll need to redefine the env vars on Railway though the service variables tab.

2/3. Regarding the services, you can keep them on Manus or migrate, I'd recommend migration to Railway in order to avoid egress fees and to reduce latency. You can spin up services on Railway like Supabase or MySQL as you need them.

.4. VITE_* variables are build time variables so yes it is required to exist during build time

.5. That's up to you and how your app works, I'm not sure


coxdoj
HOBBY

a month ago

Adding specifically to question 5: I would keep the Express/tRPC backend and migrate its authentication contract in staging before removing auth.me. Changing only the frontend adapter risks leaving the frontend and backend using different identities.

My suggested sequence:

  1. Back up the databases and identify every caller of auth.me, the Manus OAuth callback, and every protected tRPC procedure. Check whether existing records use Manus user IDs or Supabase user IDs; do not assume these are interchangeable.

  2. Make the backend accept and verify the Supabase access token, then derive the authenticated user from verified claims—not a user ID supplied by the browser. tRPC supports placing this identity in request context and checking it in protected procedures. See tRPC authorization and Supabase token verification.

  3. Keep auth.me temporarily as a compatibility endpoint, returning the existing response shape from the verified Supabase identity and your application profile. Preserve role and ownership checks. Migrate its callers incrementally, then retire the endpoint if nothing needs it.

  4. For browser-to-Supabase data access, review Row Level Security policies and test that user A cannot read or modify user B’s records. Never put service-role or secret keys in browser configuration. See Supabase RLS.

  5. Test login, refresh, logout, protected API calls, role restrictions, and existing-record ownership before removing the Manus callback and related configuration.

Creating a new MySQL database alone will not replace Manus OAuth or migrate existing data. Given your existing Supabase integration, consolidating authentication there is a reasonable option, but the remaining database dependencies need a separate inventory.

Also, Vite’s VITE_* values are bundled at build time and exposed to the browser. Rebuild after changing them; keep database credentials and server secrets out of that prefix. See Vite environment variables.

This is an architecture recommendation based on your description; confirming the exact implementation requires inspecting the auth context and database mappings.


coxdoj

Adding specifically to question 5: I would keep the Express/tRPC backend and migrate its authentication contract in staging before removing `auth.me`. Changing only the frontend adapter risks leaving the frontend and backend using different identities. My suggested sequence: 1. Back up the databases and identify every caller of `auth.me`, the Manus OAuth callback, and every protected tRPC procedure. Check whether existing records use Manus user IDs or Supabase user IDs; do not assume these are interchangeable. 2. Make the backend accept and verify the Supabase access token, then derive the authenticated user from verified claims—not a user ID supplied by the browser. tRPC supports placing this identity in request context and checking it in protected procedures. See [tRPC authorization](https://trpc.io/docs/server/authorization) and [Supabase token verification](https://supabase.com/docs/reference/javascript/auth-getclaims). 3. Keep `auth.me` temporarily as a compatibility endpoint, returning the existing response shape from the verified Supabase identity and your application profile. Preserve role and ownership checks. Migrate its callers incrementally, then retire the endpoint if nothing needs it. 4. For browser-to-Supabase data access, review Row Level Security policies and test that user A cannot read or modify user B’s records. Never put service-role or secret keys in browser configuration. See [Supabase RLS](https://supabase.com/docs/guides/database/postgres/row-level-security). 5. Test login, refresh, logout, protected API calls, role restrictions, and existing-record ownership before removing the Manus callback and related configuration. Creating a new MySQL database alone will not replace Manus OAuth or migrate existing data. Given your existing Supabase integration, consolidating authentication there is a reasonable option, but the remaining database dependencies need a separate inventory. Also, Vite’s `VITE_*` values are bundled at build time and exposed to the browser. Rebuild after changing them; keep database credentials and server secrets out of that prefix. See [Vite environment variables](https://vite.dev/guide/env-and-mode). This is an architecture recommendation based on your description; confirming the exact implementation requires inspecting the auth context and database mappings.

ecwoxkr-cmyk
FREEOP

a month ago

Thanks, this is very helpful. I agree that changing only the frontend auth adapter could create identity mismatch issues.

I’ll first inventory all auth.me callers, protected tRPC procedures, and whether existing records use Manus IDs or Supabase user IDs before changing the auth flow.

In my case, the core app data and lifecycle features already use Supabase direct repositories for profiles, jobs, applications, and status updates. The missing environment variables seem to come mainly from the legacy Manus OAuth / MySQL / tRPC path.

So I’m trying to decide whether the safer path is:

  1. keep Manus hosting and use a custom domain for now, or
  2. migrate the backend auth contract to Supabase Auth and then redeploy to Railway.

I’ll avoid creating a new MySQL database until I finish the auth and database dependency inventory.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...