claim/docs/deploy/render.md
Syazwan 2613c9d337 Refocus repository on Claim App and enable Render GitHub deploys.
Remove ProcureFlow/Celery legacy, Cursor rules bundle, and scratch artifacts; add claim API routes, deploy docs with auto-deploy, and a claim-focused README.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-01 19:58:43 +08:00

8.4 KiB

Deploy Claim App on Render

This guide deploys the Claim App (not the old ProcureFlow stack) on Render:

Component Render service type Notes
API Web Service (Docker) FastAPI + LibreOffice for Excel/PDF previews
Frontend Static Site React build
Database MongoDB Atlas External (not on Render)
File storage Cloudflare R2 (recommended) Optional; without R2, uploads are ephemeral

1. Prerequisites

MongoDB Atlas

  1. Create a cluster (free M0 is fine).
  2. Create a database user and password.
  3. Network Access → allow 0.0.0.0/0 (or restrict to Render egress IPs later).
  4. Copy the connection string, for example: mongodb+srv://USER:PASS@cluster.mongodb.net/?retryWrites=true&w=majority
  5. Set database name claim (via DB_NAME=claim).

Google OAuth (if you use Google login)

  1. Google Cloud ConsoleAPIs & ServicesCredentials → OAuth client (Web).
  2. You will add redirect URIs after the API URL is known (step 4).

Without R2, files are stored on the container disk and are lost on redeploy.

  1. Create an R2 bucket.
  2. Create an API token with read/write.
  3. Note: endpoint URL, access key, secret key, bucket name.

See backend/.env.example for variable names.


2. Connect GitHub (auto-deploy on every commit)

Render redeploys when you push to the branch you connected (usually main).

  1. Push this repository to GitHub (for example https://github.com/skysyaz/claim).
  2. Render dashboard → NewBlueprint (or open an existing service → Settings).
  3. Under Build & DeployRepository, connect the GitHub account and select this repo + branch.
  4. Ensure Auto-Deploy is Yes (Blueprint sets autoDeploy: true in render.yaml for claim-api and claim-web).
  5. After each git push to that branch, Render builds and deploys automatically. Set sync: false secrets in the dashboard once; they are not overwritten on deploy.

If the repo was created before Render existed: SettingsBuild & DeployConnect repository → pick GitHub → save → Manual Deploy once to verify, then rely on auto-deploy for later commits.


3. Deploy the API (backend)

Use Docker so LibreOffice is available for mileage/meal/OT PDF previews on Linux.

Option A — Blueprint (fastest)

  1. Repo is on GitHub (step 2 above).
  2. Render dashboard → NewBlueprint.
  3. Connect the repository.
  4. Render reads render.yaml at the repo root.
  5. After the first deploy, open the claim-api service → Environment and set secrets marked sync: false (see table below).
  6. Redeploy the API after env vars are set.

Option B — Manual Web Service

  1. NewWeb Service → connect repo.

  2. Settings:

    • Name: claim-api
    • Region: Singapore (or closest to users)
    • Runtime: Docker
    • Dockerfile path: backend/Dockerfile
    • Docker context: repository root (.)
    • Plan: Free or paid (free tier sleeps after ~15 min idle)
  3. Start command (override default if needed):

    python -m uvicorn server:app --host 0.0.0.0 --port $PORT
    

    Do not use the old start.sh that starts Celery — Claim App does not use Celery.

  4. Health check path: /api/health

  5. Add environment variables (section 4).

  6. Create Web Service → wait for deploy.

  7. Copy the service URL, for example: https://claim-api.onrender.com

Verify API

Open:

https://YOUR-API-HOST/api/health

Expected JSON includes "mongodb": "connected" and "database": "claim".


4. Deploy the frontend (static site)

  1. NewStatic Site → same repo.

  2. Settings:

    • Name: claim-web

    • Root directory: (leave empty — repo root)

    • Build command:

      cd frontend && yarn install --frozen-lockfile && yarn build
      
    • Publish directory: frontend/build

  3. Environment variable (build time):

    Key Value
    REACT_APP_BACKEND_URL https://YOUR-API-HOST (no trailing slash)
  4. Redirects (SPA routing) — add in Render Redirects/Rewrites:

    Source Destination
    /* /index.html

    (Same idea as frontend/public/_redirects for Cloudflare Pages.)

  5. Deploy and copy the static site URL, for example: https://claim-web.onrender.com


5. Environment variables

Set these on the API service (claim-api).

Required

Variable Example Purpose
MONGO_URL mongodb+srv://... MongoDB Atlas connection string
DB_NAME claim Database name (use claim, not claim_test)
JWT_SECRET long random string Session signing (Render can auto-generate)
FRONTEND_URL https://claim-web.onrender.com OAuth redirects + cookies
CORS_ORIGINS https://claim-web.onrender.com Same as frontend URL (comma-separated if multiple)
ADMIN_EMAIL you@company.com Bootstrap admin
ADMIN_PASSWORD strong password Bootstrap admin (change after first login)
ADMIN_NAME Administrator Display name

Google OAuth (production)

Variable Example
GOOGLE_CLIENT_ID from Google Console
GOOGLE_CLIENT_SECRET from Google Console
GOOGLE_REDIRECT_URI https://YOUR-API-HOST/api/auth/google/callback
AUTH_GOOGLE_ONLY true or false

In Google Console, add Authorized redirect URI:

https://YOUR-API-HOST/api/auth/google/callback
Variable Purpose
R2_BUCKET_NAME Bucket name
R2_ENDPOINT_URL https://<account-id>.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID API token
R2_SECRET_ACCESS_KEY API token
R2_KEY_PREFIX claims (optional)

Optional

Variable Notes
ALLOWED_EMAIL_DOMAIN e.g. company.com — empty allows any email
RESEND_API_KEY / RESEND_FROM_EMAIL Email features if enabled

PORT is set automatically by Render — do not hardcode 8002 in production.


6. Wire frontend ↔ API

  1. API: FRONTEND_URL and CORS_ORIGINS = your Static Site URL.
  2. Static Site: REACT_APP_BACKEND_URL = your API URL.
  3. Redeploy both after changing env vars (frontend rebuilds when REACT_APP_* changes).

7. Custom domain (optional)

  1. Render → Static Site → Custom Domains → e.g. claims.yourcompany.com
  2. Render → Web Service → Custom Domains → e.g. api.yourcompany.com
  3. Update FRONTEND_URL, CORS_ORIGINS, REACT_APP_BACKEND_URL, and Google redirect URI to match.

8. Limitations on Render

  • Free tier: API sleeps when idle; first request after sleep can be slow (cold start).
  • PDF previews: Use LibreOffice in Docker (included in backend/Dockerfile). Windows Excel COM is not used on Render.
  • Mileage template: Maximum 12 trip rows per form in the Excel/PDF layout.
  • Uploads: Use R2 in production; local disk is not durable across deploys.
  • No Celery/Redis: The Claim App does not need Redis. Ignore old ProcureFlow docs that mention Celery.

9. Troubleshooting

Problem What to check
Login works locally but not on Render FRONTEND_URL, CORS_ORIGINS, cookie domain, HTTPS on both sides
database: claim_test in health Set DB_NAME=claim on Render; redeploy
Google OAuth redirect error GOOGLE_REDIRECT_URI must exactly match Google Console
PDF preview 503 Docker image includes LibreOffice; check API logs for soffice errors
Attachments missing after redeploy Configure R2 env vars
Frontend calls wrong API Rebuild static site after changing REACT_APP_BACKEND_URL
Health check fails Path must be /api/health, not / only

10. Quick checklist

  • MongoDB Atlas cluster + user + MONGO_URL
  • DB_NAME=claim
  • API deployed (Docker), health OK
  • Static site deployed with REACT_APP_BACKEND_URL
  • FRONTEND_URL + CORS_ORIGINS on API
  • Google OAuth redirect URI (if used)
  • R2 configured (if using attachments)
  • Admin login tested on production URL
  • GitHub connected; auto-deploy enabled on main