RAGFlow is a RAG (retrieval-augmented generation) engine with document parsing, chunking, and a web UI. It ships as a multi-container Docker stack (server, MySQL/Postgres, Elasticsearch or Infinity, Redis, MinIO), so it's memory-hungry — plan for a real VPS, not the smallest tier.
1. Prerequisites
- A RamNode VPS running Ubuntu 24.04 LTS (KVM plan recommended)
- Minimum 16 GB RAM, 4 vCPUs, 50 GB disk — RAGFlow's default stack (Elasticsearch + MySQL + MinIO + Redis + the app server) is heavy; 8 GB will swap constantly under real document loads
- A domain or subdomain pointed at the VPS's public IP (A record) — e.g.
ragflow.yourdomain.com - Root or sudo SSH access
2. Initial server setup
apt update && apt -y upgrade
apt -y install curl git ufw
# Basic firewall
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enableIncrease vm.max_map_count, which Elasticsearch requires:
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p3. Install Docker Engine + Compose plugin
curl -fsSL https://get.docker.com | sh
apt -y install docker-compose-plugin
systemctl enable --now docker4. Pull RAGFlow and configure
git clone https://github.com/infiniflow/ragflow.git /opt/ragflow
cd /opt/ragflow/dockerEdit .env in this directory — the key settings to review:
RAGFLOW_IMAGE— use the:v0.x.x-slimtag unless you need embedded models baked into the image (the slim image is far smaller and faster to pull)MYSQL_PASSWORD,MINIO_PASSWORD,ELASTIC_PASSWORD— set strong unique passwords, not the defaultsTIMEZONE— set to your local zoneDOC_ENGINE—elasticsearch(default) orinfinity(lighter weight, fewer moving parts if RAM is tight)
If you're memory-constrained, switch DOC_ENGINE=infinity and use the corresponding docker-compose.yml variant included in the repo (docker-compose-base.yml swaps the engine).
5. Bring up the stack
docker compose -f docker-compose.yml up -dFirst boot pulls several large images and can take a few minutes. Watch logs until the server reports it's listening:
docker logs -f ragflow-serverBy default the web UI listens on port 80 inside the compose network, mapped to the host. Confirm with:
docker compose ps6. Put nginx in front with TLS
Don't expose RAGFlow's container port directly to the internet long-term — front it with nginx and Let's Encrypt so you get HTTPS and can layer on rate limiting later.
apt -y install nginx certbot python3-certbot-nginxCreate /etc/nginx/sites-available/ragflow:
server {
listen 80;
server_name ragflow.yourdomain.com;
client_max_body_size 100M; # document uploads can be large
location / {
proxy_pass http://127.0.0.1:9380; # RAGFlow's host-mapped port; check docker compose ps
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 600s; # large document parsing can be slow
}
}ln -s /etc/nginx/sites-available/ragflow /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d ragflow.yourdomain.comSince nginx now owns 80/443, you can remove RAGFlow's own port 80 mapping in docker-compose.yml if it conflicts, or just bind it to 127.0.0.1 only.
7. First login and model setup
Visit https://ragflow.yourdomain.com, register the first admin account, then under Settings → Model Providers add your LLM/embedding provider (OpenAI-compatible endpoint, Ollama, etc.). RAGFlow doesn't ship a model itself — it orchestrates calls to whatever provider you configure.
8. Backups
The stateful pieces live in Docker volumes: MySQL/Postgres data, MinIO (uploaded documents), and the Elasticsearch/Infinity index. At minimum, cron a nightly dump:
docker exec ragflow-mysql mysqldump -u root -p"$MYSQL_PASSWORD" --all-databases > /root/backups/ragflow-mysql-$(date +%F).sql
docker run --rm -v ragflow_minio_data:/data -v /root/backups:/backup alpine \
tar czf /backup/ragflow-minio-$(date +%F).tar.gz -C /data .Rotate old backups off-box (RamNode object storage or another VPS) rather than keeping them on the same disk.
9. Updating
cd /opt/ragflow/docker
docker compose down
git pull
docker compose pull
docker compose up -dCheck the release notes first — RAGFlow has had breaking config/schema changes between minor versions.
Troubleshooting notes
- Elasticsearch container exits immediately → almost always the
vm.max_map_countsetting from step 2 wasn't applied, or RAM is too low for ES's default heap. - Uploads fail past a certain size → check both nginx's
client_max_body_sizeand RAGFlow's own upload limit env var. - Slow document parsing → parsing is CPU-bound; on a 4 vCPU box, expect large PDFs to take real time. Scale vCPUs before assuming something's broken.
