Spaces:
Runtime error
Deploying the Multi-Agent RAG Web App
This app is a single FastAPI process that serves both the API and the frontend. Everything ships as one Docker image, so it runs the same way on any platform.
What's in the image
- Python 3.12 + all deps from
backend/requirements.txt - The embedding model (
sentence-transformers/all-mpnet-base-v2) pre-baked - Your
data/source/files (re-indexed on first boot) - The static frontend under
/
Persistent state lives in a single directory: /home/user/app/data/chroma
— mount a volume there so the vector DB survives redeploys. (The path is
baked into the image by the Dockerfile; override it with the
CHROMA_DB_PATH env var if you prefer a different mount point.)
Required runtime secrets
| Env var | Required | Notes |
|---|---|---|
GROQ_API_KEY |
yes | gsk_... from https://console.groq.com/keys |
GROQ_MODEL |
no | defaults to openai/gpt-oss-120b |
CORS_ORIGINS |
no | comma-separated origins; * for open |
CHROMA_DB_PATH |
no | image default: /home/user/app/data/chroma |
Minimum recommended VM: 1 GB RAM, 1 vCPU. The embedding model alone is ~420 MB resident.
Option 1 — Local / any VPS with Docker Compose
Simplest path. Works on a $4 DigitalOcean droplet, Hetzner, EC2, your Pi, etc.
# 1. On the server
git clone <your-repo> && cd Langchain
cp .env.example .env
# edit .env and set GROQ_API_KEY=gsk_...
# 2. Build + run
docker compose up -d --build
# 3. First-time: ingest the Dell docs into Chroma
curl -X POST http://localhost:8000/api/ingest
# 4. Verify
curl http://localhost:8000/api/health
Put Caddy or Nginx + certbot in front for HTTPS and your own domain.
Minimal Caddy (/etc/caddy/Caddyfile):
yourdomain.com {
reverse_proxy localhost:8000
}
Option 2 — Hugging Face Spaces (free, zero-ops)
The repo's top-level README.md has HF Spaces frontmatter, so pushing this
repo to a Space builds it as a Docker Space on port 8000.
# 1. Create an empty Docker Space at https://huggingface.co/new-space
# (SDK: Docker, Hardware: CPU basic is enough)
# 2. In the Space's Settings → Variables and secrets:
# Secret: GROQ_API_KEY = gsk_...
# 3. Push the code:
HF_USER=your_hf_username \
HF_SPACE=your_space_name \
HF_TOKEN=hf_your_write_token \
./scripts/push-to-hf.sh
Notes:
- First build is ~5–8 minutes (it pre-downloads the embedding model).
- Auto-ingest runs on the first request after boot (~30 s).
- Spaces do not support persistent volumes on the free tier, so Chroma
rebuilds from
data/source/each cold start. This is fine because the corpus is small and re-ingest is fast. - Subsequent deploys are just
git push hf HEAD:main.
Option 3 — Google Cloud Run (pay-per-request, generous free tier)
Good fit because traffic is bursty and Cloud Run bills per request. Caveat: Cloud Run's local filesystem is ephemeral, so you need a mounted volume for Chroma. Use a second-gen service + a Cloud Storage FUSE mount or switch Chroma to a hosted vector DB (Pinecone, Qdrant Cloud, etc.).
Simplest version (ephemeral Chroma, re-ingests on cold start — fine for demos):
gcloud auth login
gcloud config set project YOUR_PROJECT
# build + push
gcloud builds submit --tag gcr.io/YOUR_PROJECT/langgraph-rag
# deploy
gcloud run deploy langgraph-rag \
--image gcr.io/YOUR_PROJECT/langgraph-rag \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--memory 2Gi \
--cpu 2 \
--concurrency 10 \
--timeout 300 \
--min-instances 0 \
--max-instances 3 \
--set-env-vars GROQ_MODEL=openai/gpt-oss-120b \
--set-secrets GROQ_API_KEY=GROQ_API_KEY:latest
For persistent Chroma on Cloud Run, either (a) add a GCS volume mount
(--add-volume + --add-volume-mount) pointing at /home/user/app/data/chroma, or (b)
swap Chroma for a managed vector DB.
Option 4 — Render / Railway
Both give you a managed container host with a UI instead of a CLI.
Render
- New -> Web Service -> connect your repo
- Runtime: Docker
- Instance type: Standard (2 GB) — the free 512 MB tier will OOM
- Add a Disk: mount path
/home/user/app/data/chroma, size 1 GB - Env vars:
GROQ_API_KEY=gsk_... - Health check path:
/api/health
Railway
- New Project -> Deploy from GitHub -> pick this repo
- Railway autodetects the
Dockerfile - Variables:
GROQ_API_KEY=gsk_... - Add a Volume mounted at
/home/user/app/data/chroma - Hit the generated
*.up.railway.appURL
Post-deploy checklist
-
GET /api/healthreturns{"status":"ok","has_api_key":"yes"} -
POST /api/ingestreturns non-zero chunk counts for each collection - Chat UI at
/answers a Dell question and shows the debug trace - HTTPS is enforced (platform-provided or Caddy/Nginx)
-
GROQ_API_KEYis stored in platform secrets, not in a committed.env -
CORS_ORIGINSis set to your real domain(s) instead of* - Volume backup for
/home/user/app/data/chromaif the content matters
Scaling notes
- Keep 1 worker per process. The embedding model is loaded once per process (~420 MB); 4 workers = ~1.7 GB just for model weights.
- To go beyond ~10 concurrent users, scale horizontally (more instances) with a shared vector DB — Chroma's local file backend is single-writer.
- For heavier loads swap Chroma for Qdrant / Pinecone / Weaviate and point
CHROMA_DB_PATHlogic at the managed DB instead (requires code changes inbackend/app/ingest.py+backend/app/graph.py).