Self-hosted
Private company knowledge base (self-hosted RAG)
Open WebUI as the employee interface, vLLM serving a Qwen2.5-14B-Instruct model on a single 24 GB GPU, PostgreSQL with pgvector for chats and embeddings, and OIDC single sign-on — all in Docker on one server in your office or colocation rack. Ollama replaces vLLM for teams under about 20 users; a 48 GB GPU lets you run a 32B model for better answers.
- Source
- Editorial recipe — no step evidence has been fetched yet
- Verified
- Evidence not verified
- Confidence
- Low
01Objective
Let employees ask questions of the company’s own documents, conversationally, without any document, question or answer leaving the company network.
- use caseDocument Q&AAsk questions of a specific document or a small set of them and get an answer with the passage it came from. Narrower than company-wide search: the user already knows which file matters and wants it read carefully.
- use caseInternal company searchOne search box over the documents a company already has — shared drives, wikis, ticket systems, email attachments — answered by a model that quotes the source. The value is finding the right paragraph in a corpus nobody has read end to end, not writing new text.
- use caseKnowledge managementCapturing what the organisation knows — process notes, decisions, answers given once already — and keeping it findable and current. AI helps by drafting entries, spotting duplicates and flagging pages that contradict each other.
- use casePrivate LLMUsing a language model without your data leaving a boundary you control — a country, a cloud region, or your own network. The constraint is where processing happens and who can see the prompts, not which model runs.
Reference deployments using this recipe
Field notes about this recipe
02Recommended stack
| Role | Component |
|---|---|
| Authentication | Keycloak (or Authentik) |
| Gateway | Reverse proxy with TLS (nginx, Caddy or Traefik) |
| Inference | BGE-M3 embeddings |
| Inferenceoptional | Ollama |
| Inference | Qwen2.5-14B-Instruct (4-bit) — or Qwen3-32B on a 48 GB GPU |
| Inference | vLLM |
| Ingestionoptional | Docling |
| Orchestrationoptional | RAGFlow |
| Storage | PostgreSQL |
| Ui | Open WebUI |
| Vector store | pgvector |
Architecture and data flow
Components
- Employees — people
- Document ingestion (Docling) — storage, optional
- Reverse proxy (TLS, internal only) — network
- Open WebUI — application
- Keycloak (OIDC) — identity
- Retrieval layer (Open WebUI Knowledge, or RAGFlow) — retrieval
- PostgreSQL + pgvector (embeddings) — vector store
- PostgreSQL (chats, users, permissions) — database
- vLLM (OpenAI-compatible server) — inference server
- Qwen2.5-14B-Instruct (4-bit) — model
- Company GPU server (24 GB) — hardware
Connections
- Employees to Reverse proxy (TLS, internal only) — HTTPS (confidential data)
- Reverse proxy (TLS, internal only) to Open WebUI — reverse proxy (confidential data)
- Open WebUI to Keycloak (OIDC) — OIDC sign-in (personal data)
- Document ingestion (Docling) to Retrieval layer (Open WebUI Knowledge, or RAGFlow) — documents to index (confidential data)
- Open WebUI to Retrieval layer (Open WebUI Knowledge, or RAGFlow) — question + user groups (confidential data)
- Retrieval layer (Open WebUI Knowledge, or RAGFlow) to PostgreSQL + pgvector (embeddings) — embedding search (confidential data)
- Retrieval layer (Open WebUI Knowledge, or RAGFlow) to PostgreSQL (chats, users, permissions) — documents + permissions (confidential data)
- Open WebUI to PostgreSQL (chats, users, permissions) — chats, users, settings (personal data)
- Retrieval layer (Open WebUI Knowledge, or RAGFlow) to vLLM (OpenAI-compatible server) — prompt + retrieved passages (confidential data)
- vLLM (OpenAI-compatible server) to Qwen2.5-14B-Instruct (4-bit) — loaded weights
- Qwen2.5-14B-Instruct (4-bit) to Company GPU server (24 GB) — GPU memory
- vLLM (OpenAI-compatible server) to Company GPU server (24 GB) — GPU memory
External data transfer · NONE
DashedOptional — not included in the cost or the hardware sizing: Document ingestion (Docling).
- No edge in this design crosses out of the company network.
- Model weights are downloaded once from Hugging Face at setup; after that the server needs no internet access to answer questions.
- Container image pulls and OS patching are the only other outbound flows, and they carry no company data.
03Suitable for
- Organisation size
- 20–200 employees
- Data classes
- confidential, personal, privileged
- Constraints
- documents must not leave the company network; somewhere to put a server: an office comms room, a rack, or colocation; someone who can run Linux and Docker, in-house or on retainer; a GPU with at least 24 GB of memory for a 14B model at 4-bit
- Industries
- Legal, Accounting, Professional services, Financial services
- Jurisdictions
- any
04Hardware
On-premise single 24 GB GPU server
- GPU
- NVIDIA RTX 4090 24 GB (or NVIDIA L4 24 GB for a rack-mounted, 72 W alternative)
- VRAM
- 24 GB
- System RAM
- 64 GB
- Storage
- 2000 GB
- CPU
- 16-core x86 server CPU (AMD EPYC 7003/9004 or Intel Xeon Scalable)
- Form factor
- Tower server
Indicative costUS$4,000 – US$9,000
indicative build cost for the complete machine, USD, Aug 2026 — verify with a local supplier
The default box for a 20–60 person firm. Fits a 14B model at 4-bit with roughly 8 GB of KV cache left for concurrent chat, or an 8B model at fp16. NVMe storage sized for the model cache plus a document corpus and its embeddings. Add a UPS and an offsite backup target — this machine holds the whole knowledge base.
On-premise single 48 GB GPU server
- GPU
- NVIDIA L40S 48 GB (rack) or NVIDIA RTX 6000 Ada 48 GB (office workstation)
- VRAM
- 48 GB
- System RAM
- 128 GB
- Storage
- 4000 GB
- CPU
- 24–32-core x86 server CPU (AMD EPYC or Intel Xeon Scalable)
- Form factor
- Rack server
Indicative costUS$12,000 – US$22,000
indicative build cost for the complete machine, USD, Aug 2026 — verify with a local supplier
The step up when answer quality matters more than price: a 32B model at 4-bit with generous KV cache, or a 14B model at fp16 with a long context. ECC memory and a standard 2U chassis mean it belongs in a rack or comms room rather than under a desk.
Apple Silicon workstation (unified memory)
- GPU
- Apple M4 Max (up to 128 GB unified) or M3 Ultra (up to 256 GB unified)
- VRAM
- 96 GB
- System RAM
- 128 GB
- Storage
- 2000 GB
- CPU
- Apple M4 Max / M3 Ultra
- Form factor
- Workstation
Indicative costUS$4,500 – US$12,000
indicative build cost for the complete machine, USD, Aug 2026 — verify with a local supplier
Quiet, standard-socket power draw, and a large memory pool — about 75% of installed unified memory is addressable by the GPU, which is where the 96 GB figure comes from on a 128 GB M4 Max. Memory bandwidth, not capacity, sets the ceiling: excellent for a pilot, a partner workstation or a single heavy user, weak for 40 people at once. Runs Ollama, llama.cpp and MLX; does not run CUDA builds of vLLM.
Indicative costUSD · one-off plus monthly
- Software licences
- All components are open source and self-installed. Check each licence for use limits.
- US$0
- Model usage
- Open weights served locally: no per-token charge. The GPU cost sits under infrastructure.
- US$0
- GPU server (24 GB class), purchased
- Hardware profile onprem-small-24gb: indicative build cost for the complete machine, Aug 2026 — verify with a local supplier. Excludes power, cooling, UPS and offsite backup.
- US$4,000 – US$9,000
- Implementation (8–20 FDE-days)
- 8–20 FDE-days at US$760–1940 per day, converted from the HK$6,000–15,000 band at the HKMA Linked Exchange Rate band of HK$7.75–7.85 to one US dollar. One-off; excludes internal staff time.
- US$6,080 – US$38,800
- Ongoing support and patching
- Not estimated: this is either internal staff time or a retainer, and both depend on arrangements we cannot see. Budget one day a month as a starting point for discussion.
- Not estimated
- 40 users, one document corpus, one office site.
- Hardware is a one-off purchase written down over three to five years; the implementation figure is one-off; there is no monthly licence or per-token charge.
- A 48 GB machine (onprem-medium-48gb) roughly doubles the hardware line and buys a 32B model.
- Every figure is an assessment from the inputs listed, not a quotation.
05Difficulty
3 / 5
A project week with Linux, Docker and GPU experience
06Skills
- Dockerdocker
- infrastructure
- Identity and SSOidentity-sso
- security
- Linuxlinux
- operations
- LLM evaluationllm-evaluation
- ml
- LLM inferencellm-inference
- ml
- Networkingnetworking
- networking
- PostgreSQLpostgresql
- data
- Retrieval-augmented generationrag
- ml
- Security hardeningsecurity-hardening
- security
07Deployment steps
Commands are copied from each project’s own documentation, and the page they came from is linked under the step. 0 of 11 steps currently open an evidence record. The rest are linked to their source; §10 says which of those documents were fetched and which were fetched without their anchor being found — two different states, named differently there.
- 01
Prepare the server and GPU drivers
AssessmentInstall a current Linux LTS on the machine, then the NVIDIA driver, Docker Engine and the NVIDIA Container Toolkit so containers can see the GPU. Configure the Docker runtime and restart the daemon. Verify with `nvidia-smi` inside a container before going further — every later step assumes the GPU is visible.
sudo apt-get install -y nvidia-container-toolkitNVIDIA Container Toolkit
sudo nvidia-ctk runtime configure --runtime=docker sudo systemctl restart docker - 02
Run PostgreSQL with the pgvector extensionversion-sensitive
AssessmentUse the pgvector image, which is the Postgres image with the extension added, and enable the extension once in the database you will use. Put the data directory on the machine’s own storage, not a network share, and set up a nightly dump to an offsite target now rather than later — this database ends up holding the whole knowledge base.
docker pull pgvector/pgvector:pg18-trixieCREATE EXTENSION vector;run once in each database that stores embeddings
- 03
Serve the model with vLLMversion-sensitive
AssessmentvLLM "can be deployed as a server that implements the OpenAI API protocol", which is what lets the rest of the stack treat it as a drop-in endpoint. Start the official image with the GPU attached and the Hugging Face cache mounted, substituting the model you sized for — Qwen/Qwen2.5-14B-Instruct at 4-bit on a 24 GB card. Set an API key so nothing else on the network can use the GPU: pass `--api-key` or set `VLLM_API_KEY`. How much GPU memory this needs is computed for your own headcount in the hardware section above — weights from the model’s published parameter count, plus a KV cache sized for the concurrency assumed there, plus runtime overhead — and it is an assessment, not a measurement. Size the card against the typical figure, watch queue depth in the first month, and re-check before adding users.
docker run --runtime nvidia --gpus all \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=$HF_TOKEN" \ -p 8000:8000 \ --ipc=host \ vllm/vllm-openai:latest \ --model Qwen/Qwen3-0.6Bfrom the vLLM docs — replace the --model value with the model you sized for
curl http://localhost:8000/v1/modelsconfirm the server is up
- 04
Run Open WebUIversion-sensitive
AssessmentStart the container with a named volume so nothing is lost on restart, and pin a version tag rather than `:main` for a deployment people depend on — the docs are explicit that `:main` and `:latest` are rolling images. The first account created becomes the admin.
docker run -d -p 3000:8080 -v open-webui:/app/backend/data --name open-webui ghcr.io/open-webui/open-webui:main - 05
Point Open WebUI at the vLLM server
AssessmentIn Admin Settings → Connections → OpenAI → Manage, add a connection with the API URL `http://localhost:8000/v1` (or `http://host.docker.internal:8000/v1` when Open WebUI is itself in a container) and the API key you set on vLLM. The model then appears in the model selector.
- 06
Move Open WebUI onto PostgreSQL and pgvector
AssessmentThe default SQLite file and local Chroma index do not survive real concurrency. Set the database URL and switch the vector store to pgvector, then restart. Do this before loading documents: migrating a populated instance is far more work than starting on the right store.
DATABASE_URL=postgresql://user:password@db-host:5432/openwebui VECTOR_DB=pgvector PGVECTOR_DB_URL=postgresql://user:password@db-host:5432/openwebuienvironment variables from the scaling guide
- 07
Turn on single sign-on
AssessmentCreate an OIDC client in Keycloak (or your existing identity provider), then set `WEBUI_URL`, `OAUTH_CLIENT_ID`, `OAUTH_CLIENT_SECRET` and `OPENID_PROVIDER_URL` in Open WebUI. `OPENID_PROVIDER_URL` is mandatory and the redirect URI must be exactly `<your-domain>/oauth/oidc/callback`. Map identity-provider groups to Open WebUI groups so that access to a document collection follows the same rules as access to the file share.
- 08
Harden the deployment before anyone logs in
AssessmentOpen WebUI "is built for private, trusted networks": put it behind your VPN or a reverse proxy with TLS and IP allowlisting, and give it no public route. Set `WEBUI_SECRET_KEY` explicitly if you will ever run more than one instance, keep new accounts pending until an admin approves them, and set the secure-cookie and security-header variables.
DEFAULT_USER_ROLE=pendingWEBUI_SESSION_COOKIE_SECURE=true WEBUI_SESSION_COOKIE_SAME_SITE=strict - 09
Load a first document collection
AssessmentBuild one Knowledge collection for a single team and a single, well-understood set of documents — not the whole file server. Knowledge "uses retrieval (RAG) to find the relevant chunks on demand", so the quality of extraction sets the ceiling: switch the content-extraction engine to Docling if the corpus is scanned or table-heavy. Set the embedding model once, because changing it means re-indexing everything.
- 10
Evaluate retrieval before rollout, and again after
AssessmentWrite 30–50 real questions with the answer and the source document recorded by a person who knows the corpus. Measure two things separately: did retrieval surface the right document, and did the answer use it. Retrieval failures are fixed by chunking, the embedding model or metadata filters; answer failures by the prompt or a larger model. Keep the question set — it is how you will judge the next upgrade.
- 11
Set the operating routine
AssessmentNightly database dump held offsite; monthly patch window for the containers and the host; a named owner for adding and removing document collections; quarterly review of who has access to what. Watch GPU memory and queue depth — the first sign of outgrowing a 24 GB card is queuing at peak, not an error.
08Compliance considerations
Structured issue-spotting to support your own review — not legal advice. Verify against the cited primary sources and your counsel.
Applies everywhere
Personal datamedium
Documents and chat history will contain personal data about employees and clients. Decide the lawful basis and the retention period before ingesting, and record this system in your processing inventory: it is a new copy of personal data in a new place.
Confidentiality · Professional secrecyhigh
Client confidentiality and professional secrecy obligations survive the move into a search system. Scope collections by matter or team rather than making one company-wide index, and map identity-provider groups to Open WebUI groups so retrieval cannot cross a wall that the file server enforces.
Retentionmedium
Chats, uploaded files and embeddings are three separate copies with three separate lifetimes. Deleting a document from the source system does not remove its embeddings — write the deletion path down and test it.
Logging · Auditabilitymedium
Keep an access log that answers "who asked what, and which documents were returned". Retain it long enough to investigate an incident and no longer than your retention policy allows — the log is itself a record of personal data.
Securityhigh
Security controls that follow from the design: no public route, TLS on the internal name, an API key on the inference server, disk encryption on the machine holding the corpus, and admin approval for new accounts.
Open-source licensing · Intellectual propertyhigh
Open WebUI is not under a standard OSI licence. Its LICENSE adds a branding condition: licensees are "strictly prohibited from altering, removing, obscuring, or replacing any 'Open WebUI' branding", except where total end users "does not exceed fifty (50) within any rolling thirty (30) day period", with written permission, or under an enterprise licence. A 40-person firm running it unbranded is inside that exception today and outside it after 50 users — verify the current LICENSE text before you rebrand or grow. The other components carry their own licences (vLLM Apache-2.0, pgvector PostgreSQL licence, Qwen2.5-14B-Instruct per its model card); confirm each against the fetched licence text.
Data residency · Cross-border transfersinfo
No document, question or answer leaves the network in this design, so no cross-border transfer assessment is triggered by the AI system itself. The one outbound flow is the model download at install time, which carries no company data. If you later add a hosted model as a fallback, that decision reopens this question.
Human oversight · Transparencymedium
Tell staff what the system indexes and that their questions are logged, and state plainly that answers are drafts to be checked against the cited document. A retrieval system that is trusted without checking is a professional risk, not a technical one.
09Alternatives
AnythingLLM with Ollama
A single container plus Ollama, installed in an afternoon on a workstation. The right choice for a team under about 20 people or for proving the idea before buying a server.
- — Simpler to run and to explain
- — Lower throughput: Ollama serves fewer concurrent users than vLLM on the same GPU
- — Fewer administrative controls for groups and document permissions
Dify
Use Dify when the requirement grows past search into workflows and agents — approvals, multi-step tools, applications built on the corpus rather than a chat box over it.
- — Far more capable as a builder
- — More moving parts to operate
- — Chat-with-documents is one feature among many rather than the product
Onyx
Onyx leads with connectors: if most of the knowledge lives in Google Drive, SharePoint, Slack and Confluence rather than in a folder, start there instead of building ingestion.
- — Connector coverage and permission syncing out of the box
- — Heavier deployment
- — Less direct control over chunking and retrieval than a purpose-built RAG engine
Private-cloud RAG in one region
The same stack on a rented GPU instance in a region you name. Choose it when there is nowhere sensible to put a server, or when the workload is seasonal.
- — No hardware to buy, rack or replace
- — The cloud provider becomes a processor: DPA, region commitment and access review
- — Costs more than owning the box if it runs continuously for a year
- Private cloudPrivate-cloud RAG in a single regionA GPU instance in one region running vLLM and Open WebUI, a managed PostgreSQL with pgvector for chats and embeddings, object storage for the original files, and your existing identity provider for sign-in. Same software as the on-premise recipe; different trust boundary.
- Self-hostedPrivate ChatGPT on your own serverOllama serving an open-weight model on one GPU, Open WebUI in front of it for accounts, chats and admin controls, both in Docker on a single machine. Deliberately the smallest thing that works: no vector database, no connectors, no cluster.
10Evidence
Not yet in the ledger
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
not yet fetched
11Community
Deployed this stack, or hit something this page does not cover? Corrections, sources and implementation reports are what keep a recipe worth reading.
Improve this page
Sign in to contribute
From the field
0 deployments · 0 questions
Nobody has reported deploying this here yet, and no question has been opened against this page. Both appear once a reviewer accepts them.
12Hire an FDE
If you would rather not build it, we can introduce a forward-deployed engineer who has deployed this stack before. The enquiry form starts from this recipe.