LightRAG with Docker and Ollama: graph RAG over your documents (Linux, Windows, Mac)
Before you start
- 21 min read
Boxes marked Run in terminal are what you type; plain text explains why. Check what you need first

What you get in one minute#
LightRAG is an open-source RAG server that turns your documents into a knowledge graph plus vectors, so it can answer questions that span several files, with a built-in WebUI and a REST API.

Logo: the official LightRAG project (github.com/HKUDS/LightRAG)
Plain RAG finds the chunks that look like your question. LightRAG also asks a language model to pull entities and relations out of every chunk and links them in a graph. That helps with questions such as "how do these three reports disagree?". The price is many model calls while indexing and a stronger model than ordinary RAG needs. This guide runs it with Docker and two local Ollama models, so nothing leaves your machine. The project is alive: not archived or renamed, with a release in September 2026 and a commit in October 2026.
| What | Value (official sources, read November 2026) |
|---|---|
| Current version | v1.5.7, released 2 September 2026; image ghcr.io/hkuds/lightrag:v1.5.7 |
| Licence | MIT (LICENSE at the release tag) |
| Time needed | About 30 minutes plus model downloads (our estimate) |
| Size and RAM | No official figure. Ollama lists the extraction model at 19 GB, the embedding model at 1.2 GB |
| Ports | TCP 9621 (WebUI, API and Ollama-style endpoint); Ollama on 11434 |
| Official docs | Repository and server docs |
At a glance:
- What it is: one server in one container, with a WebUI at
/webuito upload files, explore the graph and test queries. - Model rule: a non-thinking instruct model of about 30B for extraction. Small or "thinking" models give empty graphs.
- Context rule: set
OLLAMA_LLM_NUM_CTXyourself, aboveMAX_TOTAL_TOKENSplus 2000. - Storage: the defaults are "not suitable for production". PostgreSQL is the recommended upgrade.
- Security: open to everyone unless you set a login and an API key. We bind to
127.0.0.1and set both.
How it fits together#
You upload a file, LightRAG splits it, an extraction model finds entities and relations, an embedding model makes vectors, and everything is saved in four stores. A question searches the graph and the vectors, and an answer model writes the reply.
Drawn for this guide from the official README and server docs (v1.5.7, November 2026). This guide uses one model for extraction, keywords and answers; the docs let you split them.
LightRAG or RAGFlow?#
Our RAGFlow guide covers the other popular open-source RAG server.
| LightRAG | RAGFlow | |
|---|---|---|
| Strength | Cross-document questions through a graph | Messy scans and tables, OCR built in |
| Stack | One container plus your models | Several containers (search, database, storage) |
| Heavy part | The extraction model (about 30B) | The stack's RAM (official start: 16 GB) |
For clean text, Markdown or Word files and connected answers, start here. For scans, start with RAGFlow; LightRAG would need a parser engine such as MinerU or Docling, which we did not test.
Before you start#
You need Docker with Compose v2 and Ollama. On Windows that means Docker Desktop with the WSL 2 backend; on a Mac, Docker Desktop (Apple Silicon works, the image has an arm64 build).
Hardware. The docs give no RAM or GPU figure. The Ollama library lists the 30B model at 19 GB, and a 32,768-token context adds more. Our estimate: a 24 GB GPU is tight, 32 GB or more of GPU or unified memory is comfortable. A smaller model runs but builds a poor graph.
Check the tools (on Windows PowerShell use curl.exe):
docker --version docker compose version curl --version
- [ ] Docker is running, with about 25 GB of free disk for the models and image
- [ ] port 9621 is free (
ss -ltnon Linux,netstat -anoon Windows) - [ ] a safe place for
.env, which holds your passwords and API key - [ ] for the HTTPS section only: a domain, DNS pointing at the server, ports 80 and 443 open
Tested by DIY Lab Hub: not yet. Commands come from the official README, server docs, env.example, compose file and Dockerfile at tag v1.5.7 and the Ollama docs. We did not run the stack; our own parts are marked.
Step 1: Install Ollama and pull two models#
LightRAG needs a language model and an embedding model; both come from Ollama here. Our Ollama guide covers installation in depth.
- Extraction and answers:
qwen3:30b-a3b-instruct-2507-q4_K_M, a non-thinking model. The README calls Qwen3-30B-A3B-Instruct a reasonable local minimum. - Embeddings:
bge-m3, which the README recommends locally (1024 dimensions in the docs' example).
Linux#
curl -fsSL https://ollama.com/install.sh | sh ollama pull qwen3:30b-a3b-instruct-2507-q4_K_M ollama pull bge-m3 ollama list
Windows (PowerShell)#
Install Ollama with the installer from ollama.com/download, then open a new PowerShell window:
ollama pull qwen3:30b-a3b-instruct-2507-q4_K_M ollama pull bge-m3 ollama list
Mac (Terminal)#
Install the Ollama app from ollama.com/download, then:
ollama pull qwen3:30b-a3b-instruct-2507-q4_K_M ollama pull bge-m3 ollama list
Check it worked. ollama list shows both models. The first pull of the 19 GB model takes a while.
Tip: Pull the exact tag above. A bare
qwen3:30bis a different tag that we did not check, and a "thinking" variant is a known reason for an empty graph (see Common mistakes).
Step 2: Let the container reach Ollama#
Inside a container, localhost is the container itself. env.example says to use host.docker.internal, and the official compose file maps that name to the host.
Linux#
Native Ollama listens on 127.0.0.1 only. Make it listen on all interfaces, as the Ollama FAQ describes:
sudo systemctl edit ollama.service
Add these two lines, save, then restart:
[Service] Environment="OLLAMA_HOST=0.0.0.0:11434"
sudo systemctl daemon-reload sudo systemctl restart ollama
Ollama has no login, so allow port 11434 only from the Docker network or your LAN, or run LightRAG natively (see "Optional: run it without Docker").
Windows (PowerShell)#
Docker Desktop resolves host.docker.internal to the PC. The docs do not say whether that works with Ollama's default setting, and we did not test it. If Step 4 cannot connect, set a user variable OLLAMA_HOST to 0.0.0.0:11434 (Ollama FAQ: quit Ollama, edit the variable, start it again).
Mac (Terminal)#
Same as Windows. If the check in Step 4 fails, run launchctl setenv OLLAMA_HOST "0.0.0.0:11434" and restart the Ollama app, as the Ollama FAQ describes.
Check it worked. On the host, curl http://localhost:11434 answers Ollama is running. The container check is in Step 4.
Step 3: Create the folders, the .env file and the Compose file#
Data lives in ~/docker_volumes/lightrag. The Compose file is our version of the official one: image pinned to v1.5.7 instead of latest, no build: block (so no git clone), the port on 127.0.0.1 only, and restart: unless-stopped.
Linux#
mkdir -p ~/docker_volumes/lightrag/data/{rag_storage,inputs,prompts} ~/docker_volumes/lightrag/backups
cd ~/docker_volumes/lightrag
TOKEN_SECRET=$(openssl rand -hex 32)
API_KEY=$(openssl rand -hex 32)
ADMIN_PW='<choose-a-long-password-without-commas-or-colons>'
cat > .env << EOF
PORT=9621
WEBUI_TITLE='My Graph KB'
SUMMARY_LANGUAGE=English
# Login for the WebUI, token secret, API key
AUTH_ACCOUNTS='admin:${ADMIN_PW}'
TOKEN_SECRET=${TOKEN_SECRET}
LIGHTRAG_API_KEY=${API_KEY}
LIGHTRAG_PARSER=*:native-teP,*:legacy-R
ENTITY_EXTRACTION_USE_JSON=true
# LLM: Ollama on the host. Context must be above MAX_TOTAL_TOKENS (30000) + 2000.
LLM_BINDING=ollama
LLM_BINDING_HOST=http://host.docker.internal:11434
LLM_MODEL=qwen3:30b-a3b-instruct-2507-q4_K_M
OLLAMA_LLM_NUM_CTX=32768
LLM_TIMEOUT=600
# Embeddings: fixed after the first document
EMBEDDING_BINDING=ollama
EMBEDDING_BINDING_HOST=http://host.docker.internal:11434
EMBEDDING_MODEL=bge-m3:latest
EMBEDDING_DIM=1024
OLLAMA_EMBEDDING_NUM_CTX=8192
RERANK_BINDING=null
# Default stores: files under data/rag_storage (testing only)
LIGHTRAG_KV_STORAGE=JsonKVStorage
LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage
LIGHTRAG_GRAPH_STORAGE=NetworkXStorage
LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage
EOF
[ "$(id -u)" = "1000" ] && chmod 600 .env
cat > docker-compose.yml << 'EOF'
services:
lightrag:
image: ghcr.io/hkuds/lightrag:v1.5.7
container_name: lightrag
restart: unless-stopped
ports:
- "127.0.0.1:9621:9621"
volumes:
- ./data/rag_storage:/app/data/rag_storage
- ./data/inputs:/app/data/inputs
- ./data/prompts:/app/data/prompts
- ./.env:/app/.env
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
WORKING_DIR: "/app/data/rag_storage"
INPUT_DIR: "/app/data/inputs"
PROMPT_DIR: "/app/data/prompts"
HOST: "0.0.0.0"
PORT: "9621"
EOF
The chmod 600 line runs only for user id 1000: the container's user (uid 1000) must read .env, and the docs say a 0600 file owned by someone else fails with a PermissionError.
Windows (PowerShell)#
$root = "$HOME\docker_volumes\lightrag"
New-Item -ItemType Directory -Force "$root\data\rag_storage","$root\data\inputs","$root\data\prompts","$root\backups" | Out-Null
Set-Location $root
function New-Secret { $b = New-Object byte[] 32; [Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($b); -join ($b | ForEach-Object { $_.ToString('x2') }) }
$tokenSecret = New-Secret
$apiKey = New-Secret
$adminPw = '<choose-a-long-password-without-commas-or-colons>'
$envText = @"
PORT=9621
WEBUI_TITLE='My Graph KB'
SUMMARY_LANGUAGE=English
AUTH_ACCOUNTS='admin:$adminPw'
TOKEN_SECRET=$tokenSecret
LIGHTRAG_API_KEY=$apiKey
LIGHTRAG_PARSER=*:native-teP,*:legacy-R
ENTITY_EXTRACTION_USE_JSON=true
LLM_BINDING=ollama
LLM_BINDING_HOST=http://host.docker.internal:11434
LLM_MODEL=qwen3:30b-a3b-instruct-2507-q4_K_M
OLLAMA_LLM_NUM_CTX=32768
LLM_TIMEOUT=600
EMBEDDING_BINDING=ollama
EMBEDDING_BINDING_HOST=http://host.docker.internal:11434
EMBEDDING_MODEL=bge-m3:latest
EMBEDDING_DIM=1024
OLLAMA_EMBEDDING_NUM_CTX=8192
RERANK_BINDING=null
LIGHTRAG_KV_STORAGE=JsonKVStorage
LIGHTRAG_DOC_STATUS_STORAGE=JsonDocStatusStorage
LIGHTRAG_GRAPH_STORAGE=NetworkXStorage
LIGHTRAG_VECTOR_STORAGE=NanoVectorDBStorage
"@
[IO.File]::WriteAllText("$root\.env", ($envText -replace "`r`n", "`n"))
$compose = @'
services:
lightrag:
image: ghcr.io/hkuds/lightrag:v1.5.7
container_name: lightrag
restart: unless-stopped
ports:
- "127.0.0.1:9621:9621"
volumes:
- ./data/rag_storage:/app/data/rag_storage
- ./data/inputs:/app/data/inputs
- ./data/prompts:/app/data/prompts
- ./.env:/app/.env
extra_hosts:
- "host.docker.internal:host-gateway"
environment:
WORKING_DIR: "/app/data/rag_storage"
INPUT_DIR: "/app/data/inputs"
PROMPT_DIR: "/app/data/prompts"
HOST: "0.0.0.0"
PORT: "9621"
'@
[IO.File]::WriteAllText("$root\docker-compose.yml", ($compose -replace "`r`n", "`n"))
Mac (Terminal)#
Same commands as Linux; skip the chmod line. openssl ships with macOS.
Check it worked. The folder holds .env and docker-compose.yml, and docker compose config (run in that folder) prints the file without errors.
Tip:
AUTH_ACCOUNTSis split on commas and colons, so a password containing either breaks login. Use letters, digits and dashes.
Tip: After any
.envedit rundocker compose up -d --force-recreate. A single-file bind mount can keep the old file if your editor replaced it, andrestartdoes not fix that.
Step 4: Start LightRAG and check it#
Linux#
cd ~/docker_volumes/lightrag
docker compose up -d
docker compose ps
docker compose logs --tail=50 lightrag
curl http://localhost:9621/health
docker compose exec lightrag python -c "import urllib.request as u; print(u.urlopen('http://host.docker.internal:11434').read().decode())"
Windows (PowerShell)#
Set-Location "$HOME\docker_volumes\lightrag"
docker compose up -d
docker compose ps
docker compose logs --tail=50 lightrag
curl.exe http://localhost:9621/health
docker compose exec lightrag python -c "import urllib.request as u; print(u.urlopen('http://host.docker.internal:11434').read().decode())"
Mac (Terminal)#
Same commands as Linux.
Check it worked. docker compose ps shows lightrag running. /health answers with a small JSON document; per env.example, anonymous callers see only liveness fields, and the exact text is not published. The last command should print Ollama is running; if not, see Troubleshooting.
Step 5: Index a document and ask a question#
Linux#
Open http://localhost:9621/webui, or run xdg-open http://localhost:9621/webui.
Windows (PowerShell)#
Start-Process http://localhost:9621/webui
Mac (Terminal)#
open http://localhost:9621/webui
Log in as admin. In Documents, upload one short text, Markdown or Word file and wait until its status says processed. Then ask a question about it in the retrieval view in mix mode (the default). The docs' own first-run advice is the same: a small file, then a hybrid or mix query.
Check it worked. The logs show lines like Chunk 1 of 23 extracted 10 Ent + 5 Rel chunk-222c... (an example from a user's issue log; yours differ). Numbers above zero mean extraction works. 0 Ent + 0 Rel on every chunk means an empty graph even if the status says processed (see Common mistakes). The Knowledge Graph tab then shows nodes.
Tip: Start with one short file. A long PDF with 500 chunks on a slow GPU takes hours, and you learn nothing about your setup.
Ask through the API#
The same server has a REST API. The key goes in the X-API-Key header:
curl -s -X POST http://localhost:9621/query -H "Content-Type: application/json" -H "X-API-Key: <YOUR_API_KEY>" -d '{"query":"What is this document about?","mode":"mix","include_references":true}'
In PowerShell:
$body = @{ query = "What is this document about?"; mode = "mix"; include_references = $true } | ConvertTo-Json
Invoke-RestMethod -Uri http://localhost:9621/query -Method Post -Headers @{ "X-API-Key" = "<YOUR_API_KEY>" } -ContentType "application/json" -Body $body
The docs show a response text and references with a file_path per source.
What the numbers mean#
OLLAMA_LLM_NUM_CTX=32768: the context window LightRAG asks Ollama for. The docs say it "must be provided" and be larger thanMAX_TOTAL_TOKENSplus 2000; the defaultMAX_TOTAL_TOKENSis 30000.OLLAMA_EMBEDDING_NUM_CTX=8192: the library lists 8K forbge-m3.EMBEDDING_DIM=1024: must match the model, and the model cannot change after the first document.LLM_TIMEOUT=600: our value; the default is 240. The README says the real limit is twice the setting, and slow local models need more.
Ollama's own context default depends on your memory (its docs list 4k below 24 GiB of VRAM), which is why LightRAG sends its own value. After the first query run ollama ps: CONTEXT should show 32768 and PROCESSOR 100% GPU. A CPU/GPU split means the model spilled out of GPU memory and everything slows down.
The five query modes, from the README: local (specific entities and facts), global (themes and relations across documents), hybrid (both), naive (plain vector search, no graph) and mix (all of them, the default).
Storage backends#
LightRAG keeps four kinds of data: key-value (caches and chunks), vectors, the graph, and document status. The defaults (JsonKVStorage, NanoVectorDBStorage, NetworkXStorage, JsonDocStatusStorage) live in memory and persist to files, so the whole dataset must fit in RAM. The README says they are "not suitable for production". Issue 3679 (closed August 2026) measured ingestion slowing from about 150 to about 10 documents per hour.
- Testing: the defaults, as in Step 3.
- One backend for everything: PostgreSQL (recommended), MongoDB or OpenSearch.
- Specialists: Milvus or Qdrant for vectors, Neo4j or Memgraph for the graph, Redis for key-value and status.
The docs say you cannot change the storage choice after adding documents: there is no migration, apart from one graph tool and the LLM cache. Decide before you index real data.
PostgreSQL in the same Compose file#
The docs recommend PGTableGraphStorage for PostgreSQL: the graph lives in plain tables and needs no extension, so pgvector/pgvector:pg18 is enough. Add this service to docker-compose.yml (our assembly from the docs' parts; not run):
postgres:
image: pgvector/pgvector:pg18
container_name: lightrag-postgres
restart: unless-stopped
environment:
POSTGRES_USER: lightrag
POSTGRES_PASSWORD: <YOUR_DB_PASSWORD>
POSTGRES_DB: lightrag
volumes:
- ./data/postgres:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lightrag -d lightrag"]
interval: 10s
retries: 10
Under the lightrag service add depends_on: { postgres: { condition: service_healthy } }, and put these in environment: (the docs prefer real environment variables over .env):
POSTGRES_HOST: "postgres"
POSTGRES_PORT: "5432"
POSTGRES_USER: "lightrag"
POSTGRES_PASSWORD: "<YOUR_DB_PASSWORD>"
POSTGRES_DATABASE: "lightrag"
In .env change the four storage lines to the docs' PostgreSQL set, then start on an empty data/rag_storage:
LIGHTRAG_KV_STORAGE=PGKVStorage LIGHTRAG_VECTOR_STORAGE=PGVectorStorage LIGHTRAG_GRAPH_STORAGE=PGTableGraphStorage LIGHTRAG_DOC_STATUS_STORAGE=PGDocStatusStorage
Tip: On PostgreSQL 18 mount the data folder at
/var/lib/postgresql, not/var/lib/postgresql/data. The image docs changed the volume path in version 18.
Chat with it from Open WebUI#
LightRAG pretends to be an Ollama server, so Open WebUI can talk to it. In Open WebUI's admin settings add an Ollama connection to http://<lightrag-host>:9621 (the LightRAG port, not 11434). A model named lightrag:latest appears. Our Open WebUI guide covers installing it.
Start a message with /local, /global, /hybrid, /naive or /mix to pick the mode. Do not use "Continue response": LightRAG rejects it (issue 3645). With the default WHITELIST_PATHS=/health,/api/* these routes need no key, so use this on a trusted network only.
Optional: run it without Docker#
The README's main route is a Python tool install with uv, the same on all three systems. Ollama is then on localhost, so Step 2 is not needed:
uv tool install "lightrag-hku[api]"
Put a .env with the Step 3 values (both hosts http://localhost:11434) in a folder, start from that folder, and bind to loopback because the default is all interfaces:
lightrag-server --host 127.0.0.1
Install uv from docs.astral.sh/uv.
Put it behind HTTPS (with or without Traefik)#
This is for a server with a domain; if LightRAG only runs at home on http://localhost:9621, skip it. Both routes need a shared Docker network called proxy and a DNS record for lightrag.<your-domain>. Before you expose the server, add WHITELIST_PATHS=/health to .env so the Ollama-style routes need the key too.
docker network create proxy
With Traefik#
On a server that already runs Traefik v3, save this as docker-compose.traefik.yml next to docker-compose.yml. It assumes an entrypoint named https; use yours:
services:
lightrag:
networks:
- default
- proxy
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
- "traefik.http.routers.lightrag.rule=Host(`lightrag.<your-domain>`)"
- "traefik.http.routers.lightrag.entrypoints=https"
- "traefik.http.routers.lightrag.tls=true"
- "traefik.http.services.lightrag.loadbalancer.server.port=9621"
networks:
proxy:
external: true
docker compose -f docker-compose.yml -f docker-compose.traefik.yml up -d
Check it worked. curl -I https://lightrag.<your-domain>/ returns a status line over HTTPS (the root redirects to /webui).
Without Traefik: Caddy#
Choose this if you have no Traefik. Caddy gets and renews certificates by itself.
| Your case | What Caddy does | What you do |
|---|---|---|
| Public domain | Automatic Let's Encrypt certificate | DNS A record to the server; ports 80 and 443 open |
| Home only, no domain | tls internal: Caddy's own local certificate | Trust Caddy's root certificate on each device (below) |
First give LightRAG the proxy network in docker-compose.proxy.yml:
services:
lightrag:
networks:
- default
- proxy
networks:
proxy:
external: true
Create the Caddy folders, with a conf folder (Caddy's Docker docs warn against mounting a single Caddyfile):
mkdir -p ~/docker_volumes/caddy/{conf,data,config}
Save ~/docker_volumes/caddy/docker-compose.yml. The image is caddy:2.11.8, the latest release when we checked in November 2026:
services:
caddy:
image: caddy:2.11.8
container_name: caddy
restart: unless-stopped
ports:
- "80:80/tcp"
- "443:443/tcp"
- "443:443/udp"
volumes:
- ./conf:/etc/caddy
- ./data:/data
- ./config:/config
networks:
- proxy
networks:
proxy:
external: true
Save ~/docker_volumes/caddy/conf/Caddyfile for a public domain:
lightrag.example.com {
reverse_proxy lightrag:9621
}
Or, for a home-only name (point it at the server in your router or hosts file):
lightrag.home.arpa {
tls internal
reverse_proxy lightrag:9621
}
Start both stacks:
cd ~/docker_volumes/lightrag && docker compose -f docker-compose.yml -f docker-compose.proxy.yml up -d cd ~/docker_volumes/caddy && docker compose up -d
For a home-only certificate, copy Caddy's root out and trust it on each device (the OS steps are ours, not from the Caddy docs):
docker cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt
- Linux: copy it to
/usr/local/share/ca-certificates/caddy-root.crtand runsudo update-ca-certificates. - Windows:
Import-Certificate -FilePath .\caddy-root.crt -CertStoreLocation Cert:\CurrentUser\Root. - Mac:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain caddy-root.crt.
Check it worked. curl -I https://lightrag.example.com/ returns a status line over HTTPS. For tls internal, the browser shows a padlock only after the root is trusted on that device.
Tip: Let's Encrypt needs the DNS record to point at the server and ports 80 and 443 to reach it. A certificate error usually means the name in the Caddyfile differs from the DNS record.
Security and testing#
| Control | How |
|---|---|
| Login and API key | Set AUTH_ACCOUNTS with TOKEN_SECRET, and LIGHTRAG_API_KEY. With only a key, the WebUI still admits guests (docs). |
| Port | The official compose publishes on all interfaces. We use 127.0.0.1; HTTPS goes through a proxy. |
| Ollama-style routes | WHITELIST_PATHS defaults to /health,/api/*, leaving /api/* open. Set /health when the server is on a network. |
| Secrets | .env holds the password, token secret and API key. Never commit it or paste it into a chat. |
| Login guessing | Five failed logins per client IP and name lock that client for 300 seconds, per process; add a proxy rate limit for strict control. |
| Ollama | Port 11434 has no login. Allow it only from the Docker network or LAN. |
With local Ollama, documents and questions stay on the host; a hosted provider would receive your text. The docs we read describe no telemetry.
Quick tests:
docker compose ps docker compose logs --tail=100 lightrag curl http://localhost:9621/health ollama ps
Common mistakes#
From the official docs and the issue tracker (read November 2026).
| Mistake | Why it happens | Do this instead |
|---|---|---|
| Using a thinking model for extraction | It spends its output budget on hidden reasoning and the document still shows processed with 0 entities (issues 3597, 3601; a maintainer says no thinking models, issue 2768) | Use the instruct model from Step 1, or set EXTRACT_OLLAMA_LLM_THINK=false and KEYWORD_OLLAMA_LLM_THINK=false |
No or low OLLAMA_LLM_NUM_CTX | Ollama's default window is small; the docs say it "must be provided" above MAX_TOTAL_TOKENS + 2000 | Keep 32768; check ollama ps |
| A model that is too small | Weak models loop or time out (issue 2604: a 4B model failed at chunk 9) | Use the 30B instruct model |
localhost as the model address in Docker | In a container it means the container itself | http://host.docker.internal:11434, as env.example says |
| A path in the Ollama address | Issue 2301: https://host/ollama/ gave "Failed to connect to Ollama" | A name and optional port only |
Wrong EMBEDDING_DIM, or a later model swap | Issue 3596: nomic-embed-text gives 768 numbers, not 1024. Vectors from one model are useless to another (README) | Match the dimension; to switch models, clear vectors and re-index |
| Open WebUI pointed at port 11434 | The Ollama-style endpoint is on 9621 (issue 2438) | http://<host>:9621 |
| Default stores for real data | RAM and files only; issue 3679 shows slowdown | PostgreSQL before you index real data |
| Server exposed with no login | It listens on 0.0.0.0 and "without auth every endpoint is public" (README) | Bind 127.0.0.1; set the login and key |
PostgreSQL 18 mounted at /var/lib/postgresql/data | Version 18 images moved the volume path | Mount /var/lib/postgresql |
AI assistants: ENTITY_TYPES and invented variable names | Older tutorials use ENTITY_TYPES; v1.5 removed it and the server refuses to start. Assistants also write OLLAMA_NUM_CTX (the name is OLLAMA_LLM_NUM_CTX) | Use ENTITY_TYPE_PROMPT_FILE; copy names from env.example at the release tag |
Tip: Upload a two-page file and read the log. If every chunk says
0 Ent + 0 Rel, fix the model before you upload anything big.
Tip: Write down the embedding model and
EMBEDDING_DIMthe day you start. They are the one setting you cannot change later without re-indexing.
Tip: Copy
data/rag_storagebefore trying another extraction model; re-extraction costs hours.
Troubleshooting#
| Problem | Solution |
|---|---|
| The Ollama check in Step 4 fails | ollama list on the host; set OLLAMA_HOST=0.0.0.0:11434 (Step 2); check the firewall |
| Processed, but the graph is empty | A thinking model, truncated output or a too-small model. Read docker compose logs --tail=200 lightrag and the entries below |
PermissionError loading .env | The file is 0600 and owned by another user. Use the default 0644 or pass values through environment: |
| No start after an upgrade from 1.4 | Remove ENTITY_TYPES from .env. To keep the old file handling set LIGHTRAG_PARSER=*:legacy-F |
| Everything stalls after a while | Ollama swaps the two models in and out of memory. Check ollama ps; OLLAMA_KEEP_ALIVE keeps them loaded |
Embedding dimension mismatch#
Embedding dimension mismatch detected: total elements (N) cannot be evenly divided by expected dimension (1024) means the model returns another size than EMBEDDING_DIM (issue 3596). Fix the number, clear the vectors and index again.
Truncated model output#
Ollama response truncated by token limit (done_reason=length, content_len=0): the model ran out of output budget before writing anything (issues 3597, 3601). Use a non-thinking model or raise OLLAMA_LLM_NUM_PREDICT.
Worker timeout#
TimeoutError: ... LLM func: Worker execution timeout. The README names three causes: a model slower than about 50 tokens per second, a chunk with too many entities (bibliographies), or a model stuck in a loop. Raise LLM_TIMEOUT (it counts twice), cap output with OLLAMA_LLM_NUM_PREDICT, or re-process the document once.
Last message must be from user role#
Open WebUI's "Continue response". LightRAG treats each chat request as a new query and rejects it (issue 3645).
Known bugs#
- Issue 2675 (open):
TimeoutError: Embedding func: Worker execution timeout after 60swith Ollama. A maintainer blames one Ollama instance swapping two models and suggests vLLM or SGLang for production. - Issue 2495 (open, December 2025 report): embeddings failed on Ollama 0.13.0 to 0.13.2 and worked on 0.12.11. We did not check newer versions.
- Issue 4264 (open): the AGE-based
PGGraphStoragehas a pooled-session bug, another reason to usePGTableGraphStorage.
Updates and backups#
Update. Read the release notes first. The docs warn that ENTITY_TYPES is gone in v1.5, that a new embedding model needs a clean re-index, and that every old writer must stop before a new version starts on the same storage. Change the tag in docker-compose.yml, then:
cd ~/docker_volumes/lightrag docker compose pull docker compose down docker compose up -d docker compose logs --tail=100 lightrag
On Windows run the same four commands in $HOME\docker_volumes\lightrag.
Back up. Stop the container, archive the data folder and .env, start again:
cd ~/docker_volumes/lightrag docker compose stop tar -czf "backups/lightrag-$(date +%F).tar.gz" data/rag_storage data/inputs data/prompts .env chmod 600 backups/lightrag-*.tar.gz docker compose start
The archive holds your .env secrets, so keep it private. With PostgreSQL, also run docker compose exec -T postgres pg_dump -U lightrag lightrag > backups/lightrag-$(date +%F).sql. In PowerShell:
Set-Location "$HOME\docker_volumes\lightrag" docker compose stop Compress-Archive -Path data, .env -DestinationPath "backups\lightrag-$(Get-Date -Format yyyy-MM-dd).zip" docker compose start
Schedule it: on Linux and Mac save the Linux commands as backup.sh and add 0 3 * * * ~/docker_volumes/lightrag/backup.sh with crontab -e. On Windows save the block as backup.ps1 and run schtasks /Create /SC DAILY /ST 03:00 /TN "LightRAG backup" /TR "powershell -NoProfile -File $HOME\docker_volumes\lightrag\backup.ps1". Keep a copy on another machine; our restic guide shows how.
Restore test. Unpack an archive into a new empty folder, never over the live one:
mkdir -p /tmp/restore-test && tar -xzf backups/lightrag-<date>.tar.gz -C /tmp/restore-test ls /tmp/restore-test/data/rag_storage
On Windows use Expand-Archive into a temporary folder. We did not run these commands.
Performance and resources#
The docs publish no RAM, CPU or speed figures, so this guide gives none. What you can do:
- Measure:
docker stats lightragfor the server,ollama psfor the model and the CPU/GPU split. The extraction model sets indexing speed. - A rule of thumb: a maintainer wrote in issue 2768 that a chunk should take under 30 seconds. Minutes per chunk point to the wrong model or a CPU spill.
- Concurrency:
MAX_ASYNC_LLM(default 4) andMAX_PARALLEL_INSERT(default 3; the docs suggest about a third ofMAX_ASYNC_LLM). Raise them only with spare capacity. - Reranking: better answers for one to two seconds more; we left it off (
RERANK_BINDING=null).
FAQ#
Is LightRAG free, and is it maintained? Yes to both: MIT licence, v1.5.7 in September 2026, a commit in October 2026. The Python package is lightrag-hku.
Do I need a GPU? The docs give no figure. A 30B model on a CPU would be very slow; plan on a GPU or a Mac with plenty of unified memory.
Can I swap the embedding model later? Not cheaply. The server docs say to clear the vector data and index again. Choose once.
Can it use Qdrant? Yes, as the vector store (QdrantVectorDBStorage with QDRANT_URL). Our Qdrant guide covers running it.
Sources#
- LightRAG release v1.5.7, README, LICENSE, docker-compose.yml, env.example and Dockerfile - read November 2026
- LightRAG Server docs and Docker deployment at v1.5.7 - read November 2026
- lightrag-hku on PyPI and the GHCR package - November 2026
- Ollama docs: FAQ, context length, Linux install, and the library pages for bge-m3 and qwen3 - November 2026
- Caddy release v2.11.8, Caddy reverse_proxy, Caddy tls and running Caddy with Docker - November 2026
- pgvector image and the postgres image notes on the version 18 volume path - November 2026
- GitHub issues 2301, 2438, 2495, 2604, 2675, 2768, 3596, 3597, 3601, 3645, 3679, 4264 - November 2026
Checked against the official docs on 2026-11-05.