Node.js/Express gateway and UI for the CPP application. Serves HTML/HTMX pages, manages sessions (stored in Neon Postgres), and proxies API calls to the Flask backend.
- Node.js 18+
- Flask backend on Railway (or local)
- Neon Postgres (sessions + shared with Flask)
- SMTP credentials (student email login codes)
-
Install dependencies:
npm install npm run build:css
-
Configure environment:
copy .env.example .env # Windows cp .env.example .env # macOS/Linux
-
Start Flask backend first, then the web app:
npm run dev
Open
http://localhost:3001
Use Render for this repo and Railway for cpp-backend. Deploy the backend first.
- Flask API live on Railway with a public URL, e.g.
https://cpp-backend-production.up.railway.app - Backend health check passes:
curl https://YOUR-BACKEND.up.railway.app/api/v1/health
- Push this repo to GitHub (
Lanoiracali/cpp-student-record). - dashboard.render.com → New → Blueprint → connect the repo.
- Render reads
render.yamland creates the web service. - In the Render dashboard, set secrets Render could not fill:
FLASK_BACKEND_URL→https://YOUR-BACKEND.up.railway.appDATABASE_URL→ Neon connection string (same as backend)SMTP_USER/SMTP_PASS→ Gmail App PasswordSESSION_SECRET→ auto-generated by blueprint, or set your own
- Deploy → open
https://cpp-student-record.onrender.com(or your assigned URL).
-
New → Web Service → connect
cpp-student-record. -
Settings:
- Runtime: Node
- Build:
npm install && npm run build:css - Start:
npm start - Health check path:
/health
-
Environment variables:
Variable Value NODE_ENVproductionFLASK_BACKEND_URLhttps://YOUR-BACKEND.up.railway.appDATABASE_URLNeon connection string SESSION_SECRETopenssl rand -hex 32SMTP_HOSTsmtp.gmail.comSMTP_PORT587SMTP_SECUREfalseSMTP_USERyour email SMTP_PASSGmail App Password -
Deploy and verify:
curl https://YOUR-APP.onrender.com/health
# Set production values in .env first, then:
npm run check:deployYou can run both services on Railway instead of Render. See railway.json and the DEPLOY.md guide in the parent folder.
Browser → Render (cpp-student-record) → Railway (cpp-backend) → Neon Postgres
Express + sessions Flask API
- Users visit the Render URL only.
FLASK_BACKEND_URLis server-side (not exposed to the browser).- Sessions persist in Neon (
express_sessionstable).
| Variable | Required | Description |
|---|---|---|
PORT |
Auto | Set by Render |
NODE_ENV |
Prod | production |
FLASK_BACKEND_URL |
Yes | Railway backend HTTPS URL |
DATABASE_URL |
Yes | Neon Postgres |
SESSION_SECRET |
Yes (prod) | Session signing key |
SMTP_* |
For email login | Nodemailer |
SESSION_SECRETmust be set in production or the app exits on startup.- Cookies use
secure: truewhenNODE_ENV=production(Render provides HTTPS). - Free tier may spin down after inactivity — first request can be slow (~30s).
- Pick a Render region close to Neon (
ap-southeast) if available. - Do not commit
.env.
- Express gateway, HTMX partials, Tailwind CSS
- Teacher/student auth via Flask API
- Nodemailer for student temporary login codes
- Postgres-backed sessions