Artificial Intelligence (AI) AWS

LightRAG 1.5.7 on AWS User Guide

| Product: LightRAG 1.5.7 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the LightRAG 1.5.7 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg vector databases and RAG listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

LightRAG is an open source retrieval augmented generation (RAG) server from the HKU Data Intelligence Lab. You upload documents (PDF, Word, PowerPoint, Excel, Markdown, text). LightRAG uses your language model to extract the entities in them and the relationships between them into a knowledge graph, and your embedding model to build a vector index. Questions are answered from both, so answers draw on how the facts in your documents connect, with references to the source documents. It has a web UI (documents, knowledge graph explorer, retrieval testing) and a REST API, including an Ollama-compatible chat API.

LightRAG does not host a model. It calls the endpoint you configure: OpenAI, or any OpenAI-compatible server such as Ollama, vLLM, LM Studio or LiteLLM running in your VPC.

The cloudimg image ships it the secure way:

  • No anonymous access. Upstream LightRAG runs without authentication unless you configure it, and even then leaves its Ollama-compatible chat routes open by default. This image ships with sign-in on: every document, query, graph and chat route needs a signed-in session or the API key. Only the sign-in page and its assets are public.
  • Credentials unique to your instance. First boot generates an admin password (stored in the configuration only as a bcrypt hash), the secret that signs session tokens, and an API key, and writes the password and key to /root/lightrag-credentials.txt (root only). Nothing is baked into the image.
  • No model key ships. The image works with no key: LightRAG starts, serves the UI and calls nothing until you point it at your model (Step 7).
  • HTTPS from the first boot. nginx serves LightRAG on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS. LightRAG itself listens on 127.0.0.1:9621 only.
  • Closed until first boot, and fail closed. LightRAG cannot start before first boot has written its credentials, and refuses to start if its configuration ever loses them or reopens an upstream default. nginx ships switched off. First boot opens the public listener only after LightRAG works and a sign-in check passes; if anything fails, the listener is closed again.
  • Hardened defaults. API documentation pages are off, cross-origin browser access is off, documents cannot make the server download remote images, and the tokenizer files ship with the image so LightRAG makes no download of its own. Sign-in attempts are rate limited per client address. LightRAG runs as its own unprivileged account in a systemd sandbox that can write only to its data and log directories. LightRAG and nginx are blocked from the instance metadata service. The AMI requires IMDSv2. Requests for any host name the instance does not serve are dropped.
  • Pinned, audited dependencies. LightRAG and its 133 Python dependencies are installed from wheels pinned by checksum; every known vulnerability was patched before the image was built (a pip-audit against the PyPI and OSV databases reports none).
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: LightRAG 1.5.7 (the official lightrag-hku release with its web UI) in a Python virtual environment at /opt/lightrag/venv, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. Documents and the knowledge base (file based: graph, vectors and key/value stores, no database server) live under /var/lib/lightrag. No document, knowledge base or credential ships in the image.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH), TCP 443 (the web UI and API) and TCP 80 (redirects to HTTPS) from your own networks only. Never open 9621: LightRAG listens on the instance's loopback address only.
  • A language model and an embedding model LightRAG can reach: an OpenAI API key, or an OpenAI-compatible server (for example Ollama on another instance in your VPC).

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick LightRAG 1.5.7 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (LightRAG keeps its knowledge graph and vector index in memory while serving, so size up for a large corpus), your key pair and a security group as above. Size the root EBS volume for your documents: they and the knowledge base live under /var/lib/lightrag on the root volume, which you can grow later.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=30,VolumeType=gp3}' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=lightrag}]'

Step 2: Connect to your instance

Version SSH user
LightRAG 1.5.7 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot generates the certificate and the credentials, starts LightRAG, opens nginx and runs a sign-in check before it finishes (about a minute):

systemctl is-active lightrag nginx lightrag-firstboot
sudo test -f /var/lib/cloudimg/lightrag-firstboot.done && echo FIRSTBOOT_DONE
active
active
active
FIRSTBOOT_DONE

Only SSH and nginx listen on public addresses; LightRAG listens on loopback:

sudo ss -lntp | awk 'NR>1 {print $4}' | grep -v '127.0.0.5' | sort
0.0.0.0:22
0.0.0.0:443
0.0.0.0:80
127.0.0.1:9621
[::]:22
[::]:443
[::]:80

Step 4: Get your URL and sign-in details

The URL and the user name:

sudo grep -E '^LIGHTRAG_(URL|USERNAME)=' /root/lightrag-credentials.txt
LIGHTRAG_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
LIGHTRAG_USERNAME=admin

The password and the API key are in the same root-only file. Display it when you need them:

sudo cat /root/lightrag-credentials.txt
  • LIGHTRAG_URL is the web UI and API address. It uses the instance's public DNS name from EC2 instance metadata (the public IP address when the subnet has no public DNS names); the certificate also names the public and private IP addresses. To use your own DNS name, see Step 11.
  • LIGHTRAG_USERNAME and LIGHTRAG_PASSWORD sign in to the web UI.
  • LIGHTRAG_APIKEY authenticates REST API calls: send it in the X-API-Key header.

Open LIGHTRAG_URL in a browser. The certificate is self signed, so your browser warns once; continue (or install your own certificate, Step 11). Sign in as admin with the password from the file.

The LightRAG sign-in page served over HTTPS by the instance

Step 5: Confirm that nothing is open without signing in

C=/etc/ssl/lightrag/lightrag.crt; U=https://127.0.0.1
for p in /health /graph/label/list /documents/pipeline_status /api/tags; do echo "GET $p (not signed in) -> HTTP $(curl -s --cacert $C -o /dev/null -w '%{http_code}' $U$p)"; done
echo "POST /query (not signed in) -> HTTP $(curl -s --cacert $C -o /dev/null -w '%{http_code}' -X POST -H 'Content-Type: application/json' --data '{}' $U/query)"
curl -s --cacert $C $U/auth-status | jq -c '{auth_configured, auth_mode, core_version}'
GET /health (not signed in) -> HTTP 401
GET /graph/label/list (not signed in) -> HTTP 401
GET /documents/pipeline_status (not signed in) -> HTTP 401
GET /api/tags (not signed in) -> HTTP 401
POST /query (not signed in) -> HTTP 401
{"auth_configured":true,"auth_mode":"enabled","core_version":"1.5.7"}

/api/tags is the Ollama-compatible API, which upstream leaves open by default; here it needs the API key like everything else. From another machine, use LIGHTRAG_URL instead of https://127.0.0.1 (and -k or the instance's certificate, since it is self signed).

Step 6: Use the API key and sign in from the API

The examples read the key or password from the credentials file and hand it to curl on standard input, so it never appears on a command line or in your shell history:

C=/etc/ssl/lightrag/lightrag.crt; U=https://127.0.0.1
sudo sed -n 's/^LIGHTRAG_APIKEY=/X-API-Key: /p' /root/lightrag-credentials.txt | curl -s --cacert $C -H @- $U/health | jq -c '{status, auth_mode, core_version, llm_host: .configuration.llm_binding_host}'
printf 'X-API-Key: %s\n' wrong-key | curl -s --cacert $C -o /dev/null -w 'wrong API key -> HTTP %{http_code}\n' -H @- $U/health
sudo sed -n 's/^LIGHTRAG_PASSWORD=/username=admin\&password=/p' /root/lightrag-credentials.txt | curl -s --cacert $C --data @- $U/login | jq -c '{token_type, auth_mode, signed_in: (.access_token | length > 0)}'
{"status":"healthy","auth_mode":"enabled","core_version":"1.5.7","llm_host":"https://api.openai.com/v1"}
wrong API key -> HTTP 401
{"token_type":"bearer","auth_mode":"enabled","signed_in":true}

/login returns a session token (send it as Authorization: Bearer <token>); the web UI uses the same flow. After five wrong passwords from one address for one user name, LightRAG refuses that address for five minutes, and nginx also limits how fast any one address can try.

Step 7: Connect your language model and embedding model

All settings are in /etc/lightrag/lightrag.env (root only; it also holds the hashed password, the token secret and the API key, so do not share the file). Edit it and restart LightRAG:

sudo nano /etc/lightrag/lightrag.env
sudo systemctl restart lightrag

OpenAI: set your key on both lines; the defaults use gpt-4o-mini and text-embedding-3-small (1536 dimensions):

LLM_BINDING_API_KEY=<your-openai-api-key>
EMBEDDING_BINDING_API_KEY=<your-openai-api-key>

An OpenAI-compatible server in your VPC (Ollama, vLLM, LM Studio, LiteLLM): point both hosts at its /v1 URL, set the model names it serves and the embedding size, and give any non-empty key it accepts. For Ollama on another instance at 10.0.1.20:

LLM_BINDING_HOST=http://10.0.1.20:11434/v1
LLM_MODEL=qwen2.5:7b
LLM_BINDING_API_KEY=ollama
EMBEDDING_BINDING_HOST=http://10.0.1.20:11434/v1
EMBEDDING_MODEL=bge-m3
EMBEDDING_DIM=1024
EMBEDDING_BINDING_API_KEY=ollama

Allow the LightRAG instance to reach that server in its security group. Choose the embedding model before you add documents: changing it later needs a new knowledge base (Step 13). The values are literal: no quotes and no $ expansion. Keep HOST=127.0.0.1; LightRAG refuses to start if the file reopens an upstream default (WHITELIST_PATHS other than empty or /health, CORS_ORIGINS containing *, a plaintext password, or the upstream token secret).

Step 8: Add documents and ask questions

In the web UI, open Documents and upload files. LightRAG queues them, extracts entities and relationships with your model and indexes them; the status changes to Completed. The Knowledge Graph tab shows the entities and relationships, and the Retrieval tab answers questions from them with references to the source documents.

The two screenshots below come from a test instance with two short demonstration documents, indexed through a stand-in model endpoint; your graph reflects your own documents and model.

The Documents tab with two completed documents

The knowledge graph explorer with two extracted entities, their relationship and the properties of one entity

The same through the API with the API key (once a model is connected):

K=$(sudo sed -n 's/^LIGHTRAG_APIKEY=//p' /root/lightrag-credentials.txt)
curl -s -k -H "X-API-Key: $K" -F 'file=@report.pdf' https://<your-host>/documents/upload
curl -s -k -H "X-API-Key: $K" https://<your-host>/documents/pipeline_status
curl -s -k -H "X-API-Key: $K" -H 'Content-Type: application/json' \
  --data '{"query":"What are the main findings?","mode":"mix"}' https://<your-host>/query

Query modes are naive (vector search only), local (entities), global (relationships), hybrid and mix (graph plus vectors, the default in the UI). Ollama-compatible clients can use https://<your-host>/api/chat with the X-API-Key header.

Step 9: Run the built in check

The image ships an end to end check you can run at any time; first boot runs it too. It reads the credentials file itself and talks to LightRAG over HTTPS through nginx with the instance's certificate pinned: port 80 redirects, an unknown host name is dropped, every data, query, upload, graph and Ollama route refuses an anonymous request, the API documentation is off, a wrong password, a wrong user, a wrong API key and a token signed with LightRAG's published default secret are all refused, and this instance's password and API key work:

sudo lightrag-verify.sh
port 80 -> 301 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ ; an unknown Host is dropped on 80 and 443 ; certificate verifies for ec2-<public-ip-dashed>.<region>.compute.amazonaws.com
anonymous: / -> 307 to the sign-in page, /auth-status gives no guest token, 8 GET + 10 POST data/query/upload/graph/Ollama routes and DELETE /documents 401, API docs 404
sign-in: wrong password 401, wrong user 401, this instance's password -> token -> 200; default-secret token 401; wrong API key 401, this instance's API key 200 (LightRAG 1.5.7)
LIGHTRAG_ROUNDTRIP_OK

Step 10: Security checks

The files that matter are locked down, and the configuration keeps upstream's open defaults closed:

sudo stat -c '%a %U:%G %n' /etc/lightrag/lightrag.env /root/lightrag-credentials.txt /var/lib/lightrag/rag_storage /etc/ssl/lightrag/lightrag.key
sudo grep -E '^(HOST|WHITELIST_PATHS|CORS_ORIGINS|ENABLE_API_DOCS|NATIVE_MD_IMAGE_DOWNLOAD_ENABLED|LLM_BINDING_API_KEY)=' /etc/lightrag/lightrag.env
sudo grep -oE '^AUTH_ACCOUNTS=admin:\{bcrypt\}\$2b\$12\$' /etc/lightrag/lightrag.env
600 root:root /etc/lightrag/lightrag.env
600 root:root /root/lightrag-credentials.txt
700 lightrag:lightrag /var/lib/lightrag/rag_storage
600 root:root /etc/ssl/lightrag/lightrag.key
HOST=127.0.0.1
WHITELIST_PATHS=
CORS_ORIGINS=
ENABLE_API_DOCS=false
NATIVE_MD_IMAGE_DOWNLOAD_ENABLED=false
LLM_BINDING_API_KEY=
AUTH_ACCOUNTS=admin:{bcrypt}$2b$12$

The password is stored only as a bcrypt hash. LightRAG runs unprivileged in a sandbox that can write only to its data and log directories, and neither LightRAG nor nginx can reach the instance metadata service (so a model endpoint can never be pointed at it):

systemctl show lightrag -p User -p ProtectSystem -p ReadWritePaths -p NoNewPrivileges -p IPAddressDeny
systemctl show nginx -p IPAddressDeny
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32
User=lightrag
ReadWritePaths=/var/lib/lightrag /var/log/lightrag
ProtectSystem=strict
NoNewPrivileges=yes
IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32

nginx passes LightRAG a fixed host name and the real client address from the connection, never values a client sends:

grep -E 'proxy_set_header (Host|X-Forwarded-For|X-Real-IP|Forwarded)' /etc/nginx/lightrag-proxy.conf
proxy_set_header Host $lightrag_host;
proxy_set_header Forwarded "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;

The Python environment holds exactly the pinned set (135 packages including pip), with the security releases of its dependencies:

/opt/lightrag/venv/bin/pip freeze --all 2>/dev/null | wc -l; /opt/lightrag/venv/bin/pip freeze 2>/dev/null | grep -iE '^(lightrag-hku|aiohttp|cryptography|pillow|pypdf|pyjwt)=='
135
aiohttp==3.14.5
cryptography==50.0.2
lightrag-hku==1.5.7
pillow==13.0.0
PyJWT==2.15.1
pypdf==6.21.2

No credential reached a log, the journal, the knowledge base, shell history, backups or /etc (other than the configuration file):

sudo lightrag-secret-leak-check.sh
LEAKCHECK_OK no password, password hash, JWT secret or API key in the journal, auth.log, syslog, cloud-init, nginx and LightRAG logs, the knowledge base, shell history, MOTD, /var/backups, /etc (only lightrag.env), /usr/local, /opt/lightrag or /tmp

Step 11: Your own DNS name and certificate

Point a DNS record at the instance, then set the name LightRAG is served as. This mints a new self signed certificate for the name, updates nginx's host rule and the URL in /root/lightrag-credentials.txt, reloads nginx and keeps the name across reboots:

sudo lightrag-set-hostname <your-domain>

Without a configured name, the instance re-reads its address from EC2 instance metadata at every boot, so a stop and start that changes the public IP address keeps LightRAG reachable. To use a certificate from your own certificate authority instead, copy it over /etc/ssl/lightrag/lightrag.crt and lightrag.key (key mode 0600) and run sudo systemctl reload nginx; running lightrag-set-hostname again replaces it with a self signed one.

Step 12: New password and API key

To replace the admin password, the session token secret and the API key (for example if one was exposed):

sudo lightrag-rotate-credentials

It writes the new hash, secret and key to /etc/lightrag/lightrag.env (your model settings are kept), restarts LightRAG and rewrites /root/lightrag-credentials.txt. Every signed-in session and the old API key stop working; update your API clients.

To add more users, append ,<name>:{bcrypt}<hash> to the AUTH_ACCOUNTS line, where the hash comes from printf '%s' '<password>' | /opt/lightrag/venv/bin/python -c 'import bcrypt,sys; print(bcrypt.hashpw(sys.stdin.buffer.read(), bcrypt.gensalt()).decode())', then restart LightRAG. Plaintext passwords are refused.

Step 13: Backups and a fresh knowledge base

The knowledge base (/var/lib/lightrag/rag_storage) and the uploaded originals (/var/lib/lightrag/inputs) are plain files. Back them up with EBS snapshots, or copy them while LightRAG is stopped:

sudo systemctl stop lightrag
sudo tar -czf /root/lightrag-backup.tgz -C /var/lib/lightrag rag_storage inputs
sudo systemctl start lightrag

To start over (for example after changing the embedding model), stop LightRAG, move rag_storage aside, recreate it empty with owner lightrag and mode 0700, start LightRAG and upload your documents again.

Step 14: Server components

/opt/lightrag/venv/bin/python -c 'import lightrag; print("LightRAG", lightrag.__version__)'; nginx -v 2>&1; lsb_release -ds
ls /usr/share/doc/cloudimg/lightrag/
LightRAG 1.5.7
nginx version: nginx/1.24.0 (Ubuntu)
Ubuntu 24.04.5 LTS
LICENSE
VERSION
dependency-licences.txt
requirements-pinned.txt
Component Version Notes
LightRAG 1.5.7 /opt/lightrag/venv, service lightrag, settings /etc/lightrag/lightrag.env, data /var/lib/lightrag, logs /var/log/lightrag and journalctl -u lightrag
nginx 1.24.0 TLS on 443, redirect on 80, site /etc/nginx/sites-available/cloudimg-lightrag
Ubuntu 24.04 LTS unattended security upgrades on

Troubleshooting

  • The browser warns about the certificate: it is self signed. Continue once, or install your own certificate (Step 11). For curl, pass --cacert /etc/ssl/lightrag/lightrag.crt on the instance or -k elsewhere.
  • The connection is closed without a response: the request used a host name the instance does not serve (nginx drops unknown names). Use LIGHTRAG_URL, the instance's IP address, or set your name with lightrag-set-hostname.
  • HTTP 401: no session token or API key, or a wrong one. After lightrag-rotate-credentials the old ones stop working. HTTP 429 on sign-in: too many attempts from your address; wait five minutes.
  • Documents stay Pending or turn Failed: LightRAG could not reach your model. Check the endpoint, model names and key in /etc/lightrag/lightrag.env, that the instance can reach the endpoint, and journalctl -u lightrag. Retry failed documents from the Documents tab.
  • LightRAG does not start after an edit: journalctl -u lightrag shows which setting lightrag-check-config refused.
  • First boot: journalctl -u lightrag-firstboot shows what it did. If it failed, it closed the public listener; fix the cause and run sudo systemctl restart lightrag-firstboot.

Security recommendations

  • Restrict the security group to your own networks, and keep your model endpoint private to your VPC where you can.
  • Treat the API key like a password: use it from backends only, and rotate it with lightrag-rotate-credentials if it was exposed.
  • LightRAG sends your document text and questions to the model endpoint you configure; choose an endpoint whose data handling suits your documents.
  • Known open upstream item: a fix for a document parser that can loop on a malformed Word file is merged upstream but not yet released; only a signed-in user can upload documents. cloudimg publishes a new version when LightRAG releases it.

Support and licensing

cloudimg provides 24/7 technical support by email and live chat: support@cloudimg.co.uk.

LightRAG is licensed under the MIT licence (/usr/share/doc/cloudimg/lightrag/LICENSE); the licences of its Python dependencies are listed in /usr/share/doc/cloudimg/lightrag/dependency-licences.txt. LightRAG is an open source project of the HKU Data Intelligence Lab; cloudimg is not affiliated with or endorsed by it.