This guide covers deploying all components of the Litecoin Knowledge Hub. The production stack consists of 9 services:
- Frontend (Next.js) - User-facing chat interface
- Backend (FastAPI) - RAG pipeline and API
- Payload CMS (Next.js) - Content management system
- Admin Frontend (Next.js) - System administration dashboard
- MongoDB - Document database and vector store
- Redis - Caching and rate limiting
- Prometheus - Metrics collection
- Grafana - Metrics visualization
- Cloudflared (Optional) - Cloudflare tunnel for secure access
- Prerequisites
- Environment Variables
- Frontend Deployment (Next.js)
- Backend Deployment (FastAPI)
- Payload CMS Deployment
- Docker Deployment (All Services)
- Local RAG Deployment (Optional)
- Post-Deployment Checklist
Before deploying, ensure you have:
-
Production MongoDB Database
- MongoDB Atlas cluster (recommended) or self-hosted MongoDB instance
- Connection string with appropriate credentials
- Database name:
litecoin_rag_db(or configure via env vars)
-
Google AI API Key
- Required for embeddings and LLM generation
- Get your API key from Google AI Studio
-
Domain Names (Optional)
- Custom domain for frontend (e.g.,
knowledgehub.litecoin.org) - Custom domain for backend API (e.g.,
api.litecoin.org) - Custom domain for CMS (e.g.,
cms.litecoin.org)
- Custom domain for frontend (e.g.,
-
Deployment Platforms
- Frontend: Vercel (recommended) or any Next.js hosting
- Backend: Railway, Render, Fly.io, or any Python hosting with Docker support
- Payload CMS: Vercel, Railway, Render, or Docker container
The project uses a centralized environment variable management system. For complete documentation of all environment variables, see docs/setup/ENVIRONMENT_VARIABLES.md.
Environment variables are organized into two categories:
-
Root-level
.env.*files - Shared configuration (service URLs, database connections, monitoring).env.docker.prod- Production Docker deployment configuration.env.local- Local development configuration.env.docker.dev- Docker development configuration
-
Service-specific
.envfiles - Secrets only (never committed to git)backend/.env- Backend secrets (GOOGLE_API_KEY, WEBHOOK_SECRET, ADMIN_TOKEN)payload_cms/.env- Payload CMS secrets (PAYLOAD_SECRET, WEBHOOK_SECRET)
For Docker production deployment, you need:
-
Create
.env.docker.prodin the project root:cp .env.example .env.docker.prod
-
Generate secure passwords and add to
.env.docker.prod:# Generate passwords MONGO_ROOT_PASSWORD=$(openssl rand -base64 32) MONGO_APP_PASSWORD=$(openssl rand -base64 32) REDIS_PASSWORD=$(openssl rand -base64 32) GRAFANA_ADMIN_PASSWORD=$(openssl rand -base64 32) # Add to .env.docker.prod echo "MONGO_ROOT_PASSWORD=$MONGO_ROOT_PASSWORD" >> .env.docker.prod echo "MONGO_APP_PASSWORD=$MONGO_APP_PASSWORD" >> .env.docker.prod echo "REDIS_PASSWORD=$REDIS_PASSWORD" >> .env.docker.prod echo "GRAFANA_ADMIN_PASSWORD=$GRAFANA_ADMIN_PASSWORD" >> .env.docker.prod
-
Update production URLs in
.env.docker.prod:PAYLOAD_PUBLIC_SERVER_URL=https://cms.lite.spaceFRONTEND_URL=https://chat.lite.spaceNEXT_PUBLIC_BACKEND_URL=https://api.lite.spaceNEXT_PUBLIC_PAYLOAD_URL=https://cms.lite.spaceCORS_ORIGINS=https://chat.lite.space,https://www.chat.lite.space
-
Update connection strings with authentication in
.env.docker.prod:MONGO_URI=mongodb://litecoin_app:${MONGO_APP_PASSWORD}@mongodb:27017/litecoin_rag_db?authSource=litecoin_rag_dbDATABASE_URI=mongodb://litecoin_app:${MONGO_APP_PASSWORD}@mongodb:27017/payload_cms?authSource=payload_cmsREDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
-
Create service-specific
.envfiles:# Generate shared webhook secret WEBHOOK_SECRET=$(openssl rand -base64 32) ADMIN_TOKEN=$(openssl rand -base64 32) # Backend secrets echo "GOOGLE_API_KEY=your-google-api-key-here" > backend/.env echo "WEBHOOK_SECRET=$WEBHOOK_SECRET" >> backend/.env echo "ADMIN_TOKEN=$ADMIN_TOKEN" >> backend/.env # Payload CMS secrets echo "PAYLOAD_SECRET=$(openssl rand -base64 32)" > payload_cms/.env echo "WEBHOOK_SECRET=$WEBHOOK_SECRET" >> payload_cms/.env
-
Optional: Cloudflare Tunnel - If using Cloudflare for secure access:
echo "CLOUDFLARE_TUNNEL_TOKEN=your-tunnel-token" >> .env.docker.prod
Important Notes:
- MongoDB and Redis authentication is required for production
WEBHOOK_SECRETmust be identical in bothbackend/.envandpayload_cms/.env- See Environment Variables Documentation for complete variable reference
-
Install Vercel CLI (optional, you can also use the web interface):
npm i -g vercel
-
Deploy:
cd frontend vercel -
Configure Environment Variables:
- Go to your project settings in Vercel dashboard
- Add
NEXT_PUBLIC_BACKEND_URLwith your backend API URL
-
Update next.config.ts for Production: Update
frontend/next.config.tsto use production backend URL:const nextConfig: NextConfig = { async rewrites() { return [ { source: '/api/v1/:path*', destination: process.env.NEXT_PUBLIC_BACKEND_URL + '/api/v1/:path*', }, ] }, }
See Docker Deployment section below.
- Connect your repository
- Set build command:
npm run build - Set start command:
npm start - Configure environment variables
- Deploy
-
Install Railway CLI:
npm i -g @railway/cli
-
Login and Initialize:
railway login cd backend railway init -
Configure Environment Variables:
railway variables set MONGO_URI="your-mongodb-connection-string" railway variables set GOOGLE_API_KEY="your-google-api-key" # Add all other required environment variables
-
Deploy:
railway up
-
Configure Startup Command:
- Platform: Python
- Start Command:
uvicorn main:app --host 0.0.0.0 --port $PORT
-
Create a new Web Service:
- Connect your GitHub repository
- Root Directory:
backend - Environment: Python 3
- Build Command:
pip install -r requirements.txt - Start Command:
uvicorn main:app --host 0.0.0.0 --port $PORT
-
Add Environment Variables:
- Add all required environment variables in the Render dashboard
-
Install Fly CLI:
curl -L https://fly.io/install.sh | sh -
Initialize:
cd backend fly launch -
Configure:
- Follow the prompts to set up your app
- Add environment variables:
fly secrets set MONGO_URI="..." GOOGLE_API_KEY="..."
-
Deploy:
fly deploy
See Docker Deployment section below.
In backend/main.py, update the CORS origins for production:
origins = [
"https://your-frontend-domain.com",
"https://www.your-frontend-domain.com",
]
# Or use environment variable
import os
origins = os.getenv("CORS_ORIGINS", "http://localhost:3000").split(",")-
Deploy:
cd payload_cms vercel -
Configure Environment Variables:
DATABASE_URI: MongoDB connection stringPAYLOAD_SECRET: Secure random secretPAYLOAD_PUBLIC_SERVER_URL: Your CMS domainBACKEND_URL: Your backend API URLNODE_ENV:production
-
Build Settings:
- Framework Preset: Next.js
- Build Command:
pnpm build(ornpm run build) - Output Directory:
.next
-
Initialize:
cd payload_cms railway init -
Configure:
- Set environment variables
- Build Command:
pnpm install && pnpm build - Start Command:
pnpm start
-
Deploy:
railway up
See Docker Deployment section below.
Ensure payload_cms/next.config.mjs has standalone output for Docker:
import { withPayload } from '@payloadcms/next/withPayload'
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone', // Required for Docker deployment
}
export default withPayload(nextConfig, { devBundleServerPackages: false })The project includes a complete production Docker Compose configuration with all 9 services. The docker-compose.prod.yml file is already present in the project root.
Before deploying with Docker Compose, ensure you have:
- Environment variables configured - See Environment Variables section above
- Docker and Docker Compose installed
- MongoDB users created (if using authentication) - See MongoDB/Redis Authentication Migration Guide
The production stack includes:
- mongodb - MongoDB 7.0 database with optional authentication
- backend - FastAPI backend service (port 8000)
- payload_cms - Payload CMS content management (port 3001)
- frontend - Next.js user interface (port 3000)
- admin_frontend - Next.js admin dashboard (port 3003)
- prometheus - Metrics collection (port 9090, localhost only)
- grafana - Metrics visualization (port 3002, localhost only)
- redis - Caching and rate limiting
- cloudflared - Cloudflare tunnel (optional)
-
Prepare environment files:
# Ensure .env.docker.prod exists (see Environment Variables section) # Ensure service-specific .env files exist: # - backend/.env (GOOGLE_API_KEY, WEBHOOK_SECRET, ADMIN_TOKEN) # - payload_cms/.env (PAYLOAD_SECRET, WEBHOOK_SECRET)
-
Create MongoDB users (required if using authentication):
# See docs/setup/MONGODB_REDIS_AUTH_MIGRATION.md for instructions -
Deploy all services:
docker-compose -f docker-compose.prod.yml up -d
-
Verify services are running:
docker-compose -f docker-compose.prod.yml ps
-
View logs:
# All services docker-compose -f docker-compose.prod.yml logs -f # Specific service docker-compose -f docker-compose.prod.yml logs -f backend
- Image:
mongo:7.0 - Port: Internal only (accessible via Docker network)
- Authentication: Optional (enabled if
MONGO_ROOT_PASSWORDis set) - Health Check: Checks MongoDB connectivity
- Volume:
mongodb_dev_data:/data/db(persistent storage)
- Build: From
./backend/Dockerfile - Port:
8000:8000 - Health Check: HTTP GET
/endpoint - Dependencies: Waits for MongoDB and Payload CMS to be healthy
- Volumes: Monitoring data persisted to
./backend/monitoring/data
- Build: From
./payload_cms/Dockerfile - Port:
3001:3000 - Health Check: HTTP GET on port 3000
- Dependencies: Waits for MongoDB to be healthy
- Build: From
./frontend/Dockerfile - Port:
3000:3000 - Build Args:
NEXT_PUBLIC_BACKEND_URL(default:https://api.lite.space)NEXT_PUBLIC_PAYLOAD_URL(default:https://cms.lite.space)
- Health Check: HTTP GET on port 3000
- Dependencies: Waits for backend to be healthy
- Build: From
./admin-frontend/Dockerfile - Port:
3003:3000 - Build Args:
NEXT_PUBLIC_BACKEND_URL - Health Check: HTTP GET on port 3000
- Dependencies: Waits for backend to be healthy
- Note: Typically runs locally; backend automatically adds admin frontend URL to CORS origins
- Image:
prom/prometheus:latest - Port:
127.0.0.1:9090:9090(localhost only for security) - Volumes:
./monitoring/prometheus.yml- Configuration./monitoring/alerts.yml- Alert rulesprometheus_data:/prometheus- Metrics storage (30-day retention)
- Dependencies: Waits for backend to start
- Image:
grafana/grafana:latest - Port:
127.0.0.1:3002:3000(localhost only for security) - Credentials: Set via
GRAFANA_ADMIN_USERandGRAFANA_ADMIN_PASSWORD - Volumes:
grafana_data:/var/lib/grafana- Dashboard storage./monitoring/grafana/provisioning- Auto-provisioned datasources./monitoring/grafana/dashboards- Dashboard definitions
- Dependencies: Waits for Prometheus to start
- Image:
redis:7-alpine - Port: Internal only (accessible via Docker network)
- Authentication: Optional (enabled if
REDIS_PASSWORDis set) - Persistence: Saves every 60 seconds if at least 1 key changed
- Volume:
redis_data:/data(persistent storage)
- Image:
cloudflare/cloudflared:latest - Configuration: Requires
CLOUDFLARE_TUNNEL_TOKENin.env.docker.prod - Purpose: Provides secure tunnel to Cloudflare edge network
- Dependencies: Waits for backend and Payload CMS to be healthy
After deployment, services are accessible at:
- Frontend:
http://localhost:3000(or your production domain) - Backend API:
http://localhost:8000 - Payload CMS Admin:
http://localhost:3001/admin - Admin Frontend:
http://localhost:3003(if running locally) - Prometheus:
http://localhost:9090(localhost only) - Grafana:
http://localhost:3002(localhost only)
Security Note: Prometheus and Grafana are bound to localhost only for security. Use SSH port forwarding or a reverse proxy to access them remotely if needed.
The monitoring stack (Prometheus + Grafana) is automatically configured with:
- Pre-configured Prometheus datasource in Grafana
- Litecoin Knowledge Hub dashboard
- Alert rules for error rates, response times, LLM costs, and cache hit rates
See Monitoring Documentation for detailed information.
# Stop all services
docker-compose -f docker-compose.prod.yml down
# Stop and remove volumes (WARNING: deletes all data)
docker-compose -f docker-compose.prod.yml down -vThe system supports high-performance local RAG with cloud spillover, using local models for query rewriting, embeddings, and caching. This feature is optional and can be enabled via the --local-rag flag when starting the production stack.
Local RAG services include:
- Ollama - Local LLM for query rewriting (recommended: native on macOS for Metal acceleration)
- Infinity Embeddings - Local embedding server for document embeddings (BGE-M3 model)
- Redis Stack - Vector cache for semantic caching with HNSW index
- macOS with Apple Silicon (M1/M2/M3/M4) - Recommended for native Metal (MPS) acceleration
- For x86_64 systems, services will run in Docker with CPU acceleration
- Python 3.9+ - For native embedding server
- Ollama installed - Download from ollama.ai (for native deployment)
Option 1: Using the helper script (Recommended)
# Start all services including local RAG
./scripts/run-prod.sh --local-rag
# Stop all services including local RAG
./scripts/down-prod.shOption 2: Manual deployment
# 1. Start local RAG services (Redis Stack, Ollama, Embedding Server)
./scripts/run-local-rag.sh
# 2. Start main production stack
docker-compose -f docker-compose.prod.yml up -d
# 3. Stop local RAG services
./scripts/down-local-rag.shAdd to .env.docker.prod:
# Local RAG Configuration
USE_LOCAL_REWRITER=true # Enable local query rewriting with Ollama
USE_INFINITY_EMBEDDINGS=true # Enable local embeddings with Infinity
USE_REDIS_CACHE=true # Enable semantic caching with Redis Stack
# Embedding Model (CRITICAL: Must be BAAI/bge-m3 for best quality)
EMBEDDING_MODEL_ID=BAAI/bge-m3 # Recommended: BGE-M3 (1024-dim, better Q&A)
# EMBEDDING_MODEL_ID=dunzhang/stella_en_1.5B_v5 # Legacy: Stella 1.5B (not recommended)
# Service URLs
OLLAMA_URL=http://host.docker.internal:11434 # Native Ollama on macOS
INFINITY_URL=http://host.docker.internal:7997 # Native embedding server on macOS
REDIS_STACK_URL=redis://redis_stack:6380 # Docker Redis Stack
# Router Configuration
MAX_LOCAL_QUEUE_DEPTH=3 # Max queue depth before spillover to cloud
LOCAL_TIMEOUT_SECONDS=5.0 # Timeout for local services (seconds)
# Model Configuration
LOCAL_REWRITER_MODEL=llama3.2:3b # Ollama model for query rewriting
VECTOR_DIMENSION=1024 # BGE-M3 vector dimension
# Redis Stack Cache Configuration
REDIS_CACHE_INDEX_NAME=cache:index
REDIS_CACHE_SIMILARITY_THRESHOLD=0.90- Default
EMBEDDING_MODEL_IDin code isBAAI/bge-m3, but.env.docker.prodmay override it - Always verify your
.env.docker.prodhasEMBEDDING_MODEL_ID=BAAI/bge-m3for optimal retrieval quality - See Embedding Model Update Guide for migration instructions
For best performance on Apple Silicon, run Ollama natively:
# Install Ollama (if not already installed)
# Download from https://ollama.ai or:
brew install ollama
# Start Ollama service
ollama serve
# Pull the model (first time only)
ollama pull llama3.2:3b
# Verify it's running
curl http://localhost:11434/api/tagsThe run-local-rag.sh script will detect native Ollama and skip starting the Dockerized version.
For Apple Silicon with Metal acceleration:
# Create virtual environment (if not already done)
python3 -m venv ~/infinity-env
source ~/infinity-env/bin/activate
# Install dependencies
pip install "sentence-transformers[torch]" fastapi uvicorn scikit-learn
# Start embedding server
source ~/infinity-env/bin/activate
export EMBEDDING_MODEL_ID='BAAI/bge-m3'
python scripts/local-rag/embeddings_server.py --device mps --port 7997 &
# Verify it's running
curl http://localhost:7997/healthNote: First run will download BGE-M3 model (~1.2GB). This is a one-time download.
Redis Stack is started automatically via Docker Compose when using the --local-rag flag. It runs as part of the local-rag profile:
# Verify Redis Stack is running
docker ps | grep redis_stack
# Check Redis Stack logs
docker logs litecoin-redis-stack┌─────────────────┐
│ Frontend │
└────────┬────────┘
│
┌────────▼────────┐
│ Backend │
│ (FastAPI) │
└────────┬────────┘
│
┌────┴──────────────────┐
│ │
┌───▼────────┐ ┌───────▼──────────┐
│ Ollama │ │ Infinity Server │
│ (Native) │ │ (Native MPS) │
└────────────┘ └──────────────────┘
│ │
└───────────┬───────────┘
│
┌───────▼────────┐
│ Redis Stack │
│ (Docker) │
└────────────────┘
Enable/disable individual components via environment variables:
USE_LOCAL_REWRITER=true- Use Ollama for query rewriting (spills to Gemini if timeout/queue full)USE_INFINITY_EMBEDDINGS=true- Use local Infinity server for embeddings (1024-dim BGE-M3)USE_REDIS_CACHE=true- Use Redis Stack for semantic caching (HNSW vector index)
All flags default to false - enable them explicitly in .env.docker.prod.
After enabling local RAG, you may need to re-index documents with the new embedding model:
# Set environment variables
export INFINITY_URL=http://localhost:7997
export MONGO_URI="your-mongodb-uri"
export EMBEDDING_MODEL_ID=BAAI/bge-m3
# Activate virtual environment
source ~/infinity-env/bin/activate
# Install re-indexing dependencies
pip install pymongo faiss-cpu langchain langchain-community
# Run re-indexing script
python scripts/reindex_vectors.pyThe script will:
- Fetch all documents from MongoDB
- Generate 1024-dim embeddings using BGE-M3
- Create FAISS index at
backend/faiss_index_1024/ - Update
FAISS_INDEX_PATH_1024in.env.docker.prod
-
Check Ollama:
curl http://localhost:11434/api/tags # Should return: {"models":[...]} -
Check Embedding Server:
curl http://localhost:7997/health # Should return: {"status":"healthy","model":"BAAI/bge-m3"} -
Check Redis Stack:
docker exec -it litecoin-redis-stack redis-cli -p 6380 PING # Should return: PONG
-
Check Backend Logs:
docker logs litecoin-backend | grep -E "(InfinityEmbeddings|InferenceRouter|RedisVectorCache)" # Should show initialization messages
-
Test RAG Query:
curl -X POST http://localhost:8000/api/v1/chat/stream \ -H "Content-Type: application/json" \ -d '{"query": "What is Litecoin?", "chat_history": []}'
-
Memory Optimization (see Memory Optimization Guide):
- Reduce Docker Desktop VM memory to 8GB
- Use
float16for BGE-M3 on MPS (already enabled) - Set backend container memory limit:
deploy.resources.limits.memory: 2G
-
Query Rewriting Timeout:
- Increase
LOCAL_TIMEOUT_SECONDSif Ollama is slow (default: 5.0s) - System automatically spills to Gemini if timeout exceeded
- Increase
-
Retrieval Quality:
- Ensure
EMBEDDING_MODEL_ID=BAAI/bge-m3(not Stella 1.5B) - Adjust
VECTOR_SEARCH_SIMILARITY_THRESHOLD(default: 0.75) to filter irrelevant documents - Increase
RETRIEVER_K(default: 12) for more context
- Ensure
Issue: Embedding server not starting
- Check Python version:
python3 --version(needs 3.9+) - Verify virtual environment is activated
- Check logs:
tail -f logs/embeddings_server.log
Issue: Backend can't connect to embedding server
- Verify
INFINITY_URL=http://host.docker.internal:7997in.env.docker.prod - Check embedding server is running:
curl http://localhost:7997/health - Restart backend:
docker restart litecoin-backend
Issue: Poor retrieval quality
- Verify
EMBEDDING_MODEL_ID=BAAI/bge-m3in.env.docker.prod - Re-index documents with BGE-M3 (see Vector Store Re-indexing above)
- Check similarity threshold:
VECTOR_SEARCH_SIMILARITY_THRESHOLD=0.75
Issue: Ollama timeout errors
- Increase
LOCAL_TIMEOUT_SECONDSin.env.docker.prod - Check Ollama is responding:
curl http://localhost:11434/api/tags - Consider using native Ollama instead of Dockerized version
Issue: Memory pressure spikes
- Reduce Docker Desktop VM memory to 8GB
- Verify backend container has memory limit:
deploy.resources.limits.memory: 2G - See Memory Optimization Guide
- High-Performance Local RAG Feature - Complete feature documentation
- Embedding Model Update Guide - Migrating from Stella to BGE-M3
- Memory Optimization Guide - Reducing memory usage
- UnboundLocalError Fix - Bug fix documentation
After deploying all services, verify the following:
Check that all services are running:
docker-compose -f docker-compose.prod.yml psAll services should show "Up" status.
# Local access
curl http://localhost:8000/
# Or via production domain
curl https://your-backend-domain.com/
# Should return: {"Hello": "World"}- Visit your frontend URL (
http://localhost:3000or production domain) - Verify the UI loads correctly
- Test API connectivity by submitting a query
- Visit
http://localhost:3001/admin(or production CMS URL) - Login with admin credentials
- Verify content collections are accessible
- Check that articles are visible
- Visit
http://localhost:3003 - Verify connection to backend
- Test system management features
- Create a test article in Payload CMS
- Publish it
- Verify it syncs to the backend (check
/api/v1/sources) - Query the RAG pipeline to confirm the article is indexed
curl -X POST http://localhost:8000/api/v1/chat \
-H "Content-Type: application/json" \
-d '{
"query": "What is Litecoin?",
"chat_history": []
}'- Verify frontend can make requests to backend
- Check browser console for CORS errors
- If running admin frontend locally, verify it can connect to backend
# Check MongoDB logs
docker-compose -f docker-compose.prod.yml logs mongodb
# Verify authentication is working (if enabled)
docker exec -it litecoin-mongodb mongosh -u litecoin_app -p# Check Redis logs
docker-compose -f docker-compose.prod.yml logs redis
# Test Redis connectivity (if password is not set)
docker exec -it litecoin-redis redis-cli ping
# Test Redis connectivity (if password is set)
docker exec -it litecoin-redis redis-cli -a $REDIS_PASSWORD ping- Visit
http://localhost:9090 - Check that backend target is UP (Status → Targets)
- Try a query:
rate(http_requests_total[5m])
- Visit
http://localhost:3002 - Login with admin credentials (set via
GRAFANA_ADMIN_PASSWORD) - Navigate to Dashboards → Litecoin Knowledge Hub - Monitoring Dashboard
- Verify metrics are being collected
- Verify all environment variables are set correctly in
.env.docker.prod - Check that service-specific
.envfiles exist and contain required secrets - Verify sensitive data (API keys, secrets) are not exposed in logs or environment
# Check for errors across all services
docker-compose -f docker-compose.prod.yml logs | grep -i error
# Check specific service logs
docker-compose -f docker-compose.prod.yml logs backend
docker-compose -f docker-compose.prod.yml logs frontend- Verify tunnel is running:
docker-compose -f docker-compose.prod.yml logs cloudflared - Check Cloudflare dashboard for tunnel status
- Verify routes are configured correctly
Issue: Services fail to start
# Check service logs
docker-compose -f docker-compose.prod.yml logs [service-name]
# Check if ports are already in use
netstat -tulpn | grep :8000
netstat -tulpn | grep :3000
# Verify environment files exist
ls -la .env.docker.prod backend/.env payload_cms/.envIssue: Health checks failing
- Check service logs for startup errors
- Verify dependencies (MongoDB, Redis) are healthy
- Increase
start_periodin healthcheck if services need more time to start
Issue: MongoDB connection fails
- Verify
MONGO_URIin.env.docker.prodis correct - Check MongoDB container is running:
docker ps | grep mongodb - Verify authentication credentials if authentication is enabled
- Check MongoDB logs:
docker-compose -f docker-compose.prod.yml logs mongodb - Ensure MongoDB users are created (see MongoDB/Redis Authentication Migration Guide)
Issue: Redis connection fails
- Verify
REDIS_URLin.env.docker.prodis correct - Check Redis container is running:
docker ps | grep redis - Verify password is set correctly if authentication is enabled
- Check Redis logs:
docker-compose -f docker-compose.prod.yml logs redis
Issue: CORS errors
- Verify
CORS_ORIGINSin.env.docker.prodincludes your frontend URL - If running admin frontend locally, set
ADMIN_FRONTEND_URLor add toCORS_ORIGINS - Check backend logs for CORS rejection messages
Issue: FAISS index not found
- In production with MongoDB Atlas Vector Search, FAISS is not needed
- The system automatically uses MongoDB Atlas for vector search in production
- Remove
FAISS_INDEX_PATHfrom environment variables if present
Issue: API requests fail
- Verify
NEXT_PUBLIC_BACKEND_URLis set correctly (build-time variable) - Rebuild frontend image after changing
NEXT_PUBLIC_*variables - Check
next.config.tsrewrites configuration - Verify backend CORS allows frontend origin
- Check browser console for specific error messages
Issue: Build fails
- Verify Node.js version compatibility
- Check build logs:
docker-compose -f docker-compose.prod.yml build frontend - Ensure all dependencies are listed in
package.json
Issue: Cannot connect to database
- Verify
DATABASE_URIin.env.docker.prodis correct - Check MongoDB container is accessible from Payload CMS container
- Verify authentication credentials if authentication is enabled
- Check Payload CMS logs:
docker-compose -f docker-compose.prod.yml logs payload_cms
Issue: Webhooks not syncing
- Verify
BACKEND_URLin.env.docker.prodpoints to backend service - Verify
WEBHOOK_SECRETis identical in bothbackend/.envandpayload_cms/.env - Check backend
/api/v1/sync/payloadendpoint is accessible - Review Payload CMS webhook logs in admin panel
- Check backend logs for webhook processing errors
Issue: Prometheus not scraping metrics
- Verify backend is healthy:
curl http://localhost:8000/health - Check Prometheus targets:
http://localhost:9090/targets - Verify
prometheus.ymlconfiguration - Check Prometheus logs:
docker-compose -f docker-compose.prod.yml logs prometheus
Issue: Grafana cannot connect to Prometheus
- Verify Prometheus is running:
docker ps | grep prometheus - Check Grafana datasource configuration
- Verify Prometheus URL is correct (
http://prometheus:9090in Docker network) - Check Grafana logs:
docker-compose -f docker-compose.prod.yml logs grafana
Issue: Tunnel not connecting
- Verify
CLOUDFLARE_TUNNEL_TOKENis set in.env.docker.prod - Check tunnel token is valid in Cloudflare dashboard
- Review tunnel logs:
docker-compose -f docker-compose.prod.yml logs cloudflared - Verify routes are configured in Cloudflare dashboard
- Environment Variables Documentation - Complete guide to all environment variables
- MongoDB/Redis Authentication Migration Guide - Setting up authentication for production
- Monitoring Documentation - Prometheus and Grafana setup
- Testing Documentation - Running the test suite
- Vercel Deployment Docs
- Railway Deployment Docs
- Render Deployment Docs
- Fly.io Deployment Docs
- Payload CMS Deployment
- Next.js Deployment
- FastAPI Deployment
- Docker Compose Documentation
- Cloudflare Tunnel Documentation
For deployment issues, please:
- Check the troubleshooting section above
- Review application logs in your deployment platform
- Verify all environment variables are set correctly
- Test locally first to isolate issues