Phase 1: LightRAG Minimal Helm chart and documentation indexing using url references (#2)

* Partial implementation of phase-0

* Partial implementation of phase-1

* add report

* add postgress

* Revert "add postgress"

This reverts commit 27778dc6bb3906b5220dd386e47fe32ca7415332.

* remove junk

* Cleaned up annd setup docs

* update docs

* moved report

* Updated load_markdown_files function: Now returns tuples with (content, title, relative_path) instead of just (content, title)

* fixes to load docs script and more env variables for llm configuration

* update prod values

* update docs

* apolo docs support with linking

* update docs to reflect url conventions and mapping with docs

* Adds ingress and forwardAuth configurations

Adds ingress configuration to expose the application.

Adds forwardAuth configuration to enable user authentication.

Includes middleware to strip headers.

* Adds ingress and forward authentication middleware support
This commit is contained in:
Taddeus 2025-06-23 20:04:34 +03:00 committed by GitHub
parent 4a049bc84f
commit a70ba1f75a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 3622 additions and 1 deletions

4
.gitignore vendored
View file

@ -7,6 +7,10 @@ __pycache__/
*.tar.gz
*.ini
apolo-documentation/
init-scripts/
mongo-init/
rag_storage_test/
# Virtual Environment
.venv/
env/

174
README_load_docs.md Normal file
View file

@ -0,0 +1,174 @@
# LightRAG Documentation Loader
Advanced script to load markdown documentation into LightRAG with flexible reference modes.
## Quick Start
```bash
# Default mode (file path references)
python load_docs.py /path/to/your/docs
# URL mode (website link references)
python load_docs.py /path/to/docs --mode urls --base-url https://docs.example.com/
```
## Reference Modes
### Files Mode (Default)
Uses local file paths in query response citations:
```bash
python load_docs.py docs/
python load_docs.py docs/ --mode files
```
**Query Response Example:**
```
### References
- [DC] getting-started/installation.md
- [KG] administration/setup.md
```
### URLs Mode
Uses website URLs in query response citations:
```bash
python load_docs.py docs/ --mode urls --base-url https://docs.apolo.us/index/
python load_docs.py docs/ --mode urls --base-url https://my-docs.com/v1/
```
**Query Response Example:**
```
### References
- [DC] https://docs.apolo.us/index/getting-started/installation
- [KG] https://docs.apolo.us/index/administration/setup
```
**⚠️ Important for URLs Mode**: Your local file structure must match your documentation site's URL structure for proper link generation.
**File Structure Requirements:**
```
docs/
├── getting-started/
│ ├── installation.md → https://docs.example.com/getting-started/installation
│ └── first-steps.md → https://docs.example.com/getting-started/first-steps
├── administration/
│ ├── README.md → https://docs.example.com/administration
│ └── setup.md → https://docs.example.com/administration/setup
└── README.md → https://docs.example.com/
```
**URL Mapping Rules:**
- `.md` extension is removed from URLs
- `README.md` files map to their directory URL
- Subdirectories become URL path segments
- Hyphens and underscores in filenames are preserved
### Organizing Docs for URL Mode
**Step 1: Analyze Your Documentation Site Structure**
```bash
# Visit your docs site and note the URL patterns:
# https://docs.example.com/getting-started/installation
# https://docs.example.com/api/authentication
# https://docs.example.com/guides/deployment
```
**Step 2: Create Matching Directory Structure**
```bash
mkdir -p docs/{getting-started,api,guides}
```
**Step 3: Organize Your Markdown Files**
```bash
# Match each URL to a file path:
docs/getting-started/installation.md # → /getting-started/installation
docs/api/authentication.md # → /api/authentication
docs/guides/deployment.md # → /guides/deployment
docs/guides/README.md # → /guides (overview page)
```
**Step 4: Verify URL Mapping**
```bash
# Test a few URLs manually to ensure they work:
curl -I https://docs.example.com/getting-started/installation
curl -I https://docs.example.com/api/authentication
```
**Common Documentation Site Patterns:**
| Site Type | File Structure | URL Structure |
|-----------|---------------|---------------|
| **GitBook** | `docs/section/page.md` | `/section/page` |
| **Docusaurus** | `docs/section/page.md` | `/docs/section/page` |
| **MkDocs** | `docs/section/page.md` | `/section/page/` |
| **Custom** | Varies | Match your site's pattern |
**Real Example: Apolo Documentation**
```bash
# Apolo docs site: https://docs.apolo.us/index/
# Your local structure should match:
apolo-docs/
├── getting-started/
│ ├── first-steps/
│ │ ├── getting-started.md → /index/getting-started/first-steps/getting-started
│ │ └── README.md → /index/getting-started/first-steps
│ ├── apolo-base-docker-image.md → /index/getting-started/apolo-base-docker-image
│ └── faq.md → /index/getting-started/faq
├── apolo-console/
│ └── getting-started/
│ └── sign-up-login.md → /index/apolo-console/getting-started/sign-up-login
└── README.md → /index/
# Load with correct base URL:
python load_docs.py apolo-docs/ --mode urls --base-url https://docs.apolo.us/index/
```
## Complete Usage Examples
```bash
# Load Apolo documentation with URL references
python load_docs.py ../apolo-copilot/docs/official-apolo-documentation/docs \
--mode urls --base-url https://docs.apolo.us/index/
# Load with custom LightRAG endpoint
python load_docs.py docs/ --endpoint https://lightrag.example.com
# Load to local instance, skip test query
python load_docs.py docs/ --no-test
# Files mode with custom endpoint
python load_docs.py docs/ --mode files --endpoint http://localhost:9621
```
## Features
- **Dual Reference Modes**: File paths or live website URLs in citations
- **Flexible Base URL**: Works with any documentation site structure
- **Simple dependency**: Only requires `httpx` and Python standard library
- **Automatic discovery**: Finds all `.md` files recursively
- **Smart metadata**: Adds appropriate title, path/URL, and source information
- **Progress tracking**: Shows loading progress with success/failure counts
- **Health checks**: Verifies LightRAG connectivity before loading
- **Test queries**: Validates functionality after loading
- **Error handling**: Clear validation and error messages
## Requirements
```bash
pip install httpx
```
## Use Cases
This loader is perfect for:
- **Kubernetes deployments**: Self-contained with minimal dependencies
- **Quick testing**: Immediate setup without complex environments
- **Documentation loading**: Any markdown-based documentation
- **Development workflows**: Fast iteration and testing
## Requirements
```bash
pip install httpx
```
**Note**: This script is included with LightRAG deployments and provides a simple way to load any markdown documentation into your LightRAG instance.

View file

@ -0,0 +1,506 @@
# LightRAG Kubernetes Deployment Guide
**Complete guide for deploying LightRAG minimal stack to Kubernetes clusters**
## 📋 Overview
This guide provides a production-ready approach to deploying LightRAG to Kubernetes using only Helm charts. This method has been validated and tested for reliability.
**Key Features:**
- **Pure Helm deployment** - Everything managed through Helm charts, no kubectl apply needed
- **Embedded PostgreSQL with pgvector** - Automatic setup using Bitnami PostgreSQL chart with pgvector image
- **Multiple environments** - Development and production configurations
- **Auto-scaling ready** - Built-in HPA configuration for production
- **Validated process** - Tested teardown/rebuild cycle confirms reliability
## 🏗️ Architecture
```mermaid
graph TD
subgraph "Kubernetes Cluster"
subgraph "lightrag Namespace"
A[LightRAG Deployment<br/>gpt-4o model]
B[PostgreSQL StatefulSet<br/>pgvector/pgvector:pg16]
C[Services & ConfigMaps]
D[PersistentVolumes]
E[Secrets & API Keys]
end
end
F[Helm Chart Management]
G[External Access]
H[OpenAI API]
F --> A
F --> B
A --> B
A --> H
C --> G
style A fill:#e1f5fe
style B fill:#f3e5f5
style F fill:#e8f5e8
```
## 📦 Prerequisites
### Required Components
- **Kubernetes cluster** (1.19+) - Minikube, EKS, GKE, AKS, or on-premises
- **Helm** (3.0+) with Bitnami repository added
- **kubectl** configured for your target cluster
- **OpenAI API key** for LLM and embedding services
### Cluster Requirements
- **Minimum resources**: 2 CPU cores, 4Gi memory available
- **Storage class** supporting ReadWriteOnce volumes (standard class works)
- **Container registry access** to ghcr.io and docker.io
### Local Development Setup (Minikube)
```bash
# Start Minikube with sufficient resources
minikube start --cpus=4 --memory=8192 --disk-size=20g
# Verify cluster
kubectl cluster-info
kubectl get nodes
```
## 🚀 Deployment Process
### Step 1: Environment Preparation
```bash
# Navigate to deployment directory
cd LightRAG/k8s-deploy/lightrag-minimal
# Verify Helm repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Update chart dependencies
helm dependency update
# Set your OpenAI API key
export OPENAI_API_KEY="your-api-key-here"
```
### Step 2: Deploy for Development (Minikube/Local)
```bash
# Substitute environment variables in values file
envsubst < values-dev.yaml > values-dev-final.yaml
# Deploy the complete stack
helm install lightrag-minimal . \
-f values-dev-final.yaml \
--namespace lightrag \
--create-namespace
# Wait for PostgreSQL to be ready
kubectl wait --namespace lightrag \
--for=condition=ready pod \
-l app.kubernetes.io/name=postgresql \
--timeout=120s
# Wait for LightRAG to be ready
kubectl wait --namespace lightrag \
--for=condition=ready pod \
-l app.kubernetes.io/name=lightrag-minimal \
--timeout=120s
# Clean up temporary file
rm values-dev-final.yaml
# Start port forwarding for access
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621 &
```
**Access Methods:**
- **Web UI**: http://localhost:9621/webui
- **API Docs**: http://localhost:9621/docs
- **Health Check**: http://localhost:9621/health
### Step 3: Deploy for Production
```bash
# First, customize production values
# Edit values-prod.yaml to set:
# - Your domain name (lightrag.yourdomain.com)
# - Storage classes (fast-ssd)
# - Secure passwords
# - Resource limits based on your needs
# Substitute environment variables
envsubst < values-prod.yaml > values-prod-final.yaml
# Deploy with production configuration
helm install lightrag-minimal . \
-f values-prod-final.yaml \
--namespace lightrag \
--create-namespace
# Wait for deployment completion
kubectl wait --namespace lightrag \
--for=condition=ready pod \
-l app.kubernetes.io/name=lightrag-minimal \
--timeout=300s
# Clean up temporary file
rm values-prod-final.yaml
```
**Access:** Via ingress at your configured domain (e.g., https://lightrag.yourdomain.com/webui)
## 🔧 Configuration Files
### Available Values Files
| File | Purpose | Resources | Use Case |
|------|---------|-----------|----------|
| `values.yaml` | Default base | Medium | Testing |
| `values-dev.yaml` | Development | Small (1 CPU, 2Gi) | Local/Minikube |
| `values-prod.yaml` | Production | Large (4 CPU, 8Gi) | Production clusters |
### Key Configuration Options
#### Development (values-dev.yaml)
```yaml
# Small resources for local development
resources:
limits:
cpu: 1000m
memory: 2Gi
# Smaller storage
persistence:
ragStorage:
size: 5Gi
# Embedded PostgreSQL with pgvector
postgresql:
image:
repository: pgvector/pgvector
tag: pg16
# No ingress (use port-forward)
ingress:
enabled: false
```
#### Production (values-prod.yaml)
```yaml
# Production resources
resources:
limits:
cpu: 4000m
memory: 8Gi
# Large storage with fast storage class
persistence:
ragStorage:
size: 100Gi
storageClass: "fast-ssd"
# Ingress with TLS
ingress:
enabled: true
hosts:
- host: lightrag.yourdomain.com
# Auto-scaling
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
```
## 📊 Deployment Verification
### Check Deployment Status
```bash
# Check all deployed resources
kubectl get all --namespace lightrag
# Verify persistent volumes are bound
kubectl get pvc --namespace lightrag
# Check pod logs for any issues
kubectl logs --namespace lightrag -l app.kubernetes.io/name=lightrag-minimal
```
### Test System Health
```bash
# Start port forwarding (for development)
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621 &
# Test health endpoint
curl http://localhost:9621/health
# Expected healthy response:
{
"status": "healthy",
"configuration": {
"llm_model": "gpt-4o",
"kv_storage": "PGKVStorage",
"vector_storage": "PGVectorStorage",
"graph_storage": "NetworkXStorage"
}
}
# Test document upload endpoint
curl http://localhost:9621/documents
# Expected response:
{
"documents": 0,
"message": "Ready for document upload"
}
```
### View Logs
```bash
# LightRAG logs
kubectl logs --namespace lightrag -l app.kubernetes.io/name=lightrag-minimal -f
# PostgreSQL logs
kubectl logs --namespace lightrag -l app.kubernetes.io/name=postgresql -f
```
## 📚 Load Documentation
After successful deployment, load your documentation into LightRAG using the advanced documentation loader with dual reference modes:
### Using the Enhanced Documentation Loader
LightRAG includes an advanced documentation loader with flexible reference modes:
```bash
# Ensure port forwarding is active
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621 &
# Files Mode (Default) - Uses file paths in citations
python load_docs.py /path/to/your/docs
# URLs Mode - Uses website URLs in citations (recommended for public docs)
python load_docs.py /path/to/docs --mode urls --base-url https://docs.example.com/
# Load Apolo documentation with URL references
python load_docs.py /path/to/apolo-docs --mode urls --base-url https://docs.apolo.us/index/
# Load with custom endpoint
python load_docs.py /path/to/docs --endpoint https://lightrag.yourdomain.com
# Skip test query after loading
python load_docs.py /path/to/docs --no-test
```
### Reference Mode Benefits
**Files Mode (Default):**
- Uses local file paths in query response references
- Good for internal documentation or development
- Example: `[DC] getting-started/installation.md`
**URLs Mode:**
- Uses live website URLs in query response references
- Provides clickable links in responses
- Better user experience with direct access to source material
- Example: `[DC] https://docs.apolo.us/index/getting-started/installation`
### ⚠️ File Structure Requirements for URL Mode
**Critical**: Your local file structure must exactly match your documentation site's URL structure.
**Example Mapping:**
```
# Local file structure → Website URLs
docs/getting-started/installation.md → https://docs.example.com/getting-started/installation
docs/api/README.md → https://docs.example.com/api
docs/guides/deployment.md → https://docs.example.com/guides/deployment
```
**Setup Instructions:**
1. **Analyze your docs site URLs** - Note the exact path structure
2. **Create matching directories** - Mirror the URL structure locally
3. **Place files correctly** - Remove `.md` from URL paths to match filenames
4. **Test URLs** - Verify a few links work before loading documents
This ensures generated URLs in query responses are valid and clickable.
### Loader Features
- **Simple dependencies**: Only requires `httpx`
- **Automatic discovery**: Finds all `.md` files recursively
- **Basic metadata**: Adds title, path, and source information
- **Progress tracking**: Shows loading progress with success/failure counts
- **Health checks**: Verifies LightRAG connectivity before loading
- **Test queries**: Validates functionality after loading
### Expected Output
```
🚀 Loading Documentation into LightRAG
============================================================
📁 Documentation path: /path/to/docs
🌐 LightRAG endpoint: http://localhost:9621
✅ LightRAG is healthy: healthy
📚 Found 25 markdown files
📊 Total content: 150,000 characters
📊 Average length: 6,000 characters
🔄 Starting to load documents...
✅ Loaded: Getting Started
✅ Loaded: Installation Guide
✅ Loaded: API Reference
... (25 documents total)
📈 Progress: 20/25 (20 success, 0 failed)
✅ Loading complete!
📊 Successful: 25
📊 Failed: 0
🧪 Testing query...
✅ Query successful!
Response: This documentation covers...
```
### Verify Documentation Loading
```bash
# Check document count
curl http://localhost:9621/documents | jq '.documents | length'
# Test a sample query
curl -X POST http://localhost:9621/query \
-H "Content-Type: application/json" \
-d '{"query": "How do I get started?", "mode": "hybrid"}'
```
## 🔄 Management Commands
### Scaling
```bash
# Manual scaling
kubectl scale deployment lightrag-minimal --replicas=3 --namespace lightrag
# Update resources
helm upgrade lightrag-minimal . \
-f values-dev-final.yaml \
--set resources.limits.cpu=2000m \
--namespace lightrag
```
### Updates
```bash
# Update to latest image
helm upgrade lightrag-minimal . \
-f values-dev-final.yaml \
--set image.tag=latest \
--namespace lightrag
# Rolling restart
kubectl rollout restart deployment/lightrag-minimal --namespace lightrag
```
### Cleanup
```bash
# Uninstall release
helm uninstall lightrag-minimal --namespace lightrag
# Remove namespace
kubectl delete namespace lightrag
```
## 🚨 Troubleshooting
### Common Issues
**Issue: Pod CrashLoopBackOff**
```bash
# Check logs
kubectl logs --namespace lightrag -l app.kubernetes.io/name=lightrag-minimal
# Check PostgreSQL
kubectl logs --namespace lightrag -l app.kubernetes.io/name=postgresql
```
**Issue: pgvector extension missing**
```bash
# Check if extension was created automatically
kubectl exec --namespace lightrag \
$(kubectl get pod -l app.kubernetes.io/name=postgresql -o jsonpath='{.items[0].metadata.name}') \
-- psql -U lightrag_user -d lightrag -c "SELECT * FROM pg_extension WHERE extname='vector';"
```
**Issue: Storage issues**
```bash
# Check PVCs
kubectl get pvc --namespace lightrag
# Check storage class
kubectl get storageclass
```
### Support Commands
```bash
# Describe problematic pod
kubectl describe pod --namespace lightrag -l app.kubernetes.io/name=lightrag-minimal
# Check events
kubectl get events --namespace lightrag --sort-by='.lastTimestamp'
# Port forward for debugging
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621
```
## 🎯 Advantages of This Approach
**Pure Helm** - No manual kubectl apply commands
**Integrated PostgreSQL** - Bitnami chart handles all PostgreSQL complexity
**pgvector Support** - Automatic extension creation via initdb scripts
**Environment Flexibility** - Separate values files for dev/prod
**Production Ready** - Built-in scaling, security, monitoring hooks
**Clean Management** - Easy updates, rollbacks, and cleanup
**Persistent Storage** - Data survives pod restarts and cluster updates
## 📁 Final Directory Structure
```
lightrag-minimal/
├── Chart.yaml # Helm chart metadata
├── Chart.lock # Dependency lock file
├── charts/ # Downloaded dependencies (PostgreSQL)
├── templates/ # Kubernetes manifests templates
├── values.yaml # Default configuration
├── values-dev.yaml # Development settings
├── values-prod.yaml # Production settings
└── README.md # Chart documentation
```
## ✅ Deployment Validation
This deployment process has been thoroughly validated through complete teardown and rebuild cycles:
### Validation Process
1. **Complete Teardown**: `helm uninstall` + `kubectl delete namespace`
2. **Clean Rebuild**: Fresh deployment from scratch using only Helm
3. **Functionality Testing**: Health checks, API endpoints, document loading
4. **Resource Verification**: All pods running, PVCs bound, services accessible
### Validated Components
- ✅ **Pure Helm Deployment** - No manual kubectl apply commands needed
- ✅ **PostgreSQL with pgvector** - Automatic extension creation via initdb scripts
- ✅ **Resource Management** - Proper CPU/memory limits and persistent storage
- ✅ **API Functionality** - Health, document upload, and query endpoints working
- ✅ **Documentation Loading** - Successful loading of markdown documentation files
### Test Results
```bash
# Deployment Status: ✅ SUCCESS
📊 LightRAG: healthy, gpt-4o model configured
📊 PostgreSQL: running with pgvector extension
📊 Storage: 3 PVCs bound (12Gi total)
📊 API: All endpoints responding correctly
📊 Documentation: Ready for loading with included loader script
```
This approach provides a production-ready, maintainable solution for deploying LightRAG to any Kubernetes cluster with confidence in its reliability and repeatability.

438
blueprints/REPORT.md Normal file
View file

@ -0,0 +1,438 @@
# LightRAG Storage Stack Configurations Report
## Executive Summary
LightRAG supports a modular storage architecture with 4 distinct storage types that can be mixed and matched:
- **Graph Storage**: Knowledge graph relationships
- **Vector Storage**: Document embeddings
- **KV Storage**: Key-value pairs and metadata
- **Document Status Storage**: Document processing status
This report analyzes 25+ storage implementations across 8 database technologies to provide recommendations for different use cases.
## Storage Architecture Overview
### Storage Types & Available Implementations
| Storage Type | Implementations | Count |
|--------------|----------------|-------|
| **Graph Storage** | NetworkXStorage, Neo4JStorage, PGGraphStorage, AGEStorage¹, MongoGraphStorage¹ | 5 |
| **Vector Storage** | NanoVectorDBStorage, MilvusVectorDBStorage, ChromaVectorDBStorage, PGVectorStorage, FaissVectorDBStorage, QdrantVectorDBStorage, MongoVectorDBStorage | 7 |
| **KV Storage** | JsonKVStorage, RedisKVStorage, PGKVStorage, MongoKVStorage | 4 |
| **Doc Status Storage** | JsonDocStatusStorage, PGDocStatusStorage, MongoDocStatusStorage | 3 |
¹ *Currently commented out in production*
## Database Technology Analysis
### 1. PostgreSQL + pgvector
**Implementations**: PGVectorStorage, PGKVStorage, PGGraphStorage, PGDocStatusStorage
**Strengths:**
- ✅ **Unified Database**: Single database for all storage types
- ✅ **ACID Compliance**: Full transactional support
- ✅ **Mature Ecosystem**: Well-established, enterprise-ready
- ✅ **Minimal**: Single database to maintain
- ✅ **pgvector Extension**: Native vector operations with good performance
- ✅ **SQL Familiarity**: Easy to query and debug
**Weaknesses:**
- ❌ **Graph Limitations**: Requires AGE extension for advanced graph operations
- ❌ **Vector Performance**: Good but not specialized vector database performance
- ❌ **Single Point of Failure**: All data in one database
**Configuration:**
```yaml
LIGHTRAG_KV_STORAGE: PGKVStorage
LIGHTRAG_VECTOR_STORAGE: PGVectorStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
LIGHTRAG_GRAPH_STORAGE: PGGraphStorage # Requires AGE extension
```
### 2. Neo4j (Graph Specialist)
**Implementations**: Neo4JStorage
**Strengths:**
- ✅ **Graph Optimization**: Purpose-built for graph operations
- ✅ **Advanced Graph Analytics**: Complex graph algorithms built-in
- ✅ **Cypher Query Language**: Powerful graph query capabilities
- ✅ **Scalability**: Excellent for large, complex graphs
- ✅ **Visualization**: Rich graph visualization tools
**Weaknesses:**
- ❌ **Graph Only**: Requires additional databases for vectors/KV
- ❌ **Complexity**: More complex setup and maintenance
- ❌ **Cost**: Enterprise features require licensing
- ❌ **Memory Usage**: Can be memory-intensive
**Typical Configuration:**
```yaml
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_VECTOR_STORAGE: MilvusVectorDBStorage # Or Qdrant
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
```
### 3. Milvus (Vector Specialist)
**Implementations**: MilvusVectorDBStorage
**Strengths:**
- ✅ **Vector Performance**: Optimized for high-performance vector search
- ✅ **Scalability**: Designed for billion-scale vector collections
- ✅ **Multiple Indexes**: Various indexing algorithms (IVF, HNSW, etc.)
- ✅ **GPU Support**: CUDA acceleration for vector operations
- ✅ **Cloud Native**: Kubernetes-ready architecture
**Weaknesses:**
- ❌ **Complexity**: Complex distributed architecture
- ❌ **Resource Usage**: High memory and compute requirements
- ❌ **Overkill**: May be excessive for smaller datasets
- ❌ **Dependencies**: Requires etcd and MinIO for full deployment
**Typical Configuration:**
```yaml
LIGHTRAG_VECTOR_STORAGE: MilvusVectorDBStorage
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: MongoDocStatusStorage
```
### 4. Qdrant (Vector Specialist)
**Implementations**: QdrantVectorDBStorage
**Strengths:**
- ✅ **Performance**: High-performance vector search with Rust backend
- ✅ **Simplicity**: Easier deployment than Milvus
- ✅ **Filtering**: Advanced payload filtering capabilities
- ✅ **API**: Rich REST and gRPC APIs
- ✅ **Memory Efficiency**: Lower memory footprint than Milvus
**Weaknesses:**
- ❌ **Ecosystem**: Smaller ecosystem compared to alternatives
- ❌ **Vector Only**: Requires additional databases for other storage types
### 5. MongoDB (Multi-Purpose)
**Implementations**: MongoKVStorage, MongoVectorDBStorage, MongoDocStatusStorage
**Strengths:**
- ✅ **Flexibility**: Schema-less document storage
- ✅ **Vector Search**: Native vector search capabilities (Atlas Search)
- ✅ **Multi-Purpose**: Can handle KV, vectors, and document status
- ✅ **Scalability**: Horizontal scaling with sharding
- ✅ **Developer Friendly**: Easy to work with JSON documents
**Weaknesses:**
- ❌ **Graph Limitations**: Not optimized for graph operations
- ❌ **Vector Performance**: Vector search not as optimized as specialists
- ❌ **Memory Usage**: Can be memory-intensive for large datasets
### 6. Redis (KV Specialist)
**Implementations**: RedisKVStorage
**Strengths:**
- ✅ **Speed**: In-memory performance for KV operations
- ✅ **Simplicity**: Simple key-value operations
- ✅ **Data Structures**: Rich data structures (lists, sets, hashes)
- ✅ **Caching**: Excellent for caching and session storage
**Weaknesses:**
- ❌ **Memory Bound**: Limited by available RAM
- ❌ **KV Only**: Only suitable for key-value storage
- ❌ **Persistence**: Data persistence requires configuration
### 7. Local File Storage
**Implementations**: NetworkXStorage, JsonKVStorage, JsonDocStatusStorage, NanoVectorDBStorage, FaissVectorDBStorage
**Strengths:**
- ✅ **Simplicity**: No external dependencies
- ✅ **Development**: Perfect for development and testing
- ✅ **Portability**: Easy to backup and move
- ✅ **Cost**: No infrastructure costs
**Weaknesses:**
- ❌ **Scalability**: Limited by single machine resources
- ❌ **Concurrency**: No built-in concurrent access
- ❌ **Performance**: Limited performance for large datasets
- ❌ **Reliability**: Single point of failure
### 8. ChromaDB (Vector Specialist)
**Implementations**: ChromaVectorDBStorage
**Strengths:**
- ✅ **Simplicity**: Easy to deploy and use
- ✅ **Python Native**: Built for Python ML workflows
- ✅ **Metadata**: Rich metadata filtering capabilities
- ✅ **Local/Distributed**: Can run locally or distributed
**Weaknesses:**
- ❌ **Performance**: Slower than Milvus/Qdrant for large scales
- ❌ **Maturity**: Newer project with evolving feature set
## Recommended Stack Configurations
### 1. 🏆 **Production High-Performance Stack**
**Best for**: Large-scale production deployments, complex graph analytics
```yaml
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_VECTOR_STORAGE: MilvusVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
```
**Services Required:**
- Neo4j (Graph operations)
- Milvus + etcd + MinIO (Vector search)
- Redis (KV cache)
- PostgreSQL (Document status)
**Pros**: Maximum performance, specialized for each data type
**Cons**: High complexity, resource intensive, expensive
```mermaid
graph LR
LightRAG_App["LightRAG Application"]
Neo4j_Service["Neo4j Service"]
Milvus_Cluster["Milvus Cluster (Milvus, etcd, MinIO)"]
Redis_Service["Redis Service"]
PostgreSQL_Service["PostgreSQL Service"]
LightRAG_App --> |Graph Storage| Neo4j_Service
LightRAG_App --> |Vector Storage| Milvus_Cluster
LightRAG_App --> |KV Storage| Redis_Service
LightRAG_App --> |Doc Status Storage| PostgreSQL_Service
```
### 2. 🎯 **Production Balanced Stack**
**Best for**: Production deployments prioritizing simplicity
```yaml
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
LIGHTRAG_VECTOR_STORAGE: QdrantVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
```
**Services Required:**
- Qdrant (Vector search)
- Redis (KV cache)
- PostgreSQL (Document status)
- File system (Graph storage)
**Pros**: Good performance, simpler than full specialist stack
**Cons**: Graph operations limited by file-based storage
```mermaid
graph LR
subgraph "LightRAG Application Environment"
LightRAG_App["LightRAG Application"]
NetworkX["NetworkX Graph Storage (Local FS)"]
LightRAG_App -.-> NetworkX
end
Qdrant_Service["Qdrant Service"]
Redis_Service["Redis Service"]
PostgreSQL_Service["PostgreSQL Service"]
LightRAG_App --> |Vector Storage| Qdrant_Service
LightRAG_App --> |KV Storage| Redis_Service
LightRAG_App --> |Doc Status Storage| PostgreSQL_Service
```
### 3. 💰 **Production Minimal Stack**
**Best for**: Budget-conscious production deployments
```yaml
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
LIGHTRAG_VECTOR_STORAGE: PGVectorStorage
LIGHTRAG_KV_STORAGE: PGKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
```
**Services Required:**
- PostgreSQL + pgvector (All storage except graph)
- File system (Graph storage)
**Pros**: Single database, low cost, good for medium scale
**Cons**: Not optimized for very large datasets or complex graphs
```mermaid
graph LR
subgraph "LightRAG Application Environment"
LightRAG_App["LightRAG Application"]
NetworkX["NetworkX Graph Storage (Local FS)"]
LightRAG_App -.-> NetworkX
end
PostgreSQL_Service["PostgreSQL Service (+pgvector)"]
LightRAG_App --> |Vector Storage| PostgreSQL_Service
LightRAG_App --> |KV Storage| PostgreSQL_Service
LightRAG_App --> |Doc Status Storage| PostgreSQL_Service
```
### 4. 🚀 **Development & Testing Stack**
**Best for**: Local development, testing, small deployments
```yaml
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
LIGHTRAG_VECTOR_STORAGE: NanoVectorDBStorage
LIGHTRAG_KV_STORAGE: JsonKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: JsonDocStatusStorage
```
**Services Required:**
- None (all file-based)
**Pros**: Zero infrastructure, fast setup, portable
**Cons**: Limited scalability and performance
```mermaid
graph LR
subgraph "LightRAG Application (Local Process)"
LightRAG_App["LightRAG App"]
NetworkX["NetworkX (File System)"]
NanoVectorDB["NanoVectorDB (File System)"]
JsonKV["JsonKVStorage (File System)"]
JsonDocStatus["JsonDocStatusStorage (File System)"]
LightRAG_App -.-> |Graph| NetworkX
LightRAG_App -.-> |Vector| NanoVectorDB
LightRAG_App -.-> |KV| JsonKV
LightRAG_App -.-> |Doc Status| JsonDocStatus
end
```
### 5. 🐳 **Docker All-in-One Stack**
**Best for**: Containerized deployments, cloud environments
```yaml
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_VECTOR_STORAGE: QdrantVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: MongoDocStatusStorage
```
**Services Required:**
- Neo4j (Graph)
- Qdrant (Vector)
- Redis (KV)
- MongoDB (Document status)
**Pros**: Cloud-native, each service containerized
**Cons**: More services to manage
```mermaid
graph LR
subgraph "Docker Environment (e.g., Docker Compose)"
LightRAG_Container["LightRAG App (Container)"]
Neo4j_Container["Neo4j (Container)"]
Qdrant_Container["Qdrant (Container)"]
Redis_Container["Redis (Container)"]
MongoDB_Container["MongoDB (Container)"]
end
LightRAG_Container --> |Graph Storage| Neo4j_Container
LightRAG_Container --> |Vector Storage| Qdrant_Container
LightRAG_Container --> |KV Storage| Redis_Container
LightRAG_Container --> |Doc Status Storage| MongoDB_Container
```
## Performance Comparison
### Vector Search Performance (Approximate)
| Implementation | Small (1K docs) | Medium (100K docs) | Large (1M+ docs) | Memory Usage |
|---------------|-----------------|--------------------|-----------------|--------------|
| MilvusVectorDB | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | High |
| QdrantVectorDB | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | Medium |
| PGVectorStorage | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | Medium |
| ChromaVectorDB | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | Medium |
| FaissVectorDB | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | Low |
| NanoVectorDB | ⭐⭐⭐ | ⭐⭐ | ⭐ | Low |
### Graph Operations Performance
| Implementation | Node Queries | Edge Traversal | Complex Analytics | Scalability |
|---------------|--------------|----------------|------------------|-------------|
| Neo4JStorage | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| PGGraphStorage | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| NetworkXStorage | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐ |
### KV Operations Performance
| Implementation | Read Speed | Write Speed | Concurrency | Persistence |
|---------------|------------|-------------|-------------|-------------|
| RedisKVStorage | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| PGKVStorage | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| MongoKVStorage | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| JsonKVStorage | ⭐⭐ | ⭐⭐ | ⭐ | ⭐⭐⭐⭐⭐ |
## Deployment Considerations
### Resource Requirements
| Configuration | CPU | Memory | Storage | Network |
|--------------|-----|--------|---------|---------|
| Development Stack | 2 cores | 4GB | 10GB | Minimal |
| Minimal Stack | 4 cores | 8GB | 50GB | Medium |
| Balanced Stack | 8 cores | 16GB | 100GB | High |
| High-Performance Stack | 16+ cores | 32GB+ | 500GB+ | Very High |
### Maintenance Complexity
| Stack Type | Setup Complexity | Operational Overhead | Monitoring | Backup Strategy |
|-----------|------------------|---------------------|------------|-----------------|
| Development | ⭐ | ⭐ | ⭐ | Simple |
| Minimal | ⭐⭐ | ⭐⭐ | ⭐⭐ | Medium |
| Balanced | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | Complex |
| High-Performance | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | Very Complex |
## Migration Paths
### Development → Production
1. Start with Development Stack (all file-based)
2. Migrate to Minimal Stack (PostgreSQL-based)
3. Scale to Balanced Stack (add specialized vector DB)
4. Optimize with High-Performance Stack (full specialization)
### Data Migration Tools
- **Database-specific**: Use native tools (pg_dump, neo4j-admin, etc.)
- **LightRAG native**: Built-in export/import capabilities
- **Cross-platform**: JSON export for universal compatibility
## Recommendations by Use Case
### 📚 **Documentation/Knowledge Base**
- **Small (<10K docs)**: Development Stack
- **Medium (<100K docs)**: Minimal Stack
- **Large (>100K docs)**: Balanced Stack
### 🔬 **Research/Analytics**
- **Graph-heavy**: High-Performance Stack with Neo4j
- **Vector-heavy**: Balanced Stack with Milvus
- **Mixed workload**: Balanced Stack
### 💼 **Enterprise**
- **High Availability**: High-Performance Stack with clustering
- **Budget Conscious**: Minimal Stack with PostgreSQL
- **Regulatory**: On-premises with full control
### 🚀 **Startups/SMBs**
- **MVP**: Development Stack
- **Growing**: Minimal Stack
- **Scaling**: Balanced Stack
## Conclusion
The **Minimal Stack** (PostgreSQL + NetworkX) provides the best balance of performance, complexity, and cost for most use cases. It offers:
- ✅ Production-ready reliability
- ✅ Reasonable performance for medium-scale deployments
- ✅ Low operational overhead
- ✅ Clear upgrade path to specialized components
For specialized needs:
- **High graph complexity** → Add Neo4j
- **High vector performance** → Add Qdrant/Milvus
- **High concurrency KV** → Add Redis
The modular architecture allows gradual optimization based on actual performance bottlenecks rather than premature optimization.
---
*Report generated based on LightRAG v1.3.7 implementation analysis*

217
deploy-stacks.sh Executable file
View file

@ -0,0 +1,217 @@
#!/bin/bash
# Deployment script for LightRAG stack configurations
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if .env file exists
check_env_file() {
if [ ! -f .env ]; then
print_warning ".env file not found. Creating from env.example..."
if [ -f env.example ]; then
cp env.example .env
print_warning "Please update .env with your API keys before deployment!"
else
print_error "env.example file not found!"
exit 1
fi
fi
}
# Create necessary directories
create_directories() {
print_status "Creating necessary directories..."
mkdir -p data/inputs
mkdir -p data/rag_storage
mkdir -p data/dev-storage
print_success "Directories created"
}
# Deploy specific stack
deploy_stack() {
local stack=$1
local compose_file="docker-compose.${stack}.yml"
if [ ! -f "$compose_file" ]; then
print_error "Compose file $compose_file not found!"
return 1
fi
print_status "Deploying $stack stack..."
# Stop any existing containers
docker-compose -f "$compose_file" down 2>/dev/null || true
# Start the stack
docker-compose -f "$compose_file" up -d
if [ $? -eq 0 ]; then
print_success "$stack stack deployed successfully!"
# Show running services
echo ""
print_status "Running services:"
docker-compose -f "$compose_file" ps
# Wait a bit for services to start
sleep 5
# Check LightRAG health
print_status "Checking LightRAG health..."
for i in {1..30}; do
if curl -s http://localhost:9621/health > /dev/null 2>&1; then
print_success "LightRAG is healthy and ready!"
echo ""
echo "🌐 Web UI: http://localhost:9621/webui"
echo "📖 API Docs: http://localhost:9621/docs"
echo "💚 Health Check: http://localhost:9621/health"
return 0
fi
echo -n "."
sleep 2
done
print_warning "LightRAG health check timed out. Check logs with:"
echo "docker-compose -f $compose_file logs lightrag"
else
print_error "Failed to deploy $stack stack!"
return 1
fi
}
# Stop stack
stop_stack() {
local stack=$1
local compose_file="docker-compose.${stack}.yml"
if [ ! -f "$compose_file" ]; then
print_error "Compose file $compose_file not found!"
return 1
fi
print_status "Stopping $stack stack..."
docker-compose -f "$compose_file" down
print_success "$stack stack stopped"
}
# Clean up stack (stop and remove volumes)
cleanup_stack() {
local stack=$1
local compose_file="docker-compose.${stack}.yml"
if [ ! -f "$compose_file" ]; then
print_error "Compose file $compose_file not found!"
return 1
fi
print_warning "This will remove all data for $stack stack. Are you sure? (y/N)"
read -r response
if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
print_status "Cleaning up $stack stack..."
docker-compose -f "$compose_file" down -v --remove-orphans
print_success "$stack stack cleaned up"
else
print_status "Cleanup cancelled"
fi
}
# Show usage
show_usage() {
echo "Usage: $0 <command> [stack]"
echo ""
echo "Commands:"
echo " deploy <stack> Deploy a specific stack"
echo " stop <stack> Stop a specific stack"
echo " cleanup <stack> Stop and remove all data for a stack"
echo " list List available stacks"
echo ""
echo "Available stacks:"
echo " development File-based storage (NetworkX + NanoVector + JSON)"
echo " minimal File-based storage (NetworkX + PostgreSQL)"
echo " balanced Mixed storage (NetworkX + Qdrant + Redis + PostgreSQL)"
echo " high-performance Specialized storage (Neo4j + Milvus + Redis + PostgreSQL)"
echo " all-in-one Cloud-native (Neo4j + Qdrant + Redis + MongoDB)"
echo ""
echo "Examples:"
echo " $0 deploy development"
echo " $0 stop Minimal"
echo " $0 cleanup high-performance"
}
# List available stacks
list_stacks() {
print_status "Available LightRAG stack configurations:"
echo ""
echo "📚 development - File-based storage, perfect for development"
echo "💰 minimal - PostgreSQL-based, single database"
echo "🎯 balanced - Mixed storage, good performance/complexity balance"
echo "🏆 high-performance - Specialized databases, maximum performance"
echo "🐳 all-in-one - Cloud-native, containerized services"
echo ""
echo "Use '$0 deploy <stack>' to deploy a configuration"
}
# Main script logic
main() {
case "$1" in
deploy)
if [ -z "$2" ]; then
print_error "Please specify a stack to deploy"
show_usage
exit 1
fi
check_env_file
create_directories
deploy_stack "$2"
;;
stop)
if [ -z "$2" ]; then
print_error "Please specify a stack to stop"
show_usage
exit 1
fi
stop_stack "$2"
;;
cleanup)
if [ -z "$2" ]; then
print_error "Please specify a stack to cleanup"
show_usage
exit 1
fi
cleanup_stack "$2"
;;
list)
list_stacks
;;
*)
show_usage
exit 1
;;
esac
}
# Run main function with all arguments
main "$@"

View file

@ -0,0 +1,148 @@
version: '3.8'
# Docker All-in-One Stack
# Neo4j + Qdrant + Redis + MongoDB
# Best for: Containerized deployments, cloud environments
services:
# LightRAG Application
lightrag:
image: ghcr.io/hkuds/lightrag:latest
container_name: lightrag-aio
env_file:
- .env
environment:
# All-in-One Storage Configuration
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_VECTOR_STORAGE: QdrantVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: MongoDocStatusStorage
# Service Connection Details
NEO4J_URI: bolt://neo4j:7687
NEO4J_USERNAME: neo4j
NEO4J_PASSWORD: lightrag_neo4j_pass
QDRANT_URL: http://qdrant:6333
REDIS_URI: redis://redis:6379
MONGO_URI: mongodb://lightrag_user:lightrag_pass@mongodb:27017/lightrag?authSource=admin
MONGO_DATABASE: lightrag
# Performance settings
MAX_ASYNC: 6
MAX_TOKENS: 32768
ENABLE_LLM_CACHE: true
ENABLE_LLM_CACHE_FOR_EXTRACT: true
ports:
- "9621:9621"
depends_on:
mongodb:
condition: service_healthy
redis:
condition: service_healthy
neo4j:
condition: service_started
qdrant:
condition: service_healthy
volumes:
- ./data/inputs:/app/inputs
- ./data/rag_storage:/app/rag_storage
networks:
- lightrag-aio-network
restart: unless-stopped
# MongoDB for Document Status Storage
mongodb:
image: mongo:7
container_name: lightrag-aio-mongodb
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: admin_pass
MONGO_INITDB_DATABASE: lightrag
ports:
- "27017:27017"
volumes:
- mongodb_data:/data/db
- ./mongo-init-aio:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.runCommand('ping').ok", "--quiet"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-aio-network
restart: unless-stopped
# Redis for KV Storage
redis:
image: redis:7-alpine
container_name: lightrag-aio-redis
command: redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-aio-network
restart: unless-stopped
# Neo4j for Graph Storage
neo4j:
image: neo4j:5.15
container_name: lightrag-aio-neo4j
environment:
NEO4J_AUTH: neo4j/lightrag_neo4j_pass
NEO4J_PLUGINS: '["apoc"]'
NEO4J_dbms_security_procedures_unrestricted: apoc.*
NEO4J_dbms_memory_heap_initial__size: 512M
NEO4J_dbms_memory_heap_max__size: 1G
NEO4J_dbms_memory_pagecache_size: 512M
ports:
- "7474:7474"
- "7687:7687"
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
networks:
- lightrag-aio-network
restart: unless-stopped
# Qdrant Vector Database
qdrant:
image: qdrant/qdrant:latest
container_name: lightrag-aio-qdrant
environment:
QDRANT__SERVICE__HTTP_PORT: 6333
QDRANT__SERVICE__GRPC_PORT: 6334
QDRANT__LOG_LEVEL: INFO
ports:
- "6333:6333"
- "6334:6334"
volumes:
- qdrant_data:/qdrant/storage
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6333/health"]
interval: 30s
timeout: 20s
retries: 3
networks:
- lightrag-aio-network
restart: unless-stopped
volumes:
mongodb_data:
redis_data:
neo4j_data:
neo4j_logs:
qdrant_data:
networks:
lightrag-aio-network:
driver: bridge

122
docker-compose.balanced.yml Normal file
View file

@ -0,0 +1,122 @@
version: '3.8'
# Production Balanced Stack
# NetworkX + Qdrant + Redis + PostgreSQL
# Best for: Production deployments prioritizing simplicity
services:
# LightRAG Application
lightrag:
image: ghcr.io/hkuds/lightrag:latest
container_name: lightrag-balanced
env_file:
- .env
environment:
# Balanced Storage Configuration
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
LIGHTRAG_VECTOR_STORAGE: QdrantVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
# Service Connection Details
QDRANT_URL: http://qdrant:6333
REDIS_URI: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
POSTGRES_DATABASE: lightrag
# Performance settings
MAX_ASYNC: 6
MAX_TOKENS: 32768
ENABLE_LLM_CACHE: true
ENABLE_LLM_CACHE_FOR_EXTRACT: true
ports:
- "9621:9621"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
qdrant:
condition: service_healthy
volumes:
- ./data/inputs:/app/inputs
- ./data/rag_storage:/app/rag_storage
networks:
- lightrag-balanced-network
restart: unless-stopped
# PostgreSQL for Document Status Storage
postgres:
image: postgres:16
container_name: lightrag-balanced-postgres
environment:
POSTGRES_DB: lightrag
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lightrag_user -d lightrag"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-balanced-network
restart: unless-stopped
# Redis for KV Storage
redis:
image: redis:7-alpine
container_name: lightrag-balanced-redis
command: redis-server --appendonly yes --maxmemory 1gb --maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-balanced-network
restart: unless-stopped
# Qdrant Vector Database
qdrant:
image: qdrant/qdrant:latest
container_name: lightrag-balanced-qdrant
environment:
QDRANT__SERVICE__HTTP_PORT: 6333
QDRANT__SERVICE__GRPC_PORT: 6334
QDRANT__LOG_LEVEL: INFO
ports:
- "6333:6333"
- "6334:6334"
volumes:
- qdrant_data:/qdrant/storage
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6333/health"]
interval: 30s
timeout: 20s
retries: 3
networks:
- lightrag-balanced-network
restart: unless-stopped
volumes:
postgres_data:
redis_data:
qdrant_data:
networks:
lightrag-balanced-network:
driver: bridge

View file

@ -0,0 +1,81 @@
version: '3.8'
# Development & Testing Stack
# All file-based storage (NetworkX + NanoVector + JSON)
# Best for: Local development, testing, small deployments
services:
# LightRAG Application (File-based storage only)
lightrag:
image: ghcr.io/hkuds/lightrag:latest
container_name: lightrag-dev
env_file:
- .env
environment:
# Development Storage Configuration (All file-based)
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
LIGHTRAG_VECTOR_STORAGE: NanoVectorDBStorage
LIGHTRAG_KV_STORAGE: JsonKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: JsonDocStatusStorage
# Development settings
MAX_ASYNC: 2
MAX_TOKENS: 16384
ENABLE_LLM_CACHE: true
ENABLE_LLM_CACHE_FOR_EXTRACT: false
LOG_LEVEL: DEBUG
# No external database connections needed
ports:
- "9621:9621"
volumes:
- ./data/inputs:/app/inputs
- ./data/rag_storage:/app/rag_storage
# Mount additional volumes for file-based storage persistence
- ./data/dev-storage:/app/dev-storage
networks:
- lightrag-dev-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9621/health"]
interval: 30s
timeout: 10s
retries: 3
# Optional: Lightweight file browser for development
filebrowser:
image: filebrowser/filebrowser:latest
container_name: lightrag-dev-filebrowser
environment:
- FB_BASEURL=/files
ports:
- "8080:80"
volumes:
- ./data:/srv/data
networks:
- lightrag-dev-network
restart: unless-stopped
profiles:
- tools
# Optional: Lightweight monitoring for development
portainer:
image: portainer/portainer-ce:latest
container_name: lightrag-dev-portainer
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
networks:
- lightrag-dev-network
restart: unless-stopped
profiles:
- tools
volumes:
portainer_data:
networks:
lightrag-dev-network:
driver: bridge

View file

@ -0,0 +1,199 @@
version: '3.8'
# Production High-Performance Stack
# Neo4j + Milvus + Redis + PostgreSQL
# Best for: Large-scale production, complex graph analytics
services:
# LightRAG Application
lightrag:
image: ghcr.io/hkuds/lightrag:latest
container_name: lightrag-hp
env_file:
- .env
environment:
# High-Performance Storage Configuration
LIGHTRAG_GRAPH_STORAGE: Neo4JStorage
LIGHTRAG_VECTOR_STORAGE: MilvusVectorDBStorage
LIGHTRAG_KV_STORAGE: RedisKVStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
# Service Connection Details
NEO4J_URI: bolt://neo4j:7687
NEO4J_USERNAME: neo4j
NEO4J_PASSWORD: lightrag_neo4j_pass
MILVUS_URI: http://milvus-standalone:19530
MILVUS_DB_NAME: lightrag
REDIS_URI: redis://redis:6379
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
POSTGRES_DATABASE: lightrag
# Performance optimizations
MAX_ASYNC: 8
MAX_TOKENS: 32768
ENABLE_LLM_CACHE: true
ENABLE_LLM_CACHE_FOR_EXTRACT: true
ports:
- "9621:9621"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
neo4j:
condition: service_started
milvus-standalone:
condition: service_healthy
volumes:
- ./data/inputs:/app/inputs
- ./data/rag_storage:/app/rag_storage
networks:
- lightrag-hp-network
restart: unless-stopped
# PostgreSQL for Document Status Storage
postgres:
image: postgres:16
container_name: lightrag-hp-postgres
environment:
POSTGRES_DB: lightrag
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
POSTGRES_INITDB_ARGS: "--encoding=UTF-8"
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lightrag_user -d lightrag"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-hp-network
restart: unless-stopped
# Redis for KV Storage
redis:
image: redis:7-alpine
container_name: lightrag-hp-redis
command: redis-server --appendonly yes --maxmemory 2gb --maxmemory-policy allkeys-lru
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lightrag-hp-network
restart: unless-stopped
# Neo4j for Graph Storage
neo4j:
image: neo4j:5.15
container_name: lightrag-hp-neo4j
environment:
NEO4J_AUTH: neo4j/lightrag_neo4j_pass
NEO4J_PLUGINS: '["apoc"]'
NEO4J_dbms_security_procedures_unrestricted: apoc.*
NEO4J_dbms_memory_heap_initial__size: 1G
NEO4J_dbms_memory_heap_max__size: 2G
NEO4J_dbms_memory_pagecache_size: 1G
ports:
- "7474:7474"
- "7687:7687"
volumes:
- neo4j_data:/data
- neo4j_logs:/logs
networks:
- lightrag-hp-network
restart: unless-stopped
# Milvus Dependencies
etcd:
image: quay.io/coreos/etcd:v3.5.5
container_name: lightrag-hp-milvus-etcd
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
volumes:
- etcd_data:/etcd
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 30s
timeout: 20s
retries: 3
networks:
- lightrag-hp-network
restart: unless-stopped
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
container_name: lightrag-hp-milvus-minio
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
command: minio server /minio_data --console-address ":9001"
volumes:
- minio_data:/minio_data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
networks:
- lightrag-hp-network
restart: unless-stopped
# Milvus Vector Database
milvus-standalone:
image: milvusdb/milvus:v2.3.10
container_name: lightrag-hp-milvus
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
volumes:
- milvus_data:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
depends_on:
etcd:
condition: service_healthy
minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
start_period: 90s
timeout: 20s
retries: 3
networks:
- lightrag-hp-network
restart: unless-stopped
volumes:
postgres_data:
redis_data:
neo4j_data:
neo4j_logs:
etcd_data:
minio_data:
milvus_data:
networks:
lightrag-hp-network:
driver: bridge

View file

@ -0,0 +1,55 @@
version: '3.8'
services:
postgres:
image: pgvector/pgvector:pg16
container_name: lightrag-postgres-minimal
environment:
POSTGRES_DB: lightrag
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lightrag_user -d lightrag"]
interval: 10s
timeout: 5s
retries: 5
lightrag:
image: ghcr.io/hkuds/lightrag:latest
container_name: lightrag-minimal
env_file:
- .env
environment:
# Pass API key from host
OPENAI_API_KEY: ${OPENAI_API_KEY}
LLM_BINDING_API_KEY: ${OPENAI_API_KEY}
EMBEDDING_BINDING_API_KEY: ${OPENAI_API_KEY}
# Use mixed storage - PostgreSQL for vectors and KV, NetworkX for graph
LIGHTRAG_KV_STORAGE: PGKVStorage
LIGHTRAG_VECTOR_STORAGE: PGVectorStorage
LIGHTRAG_DOC_STATUS_STORAGE: PGDocStatusStorage
LIGHTRAG_GRAPH_STORAGE: NetworkXStorage
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
POSTGRES_USER: lightrag_user
POSTGRES_PASSWORD: lightrag_pass
POSTGRES_DATABASE: lightrag
ports:
- "9621:9621"
depends_on:
postgres:
condition: service_healthy
volumes:
- ./data/inputs:/app/inputs
- ./data/rag_storage:/app/rag_storage
volumes:
postgres_data:
networks:
default:
name: lightrag-minimal-network

View file

@ -0,0 +1,6 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 12.0.1
digest: sha256:2f6a5e813010d3cccac288a6f5a0544fdc55adcc474b7ba0bc8fe0cdf1f8f440
generated: "2025-06-18T10:39:04.357456+03:00"

View file

@ -0,0 +1,13 @@
apiVersion: v2
name: lightrag-minimal
description: A minimal Helm chart for LightRAG with PostgreSQL and NetworkX storage
type: application
version: 0.1.0
appVersion: "1.0.0"
maintainers:
- name: Apolo Copilot Team
dependencies:
- name: postgresql
version: "~12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled

View file

@ -0,0 +1,379 @@
# LightRAG Minimal Helm Chart
This Helm chart deploys a production-ready LightRAG setup with PostgreSQL and pgvector support for Kubernetes environments. It has been tested and validated with complete teardown/rebuild cycles.
## Configuration
This chart provides a comprehensive LightRAG deployment with:
- **PostgreSQL with pgvector**: For vector storage, KV storage, and document status using `pgvector/pgvector:pg16` image
- **NetworkX**: For graph storage (local, no external database required)
- **Persistent Storage**: For data persistence across pod restarts
- **Health Checks**: Automated health monitoring
- **API Endpoints**: Document upload, query, and management
- **Conservative Concurrency**: Optimized OpenAI API usage to prevent rate limiting
## Prerequisites
- Kubernetes 1.19+ (tested with Minikube)
- Helm 3.0+ with Bitnami repository
- OpenAI API key
- Storage class that supports ReadWriteOnce (standard storage class works)
- Minimum resources: 2 CPU cores, 4Gi memory available
## Validated Installation Steps
### Development/Local Setup (Minikube)
1. **Prepare Helm repositories**:
```bash
cd lightrag-minimal
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependency update
```
2. **Set your OpenAI API key**:
```bash
export OPENAI_API_KEY="your-openai-api-key-here"
```
3. **Deploy for development**:
```bash
# Substitute environment variables and deploy
envsubst < values-dev.yaml > values-dev-final.yaml
helm install lightrag-minimal . \
-f values-dev-final.yaml \
--namespace lightrag \
--create-namespace
# Wait for deployment
kubectl wait --namespace lightrag \
--for=condition=ready pod \
-l app.kubernetes.io/name=postgresql \
--timeout=120s
kubectl wait --namespace lightrag \
--for=condition=ready pod \
-l app.kubernetes.io/name=lightrag-minimal \
--timeout=120s
# Clean up temporary file
rm values-dev-final.yaml
# Start port forwarding
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621 &
```
### Production Setup
```bash
# Customize values-prod.yaml first (domain, storage classes, etc.)
envsubst < values-prod.yaml > values-prod-final.yaml
helm install lightrag-minimal . \
-f values-prod-final.yaml \
--namespace lightrag \
--create-namespace
rm values-prod-final.yaml
```
## Configuration Options
### Validated Environment Configuration
Both `values-dev.yaml` and `values-prod.yaml` include these critical settings:
```yaml
env:
# OpenAI API Configuration (REQUIRED)
LLM_BINDING: "openai"
LLM_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_BINDING: "openai"
EMBEDDING_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_MODEL: "text-embedding-ada-002"
EMBEDDING_DIM: "1536"
# Conservative concurrency (prevents API errors)
MAX_ASYNC: "4"
MAX_PARALLEL_INSERT: "2"
# LLM Configuration
ENABLE_LLM_CACHE: "true"
ENABLE_LLM_CACHE_FOR_EXTRACT: "true"
TIMEOUT: "240"
TEMPERATURE: "0"
MAX_TOKENS: "32768"
```
### PostgreSQL Configuration
```yaml
postgresql:
# CRITICAL: Use pgvector image for vector support
image:
registry: docker.io
repository: pgvector/pgvector
tag: pg16
auth:
password: "your-secure-password"
```
### Development vs Production
| Setting | Development | Production |
|---------|-------------|------------|
| Resources | 1 CPU, 2Gi RAM | 4 CPU, 8Gi RAM |
| Storage | 5Gi | 100Gi |
| Replicas | 1 | 2-10 (autoscaling) |
| Ingress | Disabled | Enabled with TLS |
| Storage Class | Default | `fast-ssd` |
## Accessing LightRAG
### Development Access
```bash
# Port forward (included in installation steps above)
kubectl port-forward --namespace lightrag svc/lightrag-minimal 9621:9621 &
# Access URLs
echo "Web UI: http://localhost:9621/webui"
echo "API Docs: http://localhost:9621/docs"
echo "Health Check: http://localhost:9621/health"
```
### Verify Deployment
```bash
# Check health
curl http://localhost:9621/health
# Expected response:
{
"status": "healthy",
"configuration": {
"llm_model": "gpt-4o",
"kv_storage": "PGKVStorage",
"vector_storage": "PGVectorStorage",
"graph_storage": "NetworkXStorage"
}
}
```
### Production (Ingress)
Production uses ingress with TLS (see `values-prod.yaml`):
```yaml
ingress:
enabled: true
className: "nginx"
hosts:
- host: lightrag.yourdomain.com
```
## Monitoring
### Check Deployment Status
```bash
kubectl get pods -l app.kubernetes.io/name=lightrag-minimal
kubectl get services -l app.kubernetes.io/name=lightrag-minimal
```
### View Logs
```bash
kubectl logs -l app.kubernetes.io/name=lightrag-minimal -f
```
### Health Checks
The deployment includes health checks on `/health` endpoint.
## Scaling
For production workloads, consider enabling autoscaling:
```yaml
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
```
## Upgrading
```bash
helm upgrade lightrag-minimal ./lightrag-minimal -f values-prod.yaml
```
## Uninstalling
```bash
helm uninstall lightrag-minimal
```
**Note**: This will delete all data unless you have persistent volumes with a retain policy.
## Document Loading
After successful deployment, load your documentation using the included loader. The loader supports two reference modes:
### Reference Modes
**Files Mode (Default)**: Uses file paths in citations
```bash
# Install dependencies (if needed)
pip install httpx
# Load documents with file path references
python ../../../load_docs.py /path/to/your/docs --endpoint http://localhost:9621
# Example with relative path
python ../../../load_docs.py ../docs --endpoint http://localhost:9621
```
**URLs Mode**: Uses website URLs in citations (recommended for public documentation)
```bash
# Load Apolo documentation with URL references
python ../../../load_docs.py ../apolo-copilot/docs/official-apolo-documentation/docs \
--mode urls --base-url https://docs.apolo.us/index/ --endpoint http://localhost:9621
# Load custom documentation with URL references
python ../../../load_docs.py /path/to/docs \
--mode urls --base-url https://your-docs.example.com/docs/ --endpoint http://localhost:9621
```
### Benefits of URL Mode
- **Clickable References**: Query responses include direct links to source documentation
- **Better User Experience**: Users can easily navigate to original content
- **Professional Citations**: References point to live documentation sites
### ⚠️ Important: File Structure Requirements for URL Mode
**Your local file structure must match your documentation site's URL structure:**
```
# Example: GitBook documentation site
docs/
├── getting-started/
│ ├── installation.md → https://docs.example.com/getting-started/installation
│ └── first-steps.md → https://docs.example.com/getting-started/first-steps
├── administration/
│ ├── README.md → https://docs.example.com/administration
│ └── setup.md → https://docs.example.com/administration/setup
└── README.md → https://docs.example.com/
```
**Quick Setup Guide:**
1. **Analyze your docs site**: Visit URLs and note the path structure
2. **Create matching directories**: `mkdir -p docs/{section1,section2,section3}`
3. **Organize markdown files**: Place files to match URL paths (remove `.md` from URLs)
4. **Verify mapping**: Test a few URLs manually before loading
**URL Mapping Rules:**
- `.md` extension is removed from URLs
- `README.md` files map to their directory URL
- Subdirectories become URL path segments
- File and folder names should match URL slugs exactly
### Expected Output
Both modes produce similar output with different reference formats:
```bash
🚀 Loading Documentation into LightRAG
============================================================
📁 Documentation path: /path/to/docs
🔧 Reference mode: urls
🌐 Base URL: https://docs.apolo.us/index/
🌐 LightRAG endpoint: http://localhost:9621
✅ LightRAG is healthy: healthy
📚 Found 58 markdown files
🔧 Mode: urls
🌐 Base URL: https://docs.apolo.us/index/
📊 Total content: 244,400 characters
📊 Average length: 4,287 characters
🔄 Starting to load documents...
✅ Loaded: Document Title
📈 Progress: 10/58 (10 success, 0 failed)
...
✅ Loading complete!
📊 Successful: 58
📊 Failed: 0
✅ Query successful!
```
### Query Response Examples
**Files Mode References:**
```
### References
- [DC] getting-started/installation.md
- [KG] administration/cluster-setup.md
```
**URLs Mode References:**
```
### References
- [DC] https://docs.apolo.us/index/getting-started/installation
- [KG] https://docs.apolo.us/index/administration/cluster-setup
```
## Troubleshooting
### Common Issues
**Issue: `UnsupportedProtocol: Request URL is missing protocol`**
- **Solution**: Ensure `LLM_BINDING_HOST` and `EMBEDDING_BINDING_HOST` are set to `https://api.openai.com/v1`
**Issue: Document processing failures with API connection errors**
- **Solution**: Reduce concurrency with `MAX_ASYNC: "4"` and `MAX_PARALLEL_INSERT: "2"`
**Issue: pgvector extension missing**
- **Solution**: Ensure using `pgvector/pgvector:pg16` image, not standard PostgreSQL
### Validation Commands
```bash
# Check all pods are running
kubectl get pods --namespace lightrag
# Verify API connectivity
kubectl exec --namespace lightrag \
$(kubectl get pod -l app.kubernetes.io/name=lightrag-minimal --namespace lightrag -o jsonpath='{.items[0].metadata.name}') \
-- python -c "import requests; print(requests.get('https://api.openai.com/v1/models', headers={'Authorization': 'Bearer ' + open('/dev/null').read()}, timeout=5).status_code)"
# Check document processing status
curl http://localhost:9621/documents | jq '.statuses | to_entries | map({status: .key, count: (.value | length)})'
```
## Clean Teardown and Rebuild
For testing or redeployment:
```bash
# Complete teardown
helm uninstall lightrag-minimal --namespace lightrag
kubectl delete namespace lightrag
# Rebuild (repeat installation steps above)
# This process has been validated multiple times
```
## Validated Features
**Pure Helm Deployment** - No manual kubectl apply commands needed
**PostgreSQL with pgvector** - Automatic extension creation via proper image
**Environment Flexibility** - Separate dev/prod configurations
**Document Loading** - Working API with `file_source` parameter
**Conservative Concurrency** - Prevents OpenAI API rate limiting
**Health Monitoring** - Comprehensive health checks and status endpoints
**Persistent Storage** - Data survives pod restarts and cluster updates
## Comparison with Docker Compose
| Feature | Docker Compose | Helm Chart |
|---------|----------------|------------|
| PostgreSQL | pgvector/pgvector:pg16 | Same image via subchart |
| Concurrency | MAX_ASYNC=4 | Same settings |
| API Configuration | .env file | Environment variables |
| Scaling | Single container | Kubernetes autoscaling |
| Persistence | Local volumes | PersistentVolumeClaims |
| Monitoring | Manual | Kubernetes native |
This chart maintains the same conservative, working configuration as the Docker Compose setup while adding Kubernetes-native features for production deployment.

View file

@ -0,0 +1,54 @@
✅ LightRAG deployment successful!
1. Wait for all pods to be ready:
kubectl wait --namespace {{ .Release.Namespace }} --for=condition=ready pod -l app.kubernetes.io/name=postgresql --timeout=120s
kubectl wait --namespace {{ .Release.Namespace }} --for=condition=ready pod -l app.kubernetes.io/name={{ include "lightrag-minimal.name" . }} --timeout=120s
2. Access your application:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
🌐 Web UI: http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}webui
📚 API Docs: http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}docs
{{- end }}
{{- end }}
{{- else }}
# Start port forwarding (run in background):
kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ include "lightrag-minimal.fullname" . }} 9621:9621 &
🌐 Web UI: http://localhost:9621/webui
📚 API Docs: http://localhost:9621/docs
🔍 Health Check: http://localhost:9621/health
{{- end }}
3. Verify deployment health:
curl http://localhost:9621/health
# Expected: {"status": "healthy", "configuration": {...}}
4. Load your documents:
# Install httpx if needed: pip install httpx
# Files mode (file path references) - Default
python ../../../load_docs.py /path/to/your/docs --endpoint http://localhost:9621
# URLs mode (website URL references) - Recommended for public docs
# Note: Local file structure must match your docs site URL structure
python ../../../load_docs.py /path/to/docs --mode urls \
--base-url https://docs.example.com/ --endpoint http://localhost:9621
5. Monitor your deployment:
# Check pods status
kubectl get pods --namespace {{ .Release.Namespace }}
# View logs
kubectl logs --namespace {{ .Release.Namespace }} -l app.kubernetes.io/name={{ include "lightrag-minimal.name" . }} -f
Configuration Summary:
🗄️ Storage: PostgreSQL with pgvector + NetworkX graph storage
🔒 Persistence: {{ if .Values.persistence.ragStorage.enabled }}Enabled{{ else }}Disabled{{ end }} ({{ .Values.persistence.ragStorage.size }} storage)
💻 Resources: {{ .Values.resources.limits.cpu }} CPU, {{ .Values.resources.limits.memory }} memory
🐘 PostgreSQL: pgvector/pgvector:pg16 with {{ .Values.postgresql.primary.persistence.size }} storage
🤖 LLM Model: {{ .Values.env.LLM_MODEL }}
📊 Concurrency: MAX_ASYNC={{ .Values.env.MAX_ASYNC }}, MAX_PARALLEL_INSERT={{ .Values.env.MAX_PARALLEL_INSERT }}
📖 For detailed usage instructions, see the README.md in the chart directory.

View file

@ -0,0 +1,80 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "lightrag-minimal.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "lightrag-minimal.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "lightrag-minimal.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "lightrag-minimal.labels" -}}
helm.sh/chart: {{ include "lightrag-minimal.chart" . }}
{{ include "lightrag-minimal.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "lightrag-minimal.selectorLabels" -}}
app.kubernetes.io/name: {{ include "lightrag-minimal.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "lightrag-minimal.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "lightrag-minimal.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the secret
*/}}
{{- define "lightrag-minimal.secretName" -}}
{{- printf "%s-secrets" (include "lightrag-minimal.fullname" .) }}
{{- end }}
{{/*
PostgreSQL connection string
*/}}
{{- define "lightrag-minimal.postgresqlHost" -}}
{{- if .Values.postgresql.enabled }}
{{- printf "%s-postgresql" (include "lightrag-minimal.fullname" .) }}
{{- else }}
{{- .Values.env.POSTGRES_HOST }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,157 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "lightrag-minimal.fullname" . }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "lightrag-minimal.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "lightrag-minimal.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "lightrag-minimal.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
env:
# Basic server configuration
- name: HOST
value: {{ .Values.env.HOST | quote }}
- name: PORT
value: {{ .Values.env.PORT | quote }}
# Web UI configuration
- name: WEBUI_TITLE
value: {{ .Values.env.WEBUI_TITLE | quote }}
- name: WEBUI_DESCRIPTION
value: {{ .Values.env.WEBUI_DESCRIPTION | quote }}
# LLM configuration
- name: LLM_BINDING
value: {{ .Values.env.LLM_BINDING | quote }}
- name: LLM_MODEL
value: {{ .Values.env.LLM_MODEL | quote }}
- name: LLM_BINDING_HOST
value: {{ .Values.env.LLM_BINDING_HOST | quote }}
- name: LLM_BINDING_API_KEY
valueFrom:
secretKeyRef:
name: {{ include "lightrag-minimal.secretName" . }}
key: openai-api-key
# Embedding configuration
- name: EMBEDDING_BINDING
value: {{ .Values.env.EMBEDDING_BINDING | quote }}
- name: EMBEDDING_MODEL
value: {{ .Values.env.EMBEDDING_MODEL | quote }}
- name: EMBEDDING_DIM
value: {{ .Values.env.EMBEDDING_DIM | quote }}
- name: EMBEDDING_BINDING_API_KEY
valueFrom:
secretKeyRef:
name: {{ include "lightrag-minimal.secretName" . }}
key: openai-api-key
# Storage configuration
- name: LIGHTRAG_KV_STORAGE
value: {{ .Values.env.LIGHTRAG_KV_STORAGE | quote }}
- name: LIGHTRAG_VECTOR_STORAGE
value: {{ .Values.env.LIGHTRAG_VECTOR_STORAGE | quote }}
- name: LIGHTRAG_DOC_STATUS_STORAGE
value: {{ .Values.env.LIGHTRAG_DOC_STATUS_STORAGE | quote }}
- name: LIGHTRAG_GRAPH_STORAGE
value: {{ .Values.env.LIGHTRAG_GRAPH_STORAGE | quote }}
# PostgreSQL configuration
- name: POSTGRES_HOST
value: {{ include "lightrag-minimal.postgresqlHost" . | quote }}
- name: POSTGRES_PORT
value: {{ .Values.env.POSTGRES_PORT | quote }}
- name: POSTGRES_USER
value: {{ .Values.env.POSTGRES_USER | quote }}
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "lightrag-minimal.secretName" . }}
key: postgres-password
- name: POSTGRES_DATABASE
value: {{ .Values.env.POSTGRES_DATABASE | quote }}
- name: POSTGRES_WORKSPACE
value: {{ .Values.env.POSTGRES_WORKSPACE | quote }}
{{- if .Values.healthCheck.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.healthCheck.path }}
port: http
initialDelaySeconds: {{ .Values.healthCheck.initialDelaySeconds }}
periodSeconds: {{ .Values.healthCheck.periodSeconds }}
timeoutSeconds: {{ .Values.healthCheck.timeoutSeconds }}
failureThreshold: {{ .Values.healthCheck.failureThreshold }}
readinessProbe:
httpGet:
path: {{ .Values.healthCheck.path }}
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.persistence.enabled }}
volumeMounts:
- name: rag-storage
mountPath: /app/rag_storage
- name: inputs
mountPath: /app/inputs
{{- end }}
{{- if .Values.persistence.enabled }}
volumes:
- name: rag-storage
persistentVolumeClaim:
claimName: {{ include "lightrag-minimal.fullname" . }}-rag-storage
- name: inputs
persistentVolumeClaim:
claimName: {{ include "lightrag-minimal.fullname" . }}-inputs
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View file

@ -0,0 +1,28 @@
{{- if and .Values.ingress.enabled .Values.ingress.forwardAuth.enabled }}
apiVersion: traefik.io/v1alpha1 # Use traefik.containo.us/v1alpha1 if using older Traefik
kind: Middleware
metadata:
# Use the helper for the Middleware resource name
name: {{ .Values.ingress.forwardAuth.name | quote }}
# Middleware MUST be in the same namespace as the Ingress that uses it
namespace: {{ .Release.Namespace }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
forwardAuth:
# Required fields from values.yaml
address: {{ .Values.ingress.forwardAuth.address | quote }}
trustForwardHeader: {{ .Values.ingress.forwardAuth.trustForwardHeader | default true }}
# Optional headers to send to the authentication service
{{- if .Values.ingress.forwardAuth.authRequestHeaders }}
authRequestHeaders:
{{- toYaml .Values.ingress.forwardAuth.authRequestHeaders | nindent 6 }}
{{- end }}
# Optional headers to copy from the authentication service's response
{{- if .Values.ingress.forwardAuth.authResponseHeaders }}
authResponseHeaders:
{{- toYaml .Values.ingress.forwardAuth.authResponseHeaders | nindent 6 }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,32 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "lightrag-minimal.fullname" . }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "lightrag-minimal.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,44 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "lightrag-minimal.fullname" . }}
labels:
{{- include "lightrag-minimal.labels" $ | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- if .Values.ingress.hosts }}
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "lightrag-minimal.fullname" $ }}
port:
name: http
{{- end }}
{{- end }}
{{- else }}
- host: {{ .Release.Namespace }}.apps.{{ .Values.ingress.clusterName }}.org.neu.ro
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "lightrag-minimal.fullname" $ }}
port:
name: http
{{- end }}
{{- end }}

View file

@ -0,0 +1,35 @@
{{- if .Values.persistence.enabled }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "lightrag-minimal.fullname" . }}-rag-storage
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.ragStorage.accessMode }}
resources:
requests:
storage: {{ .Values.persistence.ragStorage.size }}
{{- if .Values.persistence.ragStorage.storageClass }}
storageClassName: {{ .Values.persistence.ragStorage.storageClass }}
{{- end }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "lightrag-minimal.fullname" . }}-inputs
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.inputs.accessMode }}
resources:
requests:
storage: {{ .Values.persistence.inputs.size }}
{{- if .Values.persistence.inputs.storageClass }}
storageClassName: {{ .Values.persistence.inputs.storageClass }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ include "lightrag-minimal.secretName" . }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
type: Opaque
data:
openai-api-key: {{ .Values.secrets.openaiApiKey | b64enc | quote }}
postgres-password: {{ .Values.postgresql.auth.password | b64enc | quote }}

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "lightrag-minimal.fullname" . }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
protocol: TCP
name: http
selector:
{{- include "lightrag-minimal.selectorLabels" . | nindent 4 }}

View file

@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "lightrag-minimal.serviceAccountName" . }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,15 @@
{{- /* Create strip-headers Middleware only if ingress is enabled */}}
{{- if and .Values.ingress.enabled .Values.ingress.forwardAuth.enabled }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: strip-headers
namespace: {{ .Release.Namespace }}
labels:
{{- include "lightrag-minimal.labels" . | nindent 4 }}
spec:
headers:
customRequestHeaders:
Authorization: "" # Empty value removes header
Cookie: ""
{{- end }}

View file

@ -0,0 +1,75 @@
# Development/Minikube Values
# Optimized for local development with reduced resource requirements
# Environment configuration
env:
LLM_MODEL: "gpt-4o"
WEBUI_TITLE: "Apolo Copilot - LightRAG (Development)"
WEBUI_DESCRIPTION: "Development LightRAG for Apolo Documentation"
# OpenAI API Configuration
LLM_BINDING: "openai"
LLM_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_BINDING: "openai"
EMBEDDING_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_MODEL: "text-embedding-ada-002"
EMBEDDING_DIM: "1536"
# Concurrency settings (conservative for API stability)
MAX_ASYNC: "4"
MAX_PARALLEL_INSERT: "2"
# LLM Configuration
ENABLE_LLM_CACHE: "true"
ENABLE_LLM_CACHE_FOR_EXTRACT: "true"
TIMEOUT: "240"
TEMPERATURE: "0"
MAX_TOKENS: "32768"
# Reduced resources for local development
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 250m
memory: 512Mi
# Smaller storage for development
persistence:
ragStorage:
size: 5Gi
inputs:
size: 2Gi
# PostgreSQL with reduced resources
postgresql:
# Use pgvector image for vector support
image:
registry: docker.io
repository: pgvector/pgvector
tag: pg16
auth:
password: "dev-lightrag-pass"
primary:
persistence:
size: 5Gi
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 100m
memory: 256Mi
# OpenAI API key (set via environment variable)
secrets:
openaiApiKey: "${OPENAI_API_KEY}"
# Disable ingress for local development (use port-forward)
ingress:
enabled: false
# Disable autoscaling for development
autoscaling:
enabled: false

View file

@ -0,0 +1,120 @@
# Production Values
# Optimized for production with HA, scaling, and monitoring
# Environment configuration
env:
LLM_MODEL: "gpt-4o"
WEBUI_TITLE: "Apolo Copilot - LightRAG"
WEBUI_DESCRIPTION: "Production LightRAG for Apolo Documentation"
# OpenAI API Configuration
LLM_BINDING: "openai"
LLM_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_BINDING: "openai"
EMBEDDING_BINDING_HOST: "https://api.openai.com/v1"
EMBEDDING_MODEL: "text-embedding-ada-002"
EMBEDDING_DIM: "1536"
# Concurrency settings (conservative for API stability)
MAX_ASYNC: "4"
MAX_PARALLEL_INSERT: "2"
# LLM Configuration
ENABLE_LLM_CACHE: "true"
ENABLE_LLM_CACHE_FOR_EXTRACT: "true"
TIMEOUT: "240"
TEMPERATURE: "0"
MAX_TOKENS: "32768"
# Production resources
resources:
limits:
cpu: 4000m
memory: 8Gi
requests:
cpu: 1000m
memory: 2Gi
# Production storage with fast storage class
persistence:
ragStorage:
size: 100Gi
storageClass: "fast-ssd" # Adjust for your cluster
inputs:
size: 50Gi
storageClass: "fast-ssd"
# PostgreSQL with production resources
postgresql:
# Use pgvector image for vector support
image:
registry: docker.io
repository: pgvector/pgvector
tag: pg16
auth:
password: "secure-production-password" # Use external secret in real production
primary:
persistence:
size: 200Gi
storageClass: "fast-ssd"
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
# OpenAI API key (use external secret manager in production)
secrets:
openaiApiKey: "${OPENAI_API_KEY}"
# Enable ingress for production
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "100m"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: lightrag.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: lightrag-tls
hosts:
- lightrag.yourdomain.com
# Enable autoscaling for production
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
# Production security context
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
podSecurityContext:
seccompProfile:
type: RuntimeDefault
# Node affinity for production workloads
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- lightrag-minimal
topologyKey: kubernetes.io/hostname

View file

@ -0,0 +1,162 @@
# LightRAG Minimal Configuration
# Matches docker-compose.minimal.yml setup
replicaCount: 1
image:
repository: ghcr.io/hkuds/lightrag
tag: latest
pullPolicy: IfNotPresent
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 9621
targetPort: 9621
ingress:
enabled: false
className: ""
clusterName: ""
annotations: {}
hosts:
- host: lightrag-minimal.local
paths:
- path: /
pathType: Prefix
tls: []
forwardAuth:
enabled: false
# name: forwardauth
# address: http://forwardauth:8080
# trustForwardHeader: true
# authRequestHeaders:
# - "Cookie"
# - "Authorization"
# Resource limits and requests
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 500m
memory: 1Gi
# Persistence for data volumes
persistence:
enabled: true
ragStorage:
accessMode: ReadWriteOnce
size: 20Gi
storageClass: ""
inputs:
accessMode: ReadWriteOnce
size: 10Gi
storageClass: ""
# PostgreSQL configuration (embedded chart with pgvector)
postgresql:
enabled: true
# Use pgvector image instead of standard PostgreSQL
image:
registry: docker.io
repository: pgvector/pgvector
tag: pg16
auth:
database: lightrag
username: lightrag_user
password: lightrag_pass
primary:
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 250m
memory: 512Mi
initdb:
scripts:
00-pgvector.sql: |
CREATE EXTENSION IF NOT EXISTS vector;
# LightRAG Environment Configuration
# This matches the minimal docker-compose setup
env:
# Server configuration
HOST: "0.0.0.0"
PORT: "9621"
# Web UI configuration
WEBUI_TITLE: "Apolo Copilot - LightRAG"
WEBUI_DESCRIPTION: "Simple and Fast Graph Based RAG System for Apolo Documentation"
# LLM configuration
LLM_BINDING: "openai"
LLM_MODEL: "gpt-4o-mini"
LLM_BINDING_HOST: ""
# LLM_BINDING_API_KEY: Set via secret
# Embedding configuration
EMBEDDING_BINDING: "openai"
EMBEDDING_MODEL: "text-embedding-ada-002"
EMBEDDING_DIM: "1536"
# EMBEDDING_BINDING_API_KEY: Set via secret
# Storage configuration - Minimal setup
LIGHTRAG_KV_STORAGE: "PGKVStorage"
LIGHTRAG_VECTOR_STORAGE: "PGVectorStorage"
LIGHTRAG_DOC_STATUS_STORAGE: "PGDocStatusStorage"
LIGHTRAG_GRAPH_STORAGE: "NetworkXStorage" # Local storage, no external DB needed
# PostgreSQL connection (internal service)
POSTGRES_HOST: "{{ include \"lightrag-minimal.fullname\" . }}-postgresql"
POSTGRES_PORT: "5432"
POSTGRES_USER: "lightrag_user"
POSTGRES_DATABASE: "lightrag"
POSTGRES_WORKSPACE: "default"
# Secret configuration for API keys
secrets:
# Create a secret with your OpenAI API key
openaiApiKey: "" # Set this or create manually
# Node selector and affinity
nodeSelector: {}
tolerations: []
affinity: {}
# Security context
securityContext: {}
podSecurityContext: {}
# Service account
serviceAccount:
create: true
annotations: {}
name: ""
# Pod annotations
podAnnotations: {}
# Auto scaling (disabled by default for minimal setup)
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 3
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
# Health checks
healthCheck:
enabled: true
path: "/health"
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 5

View file

@ -19,7 +19,7 @@ spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: IfNotPresent
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.env.PORT }}

View file

@ -0,0 +1,28 @@
{{- if and .Values.ingress.enabled .Values.ingress.forwardAuth.enabled }}
apiVersion: traefik.io/v1alpha1 # Use traefik.containo.us/v1alpha1 if using older Traefik
kind: Middleware
metadata:
# Use the helper for the Middleware resource name
name: {{ .Values.ingress.forwardAuth.name | quote }}
# Middleware MUST be in the same namespace as the Ingress that uses it
namespace: {{ .Release.Namespace }}
labels:
{{- include "lightrag.labels" . | nindent 4 }}
spec:
forwardAuth:
# Required fields from values.yaml
address: {{ .Values.ingress.forwardAuth.address | quote }}
trustForwardHeader: {{ .Values.ingress.forwardAuth.trustForwardHeader | default true }}
# Optional headers to send to the authentication service
{{- if .Values.ingress.forwardAuth.authRequestHeaders }}
authRequestHeaders:
{{- toYaml .Values.ingress.forwardAuth.authRequestHeaders | nindent 6 }}
{{- end }}
# Optional headers to copy from the authentication service's response
{{- if .Values.ingress.forwardAuth.authResponseHeaders }}
authResponseHeaders:
{{- toYaml .Values.ingress.forwardAuth.authResponseHeaders | nindent 6 }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,54 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "lightrag.fullname" . }}
labels:
{{- include "lightrag.labels" $ | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
rules:
{{- if .Values.ingress.hosts }}
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "lightrag.fullname" $ }}
port:
name: http
{{- end }}
{{- end }}
{{- else }}
- host: {{ .Release.Namespace }}.apps.{{ .Values.ingress.clusterName }}.org.neu.ro
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "lightrag.fullname" $ }}
port:
name: http
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,15 @@
{{- /* Create strip-headers Middleware only if ingress is enabled */}}
{{- if and .Values.ingress.enabled .Values.ingress.forwardAuth.enabled }}
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: strip-headers
namespace: {{ .Release.Namespace }}
labels:
{{- include "lightrag.labels" . | nindent 4 }}
spec:
headers:
customRequestHeaders:
Authorization: "" # Empty value removes header
Cookie: ""
{{- end }}

View file

@ -3,11 +3,35 @@ replicaCount: 1
image:
repository: ghcr.io/hkuds/lightrag
tag: latest
pullPolicy: IfNotPresent
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 9621
ingress:
enabled: false
className: ""
clusterName: ""
annotations: {}
hosts:
- host: lightrag.local
paths:
- path: /
pathType: Prefix
tls: []
forwardAuth:
enabled: false
# name: forwardauth
# address: http://forwardauth:8080
# trustForwardHeader: true
# authRequestHeaders:
# - "Cookie"
# - "Authorization"
resources:
limits:
cpu: 1000m

319
load_docs.py Executable file
View file

@ -0,0 +1,319 @@
#!/usr/bin/env python3
"""
Simplified script to load documentation into LightRAG
Loads all markdown files from a directory structure
"""
import asyncio
import httpx
import argparse
import sys
from pathlib import Path
from typing import List, Optional
async def load_document_to_lightrag(
content: str,
title: str,
doc_url: str,
endpoint: str = "http://localhost:9621"
) -> bool:
"""Load a single document to LightRAG with URL reference"""
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{endpoint}/documents/text",
headers={"Content-Type": "application/json"},
json={
"text": content,
"file_source": doc_url
}
)
if response.status_code == 200:
print(f"✅ Loaded: {title}")
return True
else:
print(f"❌ Failed to load {title}: {response.status_code}")
if response.status_code == 500:
try:
error_detail = response.json()
print(f" Error details: {error_detail}")
except:
print(f" Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error loading {title}: {e}")
return False
def convert_file_path_to_url(relative_path: str, base_url: str) -> str:
"""Convert file path to documentation URL"""
# Ensure base URL ends with /
if not base_url.endswith('/'):
base_url += '/'
# Handle special cases
if relative_path in ["README.md", "SUMMARY.md"]:
return base_url.rstrip('/')
# Remove .md extension and convert path
url_path = relative_path.replace(".md", "")
# Handle README files in subdirectories - they map to the directory URL
if url_path.endswith("/README"):
url_path = url_path[:-7] # Remove "/README"
# Clean up any double slashes
url_path = url_path.strip("/")
return f"{base_url}{url_path}"
def load_markdown_files(docs_path: Path, mode: str = "files", base_url: str = None) -> List[tuple]:
"""Load all markdown files from directory structure
Args:
docs_path: Path to documentation directory
mode: 'files' for file paths, 'urls' for URL references
base_url: Base URL for documentation site (required for 'urls' mode)
"""
if not docs_path.exists():
raise FileNotFoundError(f"Documentation directory not found: {docs_path}")
if mode == "urls" and not base_url:
raise ValueError("base_url is required when mode is 'urls'")
# Find all markdown files, excluding SUMMARY.md as it's just the table of contents
md_files = [f for f in docs_path.rglob("*.md") if f.name != "SUMMARY.md"]
print(f"📚 Found {len(md_files)} markdown files")
print(f"🔧 Mode: {mode}")
if mode == "urls":
print(f"🌐 Base URL: {base_url}")
documents = []
for file_path in md_files:
try:
# Load content
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read().strip()
if not content:
continue
# Generate title from filename
title = file_path.stem.replace("-", " ").replace("_", " ").title()
if title.lower() == "readme":
# Use parent directory name for README files
title = f"{file_path.parent.name.replace('-', ' ').replace('_', ' ').title()} Overview"
# Get relative path for metadata
relative_path = str(file_path.relative_to(docs_path))
if mode == "files":
# Use file path as reference
reference = relative_path
source_info = f"File: {file_path.name}"
# Prepare content with file metadata
content_with_metadata = f"""
Title: {title}
Path: {relative_path}
Source: {source_info}
{content}
"""
else: # urls mode
# Convert file path to documentation URL
reference = convert_file_path_to_url(relative_path, base_url)
source_info = f"Documentation Site"
# Prepare content with URL metadata
content_with_metadata = f"""
Title: {title}
URL: {reference}
Source: {source_info}
{content}
"""
documents.append((content_with_metadata, title, reference))
except Exception as e:
print(f"⚠️ Error processing {file_path}: {e}")
continue
return documents
async def test_lightrag_health(endpoint: str = "http://localhost:9621") -> bool:
"""Test if LightRAG is accessible"""
try:
async with httpx.AsyncClient(timeout=10.0) as client:
response = await client.get(f"{endpoint}/health")
if response.status_code == 200:
health_data = response.json()
print(f"✅ LightRAG is healthy: {health_data.get('status')}")
return True
else:
print(f"❌ LightRAG health check failed: {response.status_code}")
return False
except Exception as e:
print(f"❌ Cannot connect to LightRAG: {e}")
return False
async def test_query(endpoint: str = "http://localhost:9621") -> None:
"""Test a sample query"""
print(f"\n🧪 Testing query...")
try:
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.post(
f"{endpoint}/query",
headers={"Content-Type": "application/json"},
json={"query": "What is this documentation about?", "mode": "local"}
)
if response.status_code == 200:
result = response.json()
print(f"✅ Query successful!")
print(f"Response: {result['response'][:200]}...")
else:
print(f"❌ Query failed: {response.status_code}")
if response.status_code == 500:
try:
error_detail = response.json()
print(f" Error details: {error_detail}")
except:
print(f" Response: {response.text}")
except Exception as e:
print(f"❌ Query error: {e}")
async def main():
"""Main loading function"""
parser = argparse.ArgumentParser(
description="Load documentation into LightRAG with file paths or URL references",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Load with file path references (default mode)
python load_docs.py ../apolo-copilot/docs/official-apolo-documentation/docs
# Load with URL references
python load_docs.py docs/ --mode urls --base-url https://docs.apolo.us/index/
# Load Apolo docs with URL references (common use case)
python load_docs.py ../apolo-copilot/docs/official-apolo-documentation/docs \\
--mode urls --base-url https://docs.apolo.us/index/
# Use custom endpoint
python load_docs.py docs/ --endpoint https://lightrag.example.com
# Load with different documentation base URL
python load_docs.py docs/ --mode urls --base-url https://my-docs.example.com/docs/
"""
)
parser.add_argument(
"docs_path",
nargs="?",
default="../apolo-copilot/docs/official-apolo-documentation/docs",
help="Path to documentation directory (default: ../apolo-copilot/docs/official-apolo-documentation/docs)"
)
parser.add_argument(
"--mode",
choices=["files", "urls"],
default="files",
help="Reference mode: 'files' for file paths, 'urls' for URL references (default: files)"
)
parser.add_argument(
"--base-url",
dest="base_url",
help="Base URL for documentation site (required when mode=urls). Example: https://docs.apolo.us/index/"
)
parser.add_argument(
"--endpoint",
default="http://localhost:9621",
help="LightRAG endpoint URL (default: http://localhost:9621)"
)
parser.add_argument(
"--no-test",
action="store_true",
help="Skip test query after loading"
)
args = parser.parse_args()
print("🚀 Loading Documentation into LightRAG")
print("=" * 60)
print(f"📁 Documentation path: {args.docs_path}")
print(f"🔧 Reference mode: {args.mode}")
if args.mode == "urls":
if args.base_url:
print(f"🌐 Base URL: {args.base_url}")
else:
print("❌ Error: --base-url is required when mode is 'urls'")
sys.exit(1)
print(f"🌐 LightRAG endpoint: {args.endpoint}")
print()
# Test LightRAG connectivity
if not await test_lightrag_health(args.endpoint):
print("❌ Cannot connect to LightRAG. Please ensure it's running and accessible.")
sys.exit(1)
# Load documents
docs_path = Path(args.docs_path).resolve()
try:
documents = load_markdown_files(docs_path, args.mode, args.base_url)
except (FileNotFoundError, ValueError) as e:
print(f"{e}")
sys.exit(1)
if not documents:
print("❌ No markdown files found to load")
sys.exit(1)
# Calculate statistics
total_content = sum(len(content) for content, _, _ in documents)
avg_content = total_content // len(documents) if documents else 0
print(f"📊 Total content: {total_content:,} characters")
print(f"📊 Average length: {avg_content:,} characters")
# Load documents
successful = 0
failed = 0
print(f"\n🔄 Starting to load documents...")
for i, (content, title, doc_url) in enumerate(documents):
success = await load_document_to_lightrag(content, title, doc_url, args.endpoint)
if success:
successful += 1
else:
failed += 1
# Progress update
if (i + 1) % 10 == 0:
print(f"📈 Progress: {i + 1}/{len(documents)} ({successful} success, {failed} failed)")
# Small delay to avoid overwhelming the service
await asyncio.sleep(0.3)
print(f"\n✅ Loading complete!")
print(f"📊 Successful: {successful}")
print(f"📊 Failed: {failed}")
# Test query unless disabled
if not args.no_test and successful > 0:
await test_query(args.endpoint)
if __name__ == "__main__":
asyncio.run(main())