Sealearn is a split-stack application: the Express API (backend) and the React + Vite client (frontend) are deployed independently. The backend can run on any Node.js 18+ host — Railway, Render, Fly.io, a bare VPS, or a Docker container — while the frontend is optimised for Vercel and ships with aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/DerBasilisk/SEA-ServicioEvaluaconAsistida/llms.txt
Use this file to discover all available pages before exploring further.
vercel.json rewrite rule that ensures React Router works correctly for all client-side routes. This guide walks through both deployments in order, then covers OAuth callback registration, production environment variables, and database seeding.
- Backend
- Frontend (Vercel)
Backend Deployment
Requirements
| Requirement | Minimum version / notes |
|---|---|
| Node.js | 18 LTS or later |
| MongoDB | Atlas M0 free tier or self-hosted 6.x+ |
| Redis | Upstash free tier, Redis Cloud, or self-hosted 6.x+ |
0.0.0.0/0 for managed platforms that do not expose a stable egress IP).rediss:// URL from the connection details page. Upstash’s free tier is sufficient for development and low-traffic production workloads.Set every variable listed in the Environment Variables reference on your hosting platform. The minimum set required for the backend to start and serve all routes in production is:
PORT=8080
MONGODB_URI=mongodb+srv://...
REDIS_URL=rediss://...
JWT_SECRET=<long-random-string>
CLIENT_URL=https://your-app.vercel.app
CLIENT_URL_WWW=https://www.your-app.vercel.app
FRONTEND_URL=https://your-app.vercel.app
BACKEND_API=https://your-api.domain
GROQ_API_KEY_1=gsk_...
GEMINI_API_KEY=AIzaSy...
RESEND_API_KEY=re_...
RESEND_FROM=SEA <noreply@yourdomain.com>
CLOUDINARY_CLOUD_NAME=...
CLOUDINARY_API_KEY=...
CLOUDINARY_API_SECRET=...
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
GOOGLE_CALLBACK_URL=https://your-api.domain/api/auth/google/callback
DISCORD_CLIENT_ID=...
DISCORD_CLIENT_SECRET=...
DISCORD_CALLBACK_URL=https://your-api.domain/api/auth/discord/callback
For local development with automatic restarts on file changes, use the
dev script which runs nodemon:On platforms like Railway or Render, point the start command to
node server.js. The server will connect to MongoDB first and only begin accepting HTTP traffic after the database connection succeeds.Once the server is running, confirm it is accepting requests by calling the health endpoint. A successful response looks like this:
Use this endpoint as your platform’s health-check probe. On Railway, Render, and Fly.io you can configure it under the service health-check settings so the platform automatically restarts unhealthy instances.
Run the subject and shop seed scripts once after the first deploy (or after wiping the database). These scripts connect to
MONGODB_URI and insert the default curriculum data that the frontend expects:Do not run the seed scripts against a production database that already has live user data — they are designed for initial setup and may overwrite existing records.
Set
CLIENT_URL and CLIENT_URL_WWW to your Vercel deployment domain. The CORS middleware in server.js builds its allow-list from these two values plus a dynamic regex that also permits any preview deployment URL matching https://sea-frontend*.vercel.app:// server.js (excerpt — do not edit, shown for reference)
app.use(cors({
origin: [
process.env.CLIENT_URL || "http://localhost:5173",
process.env.CLIENT_URL_WWW || "http://localhost:5173",
/https:\/\/sea-frontend.*\.vercel\.app$/
],
credentials: true,
}));
OAuth Callback URLs
After deploying the backend, register the following callback URLs in each OAuth provider’s developer console. The paths are fixed and must match exactly.- Open the Google Cloud Console → APIs & Services → Credentials.
- Edit your OAuth 2.0 client and add the following to Authorised redirect URIs:
- Set
GOOGLE_CALLBACK_URLon the backend to the same value.
Discord
- Open the Discord Developer Portal → your application → OAuth2.
- Add the following to Redirects:
- Set
DISCORD_CALLBACK_URLon the backend to the same value.