Architecture
VOL is served from a single Cloudflare Pages deployment while the heavy lifting (retrieval, LLM, GPU) runs on a private server reached through Workers VPC and a Cloudflare Tunnel. No inbound port is opened on the server.
Browser │ https://<host>/ → web (Astro, static) │ https://<host>/app/ → app (React + Vite, static) │ https://<host>/docs/ → docs (Astro Starlight, static) │ https://<host>/api/v1/* → Pages Function ▼Cloudflare Pages ──► Worker "vol-gateway" (Workers VPC binding) │ ▼ Cloudflare Tunnel (cloudflared, outbound only) ┌───────────────── private server (Docker) ─────────────────┐ │ vol-api :8010 (FastAPI, /v1/*) │ │ ├─► ragflow-server :80/api/v1 (RAG, chat assistants) │ │ ├─► ragflow-es-01 :9200 (Elasticsearch) │ │ ├─► graph artifacts (positions.bin, links.bin, …) │ │ └─► SQLite (API keys, hashed) │ │ ragflow-mysql · ragflow-redis · ragflow-minio │ │ ollama (bge-m3 embeddings, GPU) · tei-reranker (GPU) │ └────────────────────────────────────────────────────────────┘Supabase (auth: users, Google OAuth, magic links, SSO) ◄── app; vol-api verifies JWTs via JWKSComponents
Section titled “Components”| Component | Role |
|---|---|
| Cloudflare Pages | Hosts the three static sites and the /api/v1/* Pages Function. |
vol-gateway Worker |
Forwards API calls into the private network through Workers VPC. |
cloudflared |
Outbound tunnel from the server to Cloudflare. |
vol-api |
FastAPI service implementing the v1 contract; auth, SSE streaming, graph artifacts. |
| RAGFlow | Datasets, hybrid retrieval, RAPTOR, chat assistants per case. |
| Elasticsearch | RAGFlow’s index; also queried directly for search. |
| Ollama + TEI | bge-m3 embeddings and reranking on the GPU. |
| Supabase | User accounts and sessions. |
Request lifecycle (chat)
Section titled “Request lifecycle (chat)”- The app calls
POST /api/v1/chatwith the user’s Supabase token (or an integration sends an API key). - The Pages Function hands the request to
vol-gateway, which reachesvol-apithrough the tunnel. vol-apiauthenticates, maps thecaseto its RAGFlow assistant and opens a streaming completion.- Tokens are re-emitted as SSE
deltaevents; retrieved chunks are mapped tonodeIndexvalues and sent as acitationsevent with the RAPTOR clusters;donecloses the stream.
Local development
Section titled “Local development”In development the app’s Vite server proxies /api/v1/* to http://localhost:8010/v1/*, so the same
code runs locally and in production. See Self-hosting with bin/vol.