This guide provides step-by-step instructions for deploying the Agentic RAG system across Railway (Backend) and Vercel (Frontend).
Since this system is stateful (it persists ChromaDB vectors and BM25s lexical indexes to the hard drive), it requires specific Volume mounting on the backend to ensure data isn't lost during deployments.
We use Railway for the backend because it natively supports Dockerfiles, easily handles system-level dependencies (like Tesseract OCR), and provides attachable persistent volumes.
- Ensure your code is pushed to a GitHub repository.
- Log into Railway.app.
- Click "New Project" -> "Deploy from GitHub repo".
- Select your repository.
- Important: If your backend is in a subfolder (e.g.,
rag_system/backend), you need to tell Railway to build from that specific directory.- Go to your service Settings -> Build -> Root Directory and set it to
/backend.
- Go to your service Settings -> Build -> Root Directory and set it to
- Ensure the Buildpack is set to
Dockerfile.
If you skip this step, all uploaded documents will be deleted every time your server restarts.
- Go to your service Volumes tab.
- Click "Add Volume".
- Set the Mount Path EXACTLY to:
/app/backend/data- Note: Our Dockerfile defines
ENV CHROMA_PATH="/app/backend/data/chroma", so this mount path ensures the app writes the databases directly to the persistent disk.
- Note: Our Dockerfile defines
- Go to the Variables tab.
- Add the following variable:
GEMINI_API_KEY=your_actual_api_key_here
- Go to the Settings tab.
- Under "Networking", click "Generate Domain".
- Copy this URL. You will need it for the frontend deployment. (e.g.,
https://rag-backend-production.up.railway.app)
We use Vercel for the frontend because it provides world-class global CDNs, instant invalidation, and zero-config React/Vite deployments.
- Log into Vercel.
- Click "Add New..." -> "Project".
- Import your GitHub repository.
- In the "Configure Project" screen, look for "Root Directory".
- Click "Edit" and select the
frontend/folder. - The "Framework Preset" should automatically detect Vite. Leave the build command as
npm run buildand output directory asdist.
- Expand the Environment Variables section.
- Add the following variable:
- Name:
VITE_API_URL - Value:
https://your-railway-backend-url.up.railway.app(Paste the URL you copied from Railway in Step 5)
- Name:
- Click Deploy.
- Wait 1-2 minutes for Vercel to build and publish the frontend.
By default, the backend's CORSMiddleware (in app/main.py) allows all origins (allow_origins=["*"]). Once your Vercel frontend is live, you should lock this down for production security.
- Copy your new Vercel domain (e.g.,
https://my-rag-app.vercel.app). - Go to
backend/app/main.py. - Update the CORS middleware:
app.add_middleware(
CORSMiddleware,
allow_origins=["https://my-rag-app.vercel.app"], # Replace with your actual Vercel URL
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)- Commit and push the code to GitHub. Railway will automatically redeploy the backend with the tightened security.
- The UI says "Thinking..." but never generates an answer:
Check your Railway logs. Ensure that your
GEMINI_API_KEYis valid and hasn't exhausted its quota. - Documents disappear after a few days:
You likely missed "Part 1, Step 3". Verify in Railway that the Volume is attached and mounted strictly to
/app/backend/data. - Uploads fail instantly:
Check the Vercel console network tab. If it's a CORS error, verify
VITE_API_URLdoesn't have a trailing slash (e.g.,https://api.domain.comNOThttps://api.domain.com/).