|
| 1 | +# Deploying SpectraCleanse AI on Render |
| 2 | + |
| 3 | +This is the complete environment-variable reference and setup guide for running |
| 4 | +SpectraCleanse AI on [Render](https://render.com). It explains why Stripe and |
| 5 | +email verification may appear "not working" and exactly how to fix it. |
| 6 | + |
| 7 | +## Why Stripe / email verification aren't working |
| 8 | + |
| 9 | +The server changes behavior based on `NODE_ENV` and which secrets are present: |
| 10 | + |
| 11 | +- **If `NODE_ENV` is NOT `production`** the server enables **mock checkout** |
| 12 | + (Stripe is bypassed and returns a fake success URL — no real charge) and |
| 13 | + **dev-fallback email** (verification/reset emails are only logged, never |
| 14 | + sent). This is almost always the cause of "Stripe and email aren't working." |
| 15 | +- **If `NODE_ENV` is `production` but Stripe vars are missing**, the server |
| 16 | + exits on boot with `FATAL: Stripe is not fully configured in production.` |
| 17 | +- **If SMTP vars are missing in production**, account creation still works but |
| 18 | + verification/reset emails fail to send. |
| 19 | + |
| 20 | +After deploying, open your Render service **Logs** and look for the |
| 21 | +`[Config]` summary printed at startup — it tells you whether Stripe and Email |
| 22 | +are actually live or running in mock/fallback mode. |
| 23 | + |
| 24 | +## Required environment variables |
| 25 | + |
| 26 | +Set these in **Render → your service → Environment**. (If you deploy via the |
| 27 | +included `render.yaml` blueprint, the keys are pre-created and you just fill in |
| 28 | +the secret values.) |
| 29 | + |
| 30 | +### Core |
| 31 | + |
| 32 | +| Variable | Required | Value / Notes | |
| 33 | +|---|---|---| |
| 34 | +| `NODE_ENV` | ✅ | `production` — **this is the single most important one.** Turns off mock checkout and dev-email fallback. | |
| 35 | +| `JWT_SECRET` | ✅ | A long random string. Generate: `node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"` | |
| 36 | +| `FRONTEND_URL` | ✅ | Your public URL, e.g. `https://spectracleanseai.onrender.com`. Used for CORS, Stripe redirect URLs, and email links. | |
| 37 | +| `DB_PATH` | ✅ | `/data/spectra.db` — must point at a **persistent disk** or data is wiped on every deploy. | |
| 38 | +| `PORT` | Auto | Render injects this automatically; the server reads it. Do not hard-code. | |
| 39 | +| `APP_BASE_URL` | Optional | Base URL for email links. Falls back to `FRONTEND_URL`, so usually unnecessary. | |
| 40 | +| `ALLOWED_ORIGINS` | Optional | Comma-separated extra CORS origins. Only needed if the frontend is on a different domain than the API. | |
| 41 | + |
| 42 | +### Stripe — all four required for live checkout |
| 43 | + |
| 44 | +| Variable | Where to find it | |
| 45 | +|---|---| |
| 46 | +| `STRIPE_SECRET_KEY` | Stripe Dashboard → Developers → API keys → Secret key (`sk_live_…`) | |
| 47 | +| `STRIPE_WEBHOOK_SECRET` | Stripe Dashboard → Developers → Webhooks → your endpoint → Signing secret (`whsec_…`) | |
| 48 | +| `STRIPE_CREATOR_PRICE_ID` | Stripe → Products → Creator plan → Price ID (`price_…`) | |
| 49 | +| `STRIPE_STUDIO_PRICE_ID` | Stripe → Products → Studio plan → Price ID (`price_…`) | |
| 50 | + |
| 51 | +If **any** of these four is missing, the server treats Stripe as unconfigured. |
| 52 | + |
| 53 | +### Email / SMTP — all five required to send mail |
| 54 | + |
| 55 | +| Variable | Notes | |
| 56 | +|---|---| |
| 57 | +| `SMTP_HOST` | e.g. `smtp.sendgrid.net`, `smtp.resend.com`, `smtp.gmail.com` | |
| 58 | +| `SMTP_PORT` | `587` (STARTTLS) or `465` (implicit TLS) | |
| 59 | +| `SMTP_USER` | SMTP username (for SendGrid the literal string `apikey`) | |
| 60 | +| `SMTP_PASS` | SMTP password / API key | |
| 61 | +| `SMTP_FROM` | From address, e.g. `SpectraCleanse <no-reply@spectracleanse.com>` | |
| 62 | + |
| 63 | +If **any** of these five is missing, verification/reset emails won't send in production. |
| 64 | + |
| 65 | +### Optional |
| 66 | + |
| 67 | +| Variable | Notes | |
| 68 | +|---|---| |
| 69 | +| `GEMINI_API_KEY` | Only needed for the AI SEO-generation feature. | |
| 70 | +| `VITE_API_URL` | Build-time only. Leave **unset** for the default same-origin deployment. Set it only if you host the frontend separately from the API. | |
| 71 | + |
| 72 | +## Setup steps |
| 73 | + |
| 74 | +1. **Create the service.** Use the included `render.yaml` (New → Blueprint) or |
| 75 | + create a Web Service with **Runtime: Docker** pointing at this repo's |
| 76 | + `Dockerfile`. |
| 77 | +2. **Add a persistent disk** mounted at `/data` (≥1 GB) so the SQLite database |
| 78 | + survives deploys. Set `DB_PATH=/data/spectra.db`. |
| 79 | +3. **Fill in all environment variables** from the tables above. |
| 80 | +4. **Deploy**, then check `https://<your-service>.onrender.com/api/health` → |
| 81 | + `{"status":"ok"}`. |
| 82 | +5. **Configure the Stripe webhook.** In Stripe → Developers → Webhooks, add an |
| 83 | + endpoint at `https://<your-service>.onrender.com/api/stripe-webhook` and |
| 84 | + subscribe to `checkout.session.completed` and `customer.subscription.deleted`. |
| 85 | + Copy its signing secret into `STRIPE_WEBHOOK_SECRET` and redeploy. |
| 86 | +6. **Verify the logs.** The startup `[Config]` lines should show Stripe and |
| 87 | + Email as `configured`. |
| 88 | + |
| 89 | +## Quick checklist |
| 90 | + |
| 91 | +- [ ] `NODE_ENV=production` |
| 92 | +- [ ] `JWT_SECRET` set to a strong random value |
| 93 | +- [ ] `FRONTEND_URL` = your Render URL |
| 94 | +- [ ] Persistent disk at `/data` + `DB_PATH=/data/spectra.db` |
| 95 | +- [ ] All 4 `STRIPE_*` vars set |
| 96 | +- [ ] Stripe webhook endpoint created and `STRIPE_WEBHOOK_SECRET` set |
| 97 | +- [ ] All 5 `SMTP_*` vars set |
| 98 | +- [ ] `/api/health` returns ok and logs show Stripe + Email `configured` |
0 commit comments