Cloud Run Deployment¶
Deploy Beyond Retrieval v2 as two serverless containers on Google Cloud Run. The backend (FastAPI) and frontend (React + nginx) scale independently, connect to your Supabase cloud project, and cost nothing when idle.
Architecture¶
Internet
|
+-----------+-----------+
| |
Cloud Run (frontend) Cloud Run (backend)
React + nginx FastAPI
*.run.app *.run.app
| |
| nginx proxies |
| /api/* ---------->|
| |
| +-------+-------+
| | Supabase.co |
| | (Database, |
| | Auth, |
| | Storage) |
+ +---------------+
- Frontend serves the React SPA and proxies
/api/*requests to the backend - Backend handles all API logic, connects to Supabase for data/auth/storage
- Supabase is fully managed — no database containers to run
- Both services auto-scale from 0 to N instances based on traffic
Prerequisites¶
Before you start, you need:
| Requirement | How to get it |
|---|---|
| Google Cloud account | cloud.google.com (free tier available) |
| gcloud CLI | Install guide |
| Docker | Docker Desktop or Docker Engine |
| Supabase project | supabase.com (free tier works) |
| OpenRouter API key | openrouter.ai (for LLM inference) |
Step 1: Set Up Your Supabase Project¶
If you're cloning this repo for the first time, you need your own Supabase project with the database schema.
Create a Supabase project¶
- Go to supabase.com/dashboard
- Click New Project
- Choose a name, region, and password
- Wait for provisioning (~2 minutes)
Apply the database schema¶
- Open SQL Editor in your Supabase dashboard
- Copy the contents of
migration.sqlfrom the repo root - Paste and click Run
This creates all tables, functions, extensions (vector, pg_trgm, pg_net), and RLS policies.
Grab your credentials¶
From your Supabase project dashboard (Settings > API):
- Project URL — e.g.
https://abcdefgh.supabase.co - Service Role Key — the
service_rolekey (NOT theanonkey) - Anon Key — needed if you want frontend auth
Step 2: Set Environment Variables¶
Export the required variables in your terminal:
# Required — your GCP project
export GCP_PROJECT_ID=my-gcp-project-id
# Required — your Supabase credentials
export SUPABASE_URL=https://your-project.supabase.co
export SUPABASE_SECRET_KEY=eyJhbGciOiJIUzI1NiIs...your-service-role-key
# Required — LLM provider
export OPENROUTER_API_KEY=sk-or-v1-your-openrouter-key
Optional variables¶
# GCP region (default: europe-west3)
export GCP_REGION=us-central1
# Auth bypass (default: false). Set true for testing without auth
export BYPASS_AUTH=true
# Supabase auth for the frontend (needed if BYPASS_AUTH=false)
export VITE_SUPABASE_URL=https://your-project.supabase.co
export VITE_SUPABASE_ANON_KEY=your-anon-key
# OCR support (optional)
export MISTRAL_API_KEY=your-mistral-key
# Reranking (optional)
export COHERE_API_KEY=your-cohere-key
Step 3: One-Time GCP Setup¶
Run the setup command to enable APIs and create the container registry:
This does three things:
- Enables Cloud Run, Artifact Registry, and Cloud Build APIs
- Creates a Docker repository in Artifact Registry
- Configures Docker authentication for pushing images
You only need to run this once per GCP project.
Step 4: Deploy¶
This builds and deploys both services:
- Backend — builds
backend/Dockerfile.cloudrun, pushes to Artifact Registry, deploys to Cloud Run - Frontend — builds
frontend/Dockerfile.cloudrun(multi-stage: React build + nginx), pushes, deploys - CORS — automatically restricts the backend to only accept requests from the frontend URL
When done, you'll see:
[OK] Deployment complete!
Backend: https://beyond-retrieval-backend-xxxxx-ey.a.run.app
Frontend: https://beyond-retrieval-frontend-xxxxx-ey.a.run.app
Verify: curl https://beyond-retrieval-backend-xxxxx-ey.a.run.app/api/health
Deploy individual services¶
./cloudrun-deploy.sh deploy-backend # Backend only
./cloudrun-deploy.sh deploy-frontend # Frontend only
Step 5: Verify¶
# Health check
curl $(cat .backend-url)/api/health
# Tail logs
./cloudrun-deploy.sh logs backend
./cloudrun-deploy.sh logs frontend
Open the frontend URL in your browser. Create a notebook, upload a document, and test the RAG chat.
What Someone Cloning This Repo Needs to Change¶
Nothing in the code. The entire project is configured via environment variables. Here is exactly what a new user needs:
Must have (3 things)¶
| What | Where to get it | Env var |
|---|---|---|
| Google Cloud project | console.cloud.google.com | GCP_PROJECT_ID |
| Supabase project | supabase.com — run migration.sql | SUPABASE_URL + SUPABASE_SECRET_KEY |
| OpenRouter API key | openrouter.ai/keys | OPENROUTER_API_KEY |
Nice to have¶
| What | Purpose | Env var |
|---|---|---|
| GCP region | Deploy closer to your users | GCP_REGION |
| Supabase anon key | Frontend auth (email/password login) | VITE_SUPABASE_URL + VITE_SUPABASE_ANON_KEY |
| Mistral API key | PDF/document OCR parsing | MISTRAL_API_KEY |
| Cohere API key | Search result reranking | COHERE_API_KEY |
Quick start for a new clone¶
# 1. Clone the repo
git clone https://github.com/your-org/beyond-retrieval.git
cd beyond-retrieval/beyond-retrieval-pythonv
# 2. Set your credentials
export GCP_PROJECT_ID=my-project
export SUPABASE_URL=https://my-project.supabase.co
export SUPABASE_SECRET_KEY=eyJhbG...
export OPENROUTER_API_KEY=sk-or-v1-...
export BYPASS_AUTH=true
# 3. One-time setup
./cloudrun-deploy.sh setup
# 4. Deploy
./cloudrun-deploy.sh deploy
That's it. Zero code changes needed.
Cloud Run Service Specs¶
The deploy script configures these defaults:
| Setting | Backend | Frontend |
|---|---|---|
| Memory | 2 GiB | 256 MiB |
| CPU | 2 | 1 |
| Min instances | 0 (scales to zero) | 0 |
| Max instances | 10 | 5 |
| Concurrency | 80 req/instance | 250 req/instance |
| Timeout | 300s | 300s |
| Port | 8080 | 8080 |
Both services scale to zero when idle, so you only pay for actual usage.
CI/CD with Cloud Build¶
Generate a cloudbuild.yaml for automated deployments on push:
This creates a Cloud Build config that:
- Builds backend and frontend images (tagged with commit SHA +
latest) - Pushes both to Artifact Registry
- Deploys both to Cloud Run
Set up a Cloud Build trigger in the GCP Console to run on push to main.
Secret management
Store SUPABASE_SECRET_KEY and OPENROUTER_API_KEY in Secret Manager and reference them in your Cloud Build config rather than hardcoding.
Custom Domain¶
Cloud Run services get a *.run.app URL by default. To use your own domain:
- Go to Cloud Run > your service > Integrations (or Domain Mappings)
- Click Add Custom Domain
- Verify domain ownership
- Add the DNS records shown (CNAME or A records)
- Wait for SSL provisioning (~15 minutes)
You can map separate domains for frontend and backend, or put both behind a load balancer.
Comparison: Cloud Run vs. Docker Compose (VPS)¶
| Cloud Run | Docker Compose (VPS) | |
|---|---|---|
| Infrastructure | Fully managed, serverless | You manage the server |
| Scaling | Auto (0 to N instances) | Manual (fixed resources) |
| Cost | Pay per request (free tier available) | Fixed monthly VPS cost |
| HTTPS | Automatic on *.run.app | Caddy auto-HTTPS (needs domain) |
| Database | Supabase cloud only | Cloud or self-hosted Supabase |
| Ollama (local LLM) | Not available | Available with GPU support |
| Docling (document parser) | Not available | Available as sidecar |
| Cold starts | ~2-5s on first request | None (always running) |
| Best for | Production SaaS, low/variable traffic | Self-hosted, GPU workloads, privacy |
Troubleshooting¶
| Problem | Fix |
|---|---|
gcloud: command not found | Install the gcloud CLI |
GCP_PROJECT_ID: unbound variable | export GCP_PROJECT_ID=your-project-id |
| Backend deploy fails with auth error | Run gcloud auth login and gcloud auth configure-docker |
| Frontend shows "Failed to fetch" | Check that BACKEND_URL is set correctly and backend is deployed |
| CORS errors in browser console | Redeploy frontend to update CORS: ./cloudrun-deploy.sh deploy-frontend |
| Health check returns error | Check env vars: gcloud run services describe beyond-retrieval-backend --region your-region |
| Cold start timeouts | Increase min instances: gcloud run services update beyond-retrieval-backend --min-instances 1 |
migration.sql fails | Check Supabase SQL Editor for error details — likely a missing extension |
CLI Reference¶
./cloudrun-deploy.sh setup # One-time: enable APIs, create registry
./cloudrun-deploy.sh deploy # Build + deploy both services
./cloudrun-deploy.sh deploy-backend # Deploy backend only
./cloudrun-deploy.sh deploy-frontend # Deploy frontend only
./cloudrun-deploy.sh logs backend # Tail backend logs
./cloudrun-deploy.sh logs frontend # Tail frontend logs
./cloudrun-deploy.sh cloudbuild # Generate cloudbuild.yaml for CI/CD