RAGFlow on Ubuntu 24.04 on Azure User Guide
Overview
RAGFlow is a popular open source, self hosted retrieval augmented generation engine built on deep document understanding. It gives you a full web workspace to build knowledge bases from your own documents, parse and chunk them with layout aware models, and chat with answers that are grounded in and cited back to your content. It adds template based chunking, hybrid retrieval and an agent flow builder for multi step retrieval.
The cloudimg image ships RAGFlow as its official multi service Docker Compose project under /opt/ragflow/docker: the RAGFlow server with its own bundled nginx on port 80, an Elasticsearch index for hybrid retrieval, a MySQL database for metadata, MinIO object storage for your documents, Redis for task queues, and a CPU text embeddings service so document embedding can run on box with no external key. Every datastore binds to the internal container network or the loopback interface, so only the web workspace on port 80 is exposed.
Secure by default, no default login: the image ships with no administrator and no user rows. Registration is open, so your first visit lands on the sign up screen and the first account you create becomes the administrator. A ragflow-firstboot.service oneshot generates the per instance datastore secrets, pulls the pinned images, brings the stack up, resolves the instance URL and writes a root only instance info note on first boot, then disables itself.
Per instance secrets: the MySQL, MinIO, Redis and Elasticsearch passwords are generated uniquely on first boot into /opt/ragflow/docker/.env (readable only by root), so no two instances share a datastore secret and nothing secret ships inside the image.
Embedding included, bring your own LLM: a local CPU embedding service (BAAI/bge-small-en-v1.5) is included so you can run document embedding on box with no external key; add it in Model providers as an OpenAI compatible endpoint, or connect your own. For chat and answer generation you add your own large language model provider (OpenAI, Anthropic, a local Ollama or vLLM endpoint) from the interface after you sign up. No third party AI key ships in the image.
Always current: on first boot the stack runs docker compose pull to refresh the pinned RAGFlow release and its datastore images, so every launch runs verified, current software rather than a half pulled build.
What is included:
- RAGFlow (pinned stable release
infiniflow/ragflow:v0.26.4) with its bundled nginx on port 80 - Elasticsearch, MySQL, MinIO, Redis and a CPU text embeddings service on the private Docker network
- Docker Engine with the Compose plugin from the official Docker repository
ragflow.servicemanaging the Compose stackragflow-firstboot.servicefor the first boot secret generation, pull, start and info note- The Elasticsearch kernel requirement (
vm.max_map_count=262144) applied persistently - Ubuntu 24.04 LTS base, fully patched
- 24/7 cloudimg support, 24h response SLA
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet with a subnet. RAGFlow is a multi service stack that runs Elasticsearch, so size the VM accordingly. Recommended VM size: Standard_D4s_v5 (4 vCPU, 16 GB RAM), RAGFlow's documented minimum. Document embedding runs on CPU, so this VM does not need a GPU; the language model you connect for chat runs at your chosen provider or a separate endpoint.
Step 1: Deploy from the Azure Portal
Search the Marketplace for RAGFlow on Ubuntu 24.04, choose your VM size (at least 4 vCPU and 16 GB RAM), and attach an NSG that allows TCP 22 (SSH) from your management network and TCP 80 / 443 (the workspace) from the networks that need it. Front port 80 with TLS in production (see the HTTPS section below).
Step 2: Deploy from the Azure CLI
RG="ragflow-prod"; LOCATION="eastus"; VM_NAME="ragflow-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/ragflow-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name rf-vnet --address-prefix 10.90.0.0/16 --subnet-name rf-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name rf-nsg
az network nsg rule create -g "$RG" --nsg-name rf-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name rf-nsg --name allow-web --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 443 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
--size Standard_D4s_v5 --storage-sku StandardSSD_LRS --os-disk-size-gb 64 \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name rf-vnet --subnet rf-subnet --nsg rf-nsg --public-ip-sku Standard
Step 3: Connect via SSH
ssh azureuser@<vm-ip>
Step 4: Verify the services are running
Docker runs the Compose stack and RAGFlow serves its own nginx on port 80.
sudo systemctl is-active docker ragflow
sudo ss -tln | grep ':80 '
curl -s -o /dev/null -w 'GET / -> HTTP %{http_code}\n' http://127.0.0.1/
Both services report active, RAGFlow is bound to :80, and the web workspace returns HTTP 200.

Step 5: Secure by default, no admin ships
Nothing sensitive ships in the image. MySQL has zero users, so every instance starts at the sign up screen. The per instance info note in /root is root only and holds no credential, only the resolved URL, and the per instance datastore secrets file is readable only by root.
MP=$(sudo grep '^MYSQL_PASSWORD=' /opt/ragflow/docker/.env | cut -d= -f2-)
echo "MySQL user count: $(sudo docker compose -f /opt/ragflow/docker/docker-compose.yml exec -T mysql mysql -uroot -p"$MP" rag_flow -N -B -e 'select count(*) from user')"
sudo grep -E '^RAGFLOW_URL|^NOTE' /root/ragflow-info.txt
sudo stat -c '%n perms=%a owner=%U:%G' /opt/ragflow/docker/.env
The user count is 0 (no admin exists), the note tells you that you create your own account at the sign up screen, and the .env holding the per instance datastore secrets is 600 root:root.

Step 6: Create your account
Open http://<vm-ip>/ in your browser. Because no administrator ships and registration is open, RAGFlow shows its sign up screen. Enter your Email, a display Nickname and a strong Password, then submit. The first account you create becomes the administrator, so pick a real password. Register immediately after launch, then disable open sign up (set REGISTER_ENABLED=0 in /opt/ragflow/docker/.env and run sudo systemctl restart ragflow) so no one else can self register on your instance.

After signing in you land on your knowledge bases, where you create the datasets RAGFlow will parse, chunk and retrieve from.

Step 7: Configure your AI models
Before you build a knowledge base, tell RAGFlow which models to use: an embedding model that turns document chunks into vectors, and a language model for chat and answers. Open Model providers from your account settings. The image includes a local CPU embedding service (BAAI/bge-small-en-v1.5) you can add as an OpenAI compatible provider pointing at http://tei/v1, so document embedding runs on box with no external key; you can also add your own provider such as OpenAI, Anthropic, Gemini or DeepSeek. Add at least an embedding model and a chat model, then set them as your defaults.

Once your models are set, open Dataset, create a knowledge base and upload documents into it. RAGFlow parses each file with its layout aware models and splits it into retrievable chunks using the chunking template you pick, then embeds each chunk so it can be retrieved.
Step 8: Chat with your documents
Open Chat and create an assistant over one or more knowledge bases, selecting one of the chat models you configured. Ask a question and RAGFlow retrieves the relevant chunks and answers with citations back to the source documents.

Step 9: The runtime stack
docker --version
sudo docker compose -f /opt/ragflow/docker/docker-compose.yml ps
sudo docker image ls --format '{{.Repository}}:{{.Tag}} {{.Size}}' | grep -E 'ragflow|elasticsearch|mysql|minio|valkey'
Docker runs the multi container Compose stack, and the RAGFlow server, Elasticsearch, MySQL, MinIO, Redis and embedding containers all report Up or healthy.

Step 10: Data, persistence and staying current
RAGFlow data (metadata, documents, the retrieval index) lives in Docker named volumes captured into the image, and the first boot service keeps every instance current.
sudo docker volume ls --format '{{.Name}}' | grep ragflow
systemctl is-enabled ragflow-firstboot.service
apt-mark showhold
The ragflow_mysql_data, ragflow_minio_data, ragflow_esdata01, ragflow_redis_data and ragflow_tei_data volumes hold the metadata, documents, retrieval index and embedding model cache, the first boot service has already run once and disabled itself on this instance, and there are no held packages so the OS security baseline is intact.

Step 11: Enable HTTPS
RAGFlow serves the workspace on port 80 inside its container. To add TLS, terminate HTTPS on a host reverse proxy in front of it. Install nginx on the host, point a DNS record at your VM, then obtain a certificate with certbot and proxy to 127.0.0.1:80:
sudo apt-get install -y nginx certbot python3-certbot-nginx
# add an nginx server block that proxy_passes to http://127.0.0.1:80, then:
sudo certbot --nginx -d <your-domain> --agree-tos -m <your-email> --redirect
certbot installs the certificate, rewrites the nginx server block for TLS, and sets up automatic renewal. Your workspace is then served over HTTPS.
Managing the service
sudo systemctl is-active ragflow docker
Both report active. The Compose stack is managed by ragflow.service; use sudo systemctl restart ragflow to restart it and sudo docker compose -f /opt/ragflow/docker/docker-compose.yml logs -f to follow the container logs live. To refresh to the pinned release at any time, run sudo docker compose -f /opt/ragflow/docker/docker-compose.yml pull then sudo systemctl restart ragflow. Back up the instance by snapshotting the OS disk or exporting the datastore volumes while the service is stopped.
Support
cloudimg provides 24/7 support for this image via email and live chat: deployment, TLS termination, language model provider configuration, knowledge base tuning, upgrades and performance tuning. Email support@cloudimg.co.uk.
This is a repackaged open source software product with additional charges for cloudimg support services. RAGFlow is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.