Deployment
The app deploys as one Render web service. Express serves both the API and the built React client. The data lives in Supabase (managed Postgres) and the AI runs on Groq.
1. Supabase (database)
- Create a project at supabase.com. The free tier is fine.
- Click Connect in the top bar, then the Session pooler tab, and copy the URI:
postgresql://postgres.<project-ref>:[YOUR-PASSWORD]@aws-0-<region>.pooler.supabase.com:5432/postgres - Replace
[YOUR-PASSWORD]with the database password you chose when you created the project. That’s not your Supabase login. Reset it under Project Settings → Database if needed. - Use the result as
DATABASE_URL.
What you don’t need: the project URL, the publishable/anon key, or the service-role key. The server talks to Postgres directly.
- Why the Session pooler? The direct connection host is IPv6-only, and Render (like many hosts) connects over IPv4.
- TLS is verified against Supabase’s root CA, which is bundled in the repo.
- Tables (
users,interviews) are created on first start, with Row Level Security enabled and no policies. Supabase’s public REST API therefore can’t read them, while the server (the table owner) can.
The app doesn’t use Supabase’s REST Data API at all. You can turn it off under Project Settings → Data API to shrink the exposed surface further.
2. Groq (AI and voice)
- Create an API key at console.groq.com/keys. This is
GROQ_API_KEY. - Accept the Orpheus terms once at the Orpheus playground so the interviewer can speak with Groq’s voice.
See Configuration → Groq free-tier limits for what the free tier covers.
3. Render
Option A: Blueprint (recommended)
The repo contains a render.yaml.
- In the Render dashboard, click New + → Blueprint and pick this repository.
- Render asks for the values marked
sync: false:DATABASE_URL: your Supabase Session pooler URIGROQ_API_KEYGOOGLE_CLIENT_IDandVITE_GOOGLE_CLIENT_ID: optional, and set to the same value
- Set
FRONTEND_URLinrender.yaml(or in the dashboard) to your service URL.
JWT_SECRET is generated automatically.
Option B: Manual web service
| Setting | Value |
|---|---|
| Runtime | Node |
| Build command | npm install && cd server && npm install && cd ../client && npm install && npm run build |
| Start command | node server/index.js |
| Health check path | /api/health |
Environment variables: NODE_ENV=production, FRONTEND_URL, DATABASE_URL, JWT_SECRET, JWT_EXPIRES_IN=7d, AI_PROVIDER=groq, GROQ_API_KEY, TTS_PROVIDER=groq, and optionally the Google client IDs. See Configuration.
4. Verify
https://<your-service>.onrender.com/api/healthreturns{"success":true,...}.- Register, run a short interview, and check that it appears on the dashboard.
- In Supabase’s Table Editor, the
usersandinterviewstables show the new rows.
Google sign-in (optional)
- In Google Cloud Console, create an OAuth client ID of type Web application.
- Under Authorized JavaScript origins, add every origin you’ll use:
http://localhost:5173and your Render URL. - Set
GOOGLE_CLIENT_ID(server) andVITE_GOOGLE_CLIENT_ID(client build) to that ID.
Signing in with Google links to an existing account with the same email. Because Google has verified the email, any password previously set on that account is removed, so only the verified owner can sign in.