Skip to content

RAGFlow Integration

Run RAGFlow as a complete, self-hosted retrieval-augmented generation platform with Amazon Bedrock behind it. Document parsing, embeddings, reranking, and answer synthesis all reach Bedrock through stdapi.ai — and the models are already bound to the tenant before the first login.

About RAGFlow

🔗 Links: Website | GitHub | Documentation

RAGFlow is an open-source (Apache-2.0) RAG engine built around deep document understanding. Rather than a library you assemble a pipeline from, it is a finished product: a web UI for knowledge bases, a document parser, a retrieval stack, a chat assistant with citations, and an agent builder.

Key Features:

  • Deep document parsing - Layout-aware extraction from PDFs, office documents, and images, with chunk-level visual grounding
  • Knowledge bases - Upload, parse, chunk, and index documents through the UI, with per-base parsing and embedding settings
  • Hybrid retrieval - BM25 keyword scoring combined with vector similarity, then reranked before generation
  • Grounded chat - Answers cite the exact chunks they came from, so every claim is traceable to a source page
  • Agents - A visual builder for multi-step retrieval and tool workflows on top of the knowledge bases

Why RAGFlow + stdapi.ai?

  • Every RAG Stage, One Gateway
    Chat, embeddings, and reranking are three different API dialects. stdapi.ai serves all three from one deployment, so RAGFlow needs a single endpoint and a single key.

  • Access Amazon Bedrock Models
    Nova and Claude for synthesis, Cohere Embed and Amazon Titan for indexing, Cohere Rerank for two-stage retrieval — all through Bedrock.

  • Reranking Without a Second Vendor
    RAGFlow's reranking stage speaks the Cohere API. It reaches Bedrock's Rerank through stdapi.ai's Cohere-compatible route, with no Cohere account involved.

  • Enterprise Data Privacy
    Your documents, their chunks, and their vectors stay in your AWS account, in services you own.

  • Pay-Per-Use Pricing
    No RAGFlow Cloud subscription and no per-seat fees. Pay Amazon Bedrock rates for the parse, embed, rerank, and chat calls you actually make.

%%{init: {'flowchart': {'htmlLabels': true}} }%%
flowchart LR
  ragflow["<img src='../styles/logo_ragflow.svg' style='height:64px;width:auto;vertical-align:middle;' /> RAGFlow"] --> stdapi["<img src='../styles/logo.svg' style='height:64px;width:auto;vertical-align:middle;' /> stdapi.ai"]
  stdapi --> bedrock["<img src='../styles/logo_amazon_bedrock.svg' style='height:64px;width:auto;vertical-align:middle;' /> Amazon Bedrock"]

Connect Your Own Instance

Point any RAGFlow instance's model providers at stdapi.ai — the deployment underneath doesn't matter to RAGFlow.

Prerequisites

What You'll Need

  • stdapi.ai deployed - See deployment guide
  • Your stdapi.ai URL - e.g., https://api.example.com
  • Your API key - From Terraform output or configuration
  • RAGFlow instance - Running or ready to deploy (see Deployment section below), on x86_64 — RAGFlow publishes no arm64 image
  • A reranking region - Bedrock serves Rerank from a subset of regions; keep one in AWS_BEDROCK_REGIONS and stdapi.ai fails over to it automatically

Configuration

RAGFlow stores model credentials in its own database, added through Settings → Model providers in the web UI. Each entry pairs a provider (which decides the HTTP client and the URL layout) with an instance (a base URL and an API key). Three entries cover the whole pipeline:

Stage RAGFlow provider Base URL stdapi.ai route
Chat OpenAI-API-Compatible https://YOUR_STDAPI_URL/v1 /v1/chat/completions
Rerank OpenAI-API-Compatible https://YOUR_STDAPI_URL/cohere/v2 /cohere/v2/rerank
Embedding OpenAI-API-Compatible https://YOUR_STDAPI_URL/v1 /v1/embeddings

All three use the same stdapi.ai API key. Reranking needs its own entry because RAGFlow derives the request path from the instance's base URL, and reranking is served on the Cohere-compatible routes rather than the OpenAI ones.

Once the entries exist, set them as the tenant defaults under Settings → Model providers → System model settings, and RAGFlow uses them for every knowledge base and assistant.

Document Engine

RAGFlow defaults to a self-hosted Elasticsearch as its document and vector store, which cannot run on AWS Fargate: Elasticsearch requires the host sysctl vm.max_map_count=262144, and Fargate exposes no way to set it. Setting DOC_ENGINE=opensearch and pointing RAGFlow at an Amazon OpenSearch Service domain removes that constraint entirely — and replaces a container you would have to operate with a managed service.

Configuration

Select the engine with an environment variable, and give it the domain in service_conf.yaml:

DOC_ENGINE=opensearch
os:
  hosts: 'https://YOUR_DOMAIN_ENDPOINT:443'
  username: 'YOUR_MASTER_USER'
  password: 'YOUR_MASTER_USER_PASSWORD'

The scheme and port are literals in RAGFlow's shipped template, so a domain endpoint alone is not enough — the file has to be replaced, which is what the sample below does.

Hybrid BM25 + vector retrieval requires OpenSearch 2.10 or later and the cluster:admin/search/pipeline/put privilege. RAGFlow creates the search pipeline itself on start-up and silently falls back to vector-only search if the call is refused, so it is worth confirming in the application log which mode you got.

The OpenSearch backend has no upstream CI coverage

RAGFlow's own GitHub workflows exercise the elasticsearch and infinity engines only. Nothing upstream tests opensearch, so a working combination is a property of a specific RAGFlow version rather than a supported contract. Pin an exact image tag and re-validate before upgrading — the sample below pins v0.26.4.


Known Issues

RAGFlow v0.26.4's behavior with the opensearch document engine carries a few gaps that are properties of the application, not of any particular deployment: Agent Memory is unavailable (RAGFlow only wires a message store for the Elasticsearch and Infinity engines), the Agent "Code" component is unavailable (it needs a Docker socket and gVisor that DOC_ENGINE=opensearch deployments typically don't have), and Pagerank and the resume parser branch on Elasticsearch upstream and do not apply here. See Known Limitations in the sample's README for the full list, with the code references that back each one.

Deploy the Full Stack on AWS

The sample below is one worked example of a credible AWS deployment, not the only architecture that works. The gateway is a normal HTTP service, and RAGFlow and stdapi.ai can run anywhere you like — your own ECS or EKS cluster, EC2, another cloud, or a laptop.

Architecture

The diagram below is the topology the Terraform sample builds: RAGFlow and the stdapi.ai gateway as separate ECS Fargate services in one VPC, with OpenSearch, Aurora and Valkey as the managed stores behind RAGFlow.

%%{init: {'flowchart': {'htmlLabels': true, 'nodeSpacing': 20, 'rankSpacing': 40, 'subGraphTitleMargin': {'top': 8, 'bottom': 10}}} }%%
flowchart TB
  user["👤 Your users<br/>(browser)"]

  subgraph public["Your VPC · public subnets"]
    alb["<img src='../styles/logo_amazon_load_balancing.svg' style='height:40px;width:auto;vertical-align:middle;' /> Application Load Balancer<br/>fronts RAGFlow only"]
  end

  subgraph private["Your VPC · private app subnets — no inbound route from the internet"]
    ragflow["<img src='../styles/logo_ragflow.svg' style='height:40px;width:auto;vertical-align:middle;' /> RAGFlow<br/>ECS Fargate"]
    stdapi["<img src='../styles/logo.svg' style='height:40px;width:auto;vertical-align:middle;' /> stdapi.ai<br/>ECS Fargate"]
    opensearch["<img src='../styles/logo_amazon_opensearch.svg' style='height:40px;width:auto;vertical-align:middle;' /> Amazon OpenSearch Service<br/>document + vector index"]
    aurora["<img src='../styles/logo_amazon_aurora.svg' style='height:40px;width:auto;vertical-align:middle;' /> Aurora PostgreSQL<br/>Serverless v2 · metadata"]
    valkey["<img src='../styles/logo_amazon_elasticache.svg' style='height:40px;width:auto;vertical-align:middle;' /> ElastiCache Valkey<br/>TLS via loopback sidecar"]
    egress["<img src='../styles/logo_amazon_vpc.svg' style='height:40px;width:auto;vertical-align:middle;' /> NAT gateways<br/>one per Availability Zone"]
    opensearch ~~~ valkey
  end

  subgraph regional["AWS service endpoints · your account, the regions you configure"]
    bedrock["<img src='../styles/logo_amazon_bedrock.svg' style='height:40px;width:auto;vertical-align:middle;' /> Amazon Bedrock"]
    s3["<img src='../styles/logo_amazon_s3.svg' style='height:40px;width:auto;vertical-align:middle;' /> Amazon S3<br/>SSE-KMS"]
    cw["<img src='../styles/logo_amazon_cloudwatch.svg' style='height:40px;width:auto;vertical-align:middle;' /> Amazon CloudWatch<br/>logs"]
  end

  user -->|"HTTPS · TLS 1.2+<br/>(ACM certificate, when a custom<br/>domain is configured)"| alb
  alb -->|"HTTP · private subnet"| ragflow
  ragflow -->|"OpenAI + Cohere API · API key<br/>Cloud Map private DNS<br/>no public endpoint"| stdapi
  ragflow -->|"HTTPS · basic auth<br/>certificate not verified"| opensearch
  ragflow -->|"PostgreSQL · username + password"| aurora
  ragflow -->|"TLS via loopback sidecar · auth token"| valkey
  ragflow --> egress
  stdapi --> egress
  egress -->|"HTTPS · SigV4"| bedrock
  egress -->|"HTTPS · SigV4"| s3
  egress --> cw

Two things are worth reading off the picture. RAGFlow's documents and their vectors come to rest inside the account: source files land in the shared S3 bucket, and their parsed chunks and embeddings land in the OpenSearch domain — neither is reachable outside the VPC. And the gateway holds neither: it serves the Embed and Rerank calls RAGFlow sends it and returns the result, with no database of its own to persist anything in.

What Each AWS Service Does Here

AWS service Role in this integration Where it is configured
Amazon ECS on AWS Fargate Runs RAGFlow (three containers: main, a TLS sidecar for Valkey, and a one-shot bootstrap) and the stdapi.ai gateway as separate services ragflow.tf, Terraform sample
Elastic Load Balancing The only public entry point; forwards only to RAGFlow; TLS with an ACM certificate and a Route 53 alias record when a custom domain is configured, otherwise plain HTTP on the load balancer's own DNS name alb.tf
AWS Cloud Map Private DNS name that lets RAGFlow reach the gateway without exposing it publicly main.tf (service_discovery_dns_name)
Amazon Bedrock Chat completions for synthesis, embeddings for indexing, reranking for retrieval — RAGFlow never calls it directly AWS_BEDROCK_REGIONS
Amazon OpenSearch Service RAGFlow's document and vector index; a single-node VPC domain with fine-grained access control and enforced HTTPS opensearch.tf
Amazon Aurora PostgreSQL RAGFlow's metadata database (knowledge bases, chat sessions, users); Serverless v2, initialized over the RDS Data API postgres.tf
Amazon ElastiCache (Valkey) RAGFlow's cache and task queue (Redis Streams on database 1), reached through a socat sidecar that terminates TLS on loopback valkey.tf
Amazon S3 Shared with the gateway's own bucket; RAGFlow stores documents and generated files under its own prefix, reached through its own ECS task role S3 storage, ragflow.tf
AWS Secrets Manager Holds the Aurora master username and password, read by the one-time provisioners that create RAGFlow's login role and grant it schema privileges postgres.tf
AWS KMS One customer-managed key (from the VPC module) encrypts OpenSearch, Aurora and Valkey storage; the gateway module's own key encrypts the shared S3 bucket network.tf, ragflow.tf
AWS IAM Separate task roles per service; RAGFlow's (aws_iam_policy.ragflow) is scoped to its own S3 prefix and its own KMS key actions — it carries no permission for Amazon Bedrock ragflow.tf, IAM permissions
Amazon CloudWatch Container logs for every task through the ECS awslogs driver, plus the gateway's structured request events Logging & Monitoring

Security Measures in This Flow

  • Authentication — RAGFlow calls the gateway with a stdapi.ai API key that Terraform generates and injects into the container environment; the ALB's security group restricts inbound traffic to the deploying operator's current IP address.
  • Encryption in transit — HTTPS from the browser to the ALB when a custom domain is configured (otherwise plain HTTP), private-VPC HTTP from the ALB to RAGFlow, and HTTPS with SigV4 from the gateway to Amazon Bedrock. The OpenSearch and Valkey hops carry their own caveats, covered in Security Notes below rather than repeated here.
  • Encryption at rest — SSE-KMS on the shared S3 bucket, and KMS-encrypted storage for OpenSearch, Aurora and Valkey.
  • Least privilege — RAGFlow's task role is scoped to its own S3 prefix and its own KMS key actions and carries no Bedrock permission; only the gateway's task role can call Amazon Bedrock.
  • Content policy — a Bedrock guardrail configured on the gateway applies to chat, embeddings and reranking alike, since all three reach Bedrock through the same deployment.
  • Data handling — the gateway is stateless and holds request bodies in memory only for the duration of a call; the documents themselves persist in S3 and OpenSearch, inside the account, and no third party sits between RAGFlow's users and the models it calls.

What's Included

Deploy RAGFlow + stdapi.ai together, with the model providers already configured:

📦 stdapi-ai/samples/getting_started_ragflow

What's included:

  • RAGFlow v0.26.4 on ECS Fargate (4 vCPU / 16 GB), from the official infiniflow/ragflow image
  • stdapi.ai gateway connected to Amazon Bedrock, registered as RAGFlow's chat, embedding, and rerank provider
  • Amazon OpenSearch Service 2.19 as the document engine — a managed VPC domain with fine-grained access control, enforced HTTPS, and node-to-node and at-rest KMS encryption
  • Aurora PostgreSQL Serverless v2 for metadata, initialized over the RDS Data API
  • ElastiCache for Valkey with in-transit encryption and an AUTH token, reached through a socat TLS sidecar
  • Amazon S3 for documents and generated files, accessed with the ECS task role — no IAM user and no static access keys
  • A superuser account provisioned from a generated password, with self-registration closed

Every backing service is a managed AWS one; the only container in the task besides RAGFlow itself is the TLS sidecar and a short-lived bootstrap container.

Deploy:

git clone https://github.com/stdapi-ai/samples.git
cd samples/getting_started_ragflow/terraform
tofu init
tofu apply

Then read the URL and the generated superuser credentials from the Terraform outputs and sign in. There is no signup screen and no model-provider dialog to work through.

Zero-Touch Model Configuration

Out of the box, RAGFlow is not usable until an administrator opens the UI and adds a model provider by hand — a knowledge base cannot even be created without an embedding model bound to the tenant. Since RAGFlow v0.26 those credentials live in the database rather than in service_conf.yaml, so there is no configuration file to preseed them from either.

The sample closes that gap with a bootstrap container that logs in as the generated superuser, creates the three provider instances from the table above, and binds them as the tenant's chat, embedding, and rerank defaults before the first login — see How the Model Provider Gets There in the sample's README for exactly how it's wired. The result is the point of the sample: the first login lands on a working product, with a knowledge base ready to accept its first document.

Security Notes

The sample encrypts every hop and keeps every secret out of plain environment variables, but two RAGFlow application behaviors are worth knowing before you put real documents in it: it does not validate the OpenSearch server certificate, and its Redis client cannot speak TLS on its own — reached instead through a socat TLS sidecar that terminates encryption on loopback. Both are covered in detail, with the exact mitigations, under Security in the sample's README.


What It Costs to Run

Charge Driver
stdapi.ai licence $0.10 per gateway container-hour, metered through AWS Marketplace, with a 14-day free trial on the licence
ECS Fargate The RAGFlow task (4 vCPU / 16 GB, three containers, one of which — the bootstrap — runs once per task start) and the gateway task, each billed for the vCPU and memory reserved while running
Load balancing and networking One ALB fronting RAGFlow, plus the NAT gateways the private subnets egress through
Amazon OpenSearch Service A standing charge: one t3.small.search data node plus 20 GiB of gp3 storage, independent of query volume
Aurora PostgreSQL A standing charge: the Serverless v2 instance stays provisioned even when its capacity scales down to the configured 0 ACU floor
ElastiCache Valkey A standing per-node charge: one cache.t4g.micro node, no replicas
Model usage Amazon Bedrock chat, embedding and rerank calls at AWS rates, billed to your account with no markup

Read a model's price before sending it anything with GET /model_pricing. Setting COST_TRACKING=true adds a per-request cost estimate to each usage entry — estimated from published AWS prices, not read back from your invoice. See Sizing and cost in the sample's README for the knobs that move this bill and actual dollar figures at on-demand prices.


What to Watch

Every task's containers write their own logs to CloudWatch through the ECS awslogs driver; the gateway additionally writes one structured request event per call, carrying the request id, path, status code, execution_time_ms, the model that served it, and the token or search-unit counts AWS billed. Turning on CLOUDWATCH_METRICS republishes those counts as EMF metrics in the stdapi namespace, dimensioned by Model.

For a retrieval pipeline the useful first question is the split between embedding, reranking and generation, since each stage in this sample resolves to a different model:

fields model_id, execution_time_ms
| filter type = "request" and ispresent(model_id)
| stats count(*) as calls, pct(execution_time_ms, 95) as p95_ms by model_id
| sort calls desc

Amazon Bedrock model invocation logging is the AWS-side counterpart — off by default, and the record to enable when you need the prompts, chunks and completions themselves rather than metadata.

Next Steps