This guide walks you through taking HealtyHelp from a local development clone to a fully running production deployment. The stack is a Vite + React frontend (static files) and an Express + MongoDB backend (Node.js server), which can be hosted independently on any compatible platform.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/JuanSebasSV/healtyhelp/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before deploying, make sure you have accounts and credentials for each external service HealtyHelp depends on:| Service | Purpose | Free tier? |
|---|---|---|
| MongoDB Atlas | Managed database | ✅ M0 cluster |
| Cloudinary | Avatar and image storage | ✅ Free tier |
| Groq | LLaMA AI chatbot API | ✅ Free tier |
| Google Cloud Console | OAuth 2.0 for Google login | ✅ Free |
| Resend | Transactional email (verification, password reset) | ✅ Free tier |
Deployment steps
Vite compiles and bundles the React application into a
client/dist/ directory. This is the folder you will upload to your static host.The
build script is defined in client/package.json as vite build and produces an optimised, minified output with hashed filenames for cache-busting.This single rule tells Netlify (and compatible static hosts) to serve
index.html for every URL, allowing React Router to handle client-side navigation without returning a 404 on page refresh or deep-link.vercel.json with "rewrites": [{ "source": "/(.*)", "destination": "/index.html" }].htaccess with FallbackResource /index.htmltry_files $uri /index.html; in your server blockdist/ folder).client, Build command to npm run build, and Publish directory to client/dist.VITE_API_URL=https://api.your-domain.com/api in Site settings → Environment variables._redirects file is picked up automatically.Point the host at
client/dist/ and set VITE_API_URL as a build-time environment variable. Add the SPA rewrite rule appropriate for that platform (see step 2).The npm
start script in server/package.json is also node server.js, so platforms that auto-detect Node.js will use it automatically.Set
NODE_ENV=production as an environment variable on the host — this tightens the auth rate limiter and hides stack traces from API error responses.Set every variable from the table below in your server host’s environment settings panel (not in a committed
.env file).MONGO_URImongodb+srv://user:pass@cluster0.xxxxx.mongodb.net/healtyhelp?retryWrites=true&w=majorityJWT_SECRET<32+ random characters>JWT_EXPIRE7dPORT5000 (or set by host automatically)FRONTEND_URLhttps://your-app.netlify.appBACKEND_URLhttps://api.your-domain.comGROQ_API_KEYgsk_…NODE_ENVproductionGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETRemember to add
https://api.your-domain.com/api/auth/google/callback to the Authorised redirect URIs list in your Google Cloud OAuth client settings. The callback URL is constructed automatically from BACKEND_URL by server/config/passport.js.CLOUDINARY_CLOUD_NAMECLOUDINARY_API_KEYCLOUDINARY_API_SECRETRESEND_API_KEYEMAIL_FROMHealtyHelp <noreply@your-verified-domain.com>Once the server is running in production and connected to MongoDB, run the
initSuperAdmin script once to create the initial super-admin account.Set these three extra variables temporarily in your environment (remove them after the script completes):
SUPER_ADMIN_NAME="Super Admin"
SUPER_ADMIN_EMAIL="admin@your-domain.com"
SUPER_ADMIN_PASSWORD="ChangeMe123!"
✅ Conectado a MongoDB
✅ Superadmin creado exitosamente
📧 Email: admin@your-domain.com
⚠️ IMPORTANTE: Cambia la contraseña inmediatamente después del primer login
The script is idempotent — if an account with that email already exists it exits without creating a duplicate.
Security checklist
Use a strong JWT_SECRET
Use a strong JWT_SECRET
Generate a cryptographically random secret of at least 32 characters:A weak or guessable
JWT_SECRET lets an attacker forge authentication tokens and impersonate any user, including admins.Set NODE_ENV=production
Set NODE_ENV=production
Setting
NODE_ENV=production on your server host has two important security effects:- Tighter auth rate limit —
/api/auth/logindrops from 200 to 20 requests per 15 minutes, significantly raising the cost of brute-force and credential-stuffing attacks. - Hidden error details — the global error handler suppresses
err.messagefrom API responses, preventing accidental leakage of internal paths, query details, or stack frames.
Lock CORS to your production frontend URL
Lock CORS to your production frontend URL
server/server.js builds the CORS origin array from process.env.FRONTEND_URL. In production, set this to your exact frontend origin (no trailing slash) and nothing else:Helmet security headers (already configured)
Helmet security headers (already configured)
HealtyHelp already calls
app.use(helmet()) near the top of server/server.js. Helmet sets a collection of security-relevant HTTP response headers out of the box, including:Content-Security-PolicyX-Frame-Options: DENYX-Content-Type-Options: nosniffStrict-Transport-Security(HSTS)
helmet() middleware.HPP protection (already configured)
HPP protection (already configured)
app.use(hpp()) is applied in server/server.js to protect against HTTP Parameter Pollution attacks, which attempt to override Express query parameters by supplying duplicate keys. This middleware is already active and requires no extra setup.Never commit .env files
Never commit .env files
Ensure both Use your hosting platform’s secrets/environment panel to inject variables at runtime instead.
server/.env and client/.env are listed in your root .gitignore: