Installing AI Knowledge Fabric on Kubernetes

This guide describes how to install the AI Knowledge Fabric management frontend in a Kubernetes cluster. Use it when you already run Kubernetes, or when one host is not enough for your Topics and Agents. For a single host, Docker Compose is simpler.


1. How the installation works

You install two workloads yourself, with the files in the k8s/ folder:

Workload Image Purpose

aiknowledgefabric

cyrockai/knowledge-fabric-frontend

The management frontend — web UI, REST API, and the part that starts Topics and Agents

postgres

postgres:16-alpine

Configuration store (topics, agents, pipelines, users, roles, chat history)

Everything else is created by the app itself while it runs. When you start a Topic, a GraphRAG Topic or an Agent in the web UI, the app creates a Deployment and a Service for it in the cluster. When you stop it, the app removes the Deployment again. This is why the app needs its own ServiceAccount with rights in its namespace.

                    ┌──────────────────────────────────────┐
  Browser ─────────►│  aiknowledgefabric          :8080    │
   (Ingress or      │  (management frontend)               │
    port-forward)   └───┬──────────────────────┬───────────┘
                        │                      │ Kubernetes API
                        ▼                      ▼ (ServiceAccount)
            ┌───────────────────┐   ┌──────────────────────────────────┐
            │ postgres          │   │  Created on demand:              │
            │                   │   │  topic-<id>, graphrag-<id>,      │
            └───────────────────┘   │  agent-<id>, ollama-server-<id>, │
                                    │  docling-server-<id>             │
                                    └──────────────────────────────────┘

The app notices by itself that it runs in Kubernetes. Inside the cluster, the app and the containers find each other by their Service names. You do not need to choose host ports, as you do with Docker.


2. Prerequisites

Requirement Notes

A Kubernetes cluster

Local (kind, minikube, k3s) or managed (EKS, GKE, AKS)

kubectl

Configured to reach the cluster, with rights to create a Role and a RoleBinding

A StorageClass with ReadWriteOnce

GraphRAG Topics, Agents and managed servers store data on volumes. Most clusters have a default class already — see Step 2

Access to Docker Hub

The cluster pulls the images from Docker Hub, unless you mirror them into your own registry

A license key

Without a valid key nothing can be created or started. See License


3. Installation

Step 1 — Choose a namespace (optional)

The files use the namespace default. To use your own namespace, create it:

kubectl create namespace aiknowledgefabric

Then replace every default namespace in k8s/rbac.yaml and k8s/deployment.yaml with your namespace. This also includes the address in CONTAINER_FRONTEND_URL (aiknowledgefabric.default.svc.cluster.local:8080). If you forget that one, Topics and Agents cannot verify tokens (they refuse to start) and the metrics dashboard stays empty. The app finds its own namespace by itself and creates all Topics and Agents there.

Step 2 — Check the StorageClass

GraphRAG Topics, Agents and managed servers store data on volumes. A RAG Topic needs none: its vectors are in its registered vector database. By default the app uses the default StorageClass of your cluster. Check that your cluster has one:

kubectl get storageclass

One line must say (default) after its name. Then there is nothing to do.

If no class is marked as default, or the volumes should use another class (for example a faster one), add this to the env: list of the aiknowledgefabric container in k8s/deployment.yaml:

- name: KUBERNETES_STORAGE_CLASS
  value: "local-path"      # a name from: kubectl get storageclass

If no volume can be created, GraphRAG Topics and Agents stay in Starting and go to Error after two minutes, without a clear message in the UI. You see the reason with kubectl get pvc: the volume has the status Pending.

Step 3 — Give the app its rights

kubectl apply -f k8s/rbac.yaml

This creates a ServiceAccount aiknowledgefabric with a Role in the namespace. The app uses it to create and remove Deployments, Services and volumes. The Agent containers use the same ServiceAccount: they start short-lived pods and jobs for Docker-based MCP tools and for Python scripts in pipelines.

Step 4 — Set the secrets

Open k8s/deployment.yaml and change the values in the Secret aiknowledgefabric-secrets at the top before you apply it:

Key What it is for

DB_PASSWORD

Password of the configuration database. Only used when the database is created for the first time

METRICS_API_KEY

Secret that Topics and Agents send when they report usage numbers to the app. Keeps strangers from sending fake numbers

CYROCK_LICENSE_KEY

Your license key. Optional here — you can also enter it later under Admin → License

A change to METRICS_API_KEY reaches running Topics and Agents only after you stop and start them in the UI.

Step 5 — Install

kubectl apply -f k8s/deployment.yaml
kubectl rollout status deployment/aiknowledgefabric

The first start pulls both images and creates the database tables. This usually takes one to three minutes.

Step 6 — Open the web UI

The app is only reachable inside the cluster at first. For a first test, forward the port to your computer:

kubectl port-forward svc/aiknowledgefabric 8080:8080

Then open localhost:8080 and log in with admin / admin. Change this password immediately under Profile → Change Password.

For permanent access, see Making the web UI reachable.

Step 7 — Post-installation checks

  1. Admin → License — check that the status is Valid, or paste your license key there.

  2. Admin → AI Servers — register at least one model provider. See Reaching AI servers and Docling.

  3. Admin → Users — create real user accounts and assign roles.

  4. Create and start a first Topic. When it reaches Running, the app can create workloads in the cluster.


4. What the app creates in the cluster

When you start something in the UI, the app creates these resources. All of them carry the label managed-by=aiknowledgefabric.

Started in the UI Deployment and Service Volumes

Topic

topic-<id>

none — the vectors are in the registered vector database

GraphRAG Topic

graphrag-<id>

graphrag-keyword-index-<id> (only when keyword search is switched on)

Agent

agent-<id>

pipeline-store-<id>

Managed Ollama AI server

ollama-server-<id>

ollama-server-data-<id> (downloaded models)

Managed Docling server

docling-server-<id>

docling-server-cache-<id>

  • Stop removes the Deployment. The volumes stay, so keyword indexes, pipelines and models are still there at the next start.

  • Delete in the UI also removes the Service and the volumes. This cannot be undone.

  • AI servers and Docling servers that are not managed by the app (external endpoints) get no resources at all. The app only checks that they answer.

To see everything the app created:

kubectl get deployments,services,pvc -l managed-by=aiknowledgefabric

Start time

A Topic, GraphRAG Topic or Agent counts as started when its pod reports ready. If that takes longer than two minutes, the app shows Error. The first start of a new image version takes longest, because the cluster downloads the image first. If your cluster pulls slowly, raise the waiting time (in seconds) in the app’s env: list:

Variable Default For

RAG_SERVICE_STARTUP_TIMEOUT

120

Topics

GRAPHRAG_SERVICE_STARTUP_TIMEOUT

120

GraphRAG Topics

AGENT_SERVER_STARTUP_TIMEOUT

120

Agents

K8S_DOCLING_STARTUP_TIMEOUT

120

Managed Docling servers

A higher value gives slow clusters more time. A lower value shows a broken start sooner.


5. Making the web UI reachable

The Service aiknowledgefabric is internal to the cluster. To reach the web UI from outside, use an Ingress. Example for the NGINX Ingress Controller:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aiknowledgefabric
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-body-size: "512m"
spec:
  rules:
  - host: knowledgefabric.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: aiknowledgefabric
            port:
              number: 8080
  • Timeouts: chat answers and uploads can take minutes. With short timeouts, long answers break off in the middle.

  • Body size: the default of NGINX is 1 MB. With it, larger document uploads are refused.

  • The web UI keeps a live connection to the browser (WebSocket). The NGINX Ingress Controller allows this by default.

Add TLS as usual for your cluster, for example with cert-manager.


6. Making Topics and Agents reachable from outside

The app creates the Services of Topics, GraphRAG Topics and Agents as internal Services. The web UI works without anything else: chats, downloads and pictures go through the app.

Publish them only if other systems should call a Topic or Agent directly — for example through its REST API or as an MCP tool. Publishing (Ingress, API gateway, TLS, rate limits) is up to you as cluster admin; the app does not do it.

The app must then know the public address, because the containers put it into the download and picture links they hand out. Set it under Admin → Public Endpoints, for example https://api.example.com/topics/{id}. Without it, external callers get links that only work inside the cluster.

Rules for the proxy in front of a Topic or Agent:

  • Forward to port 8080 of its Service and remove the path prefix — the containers expect their paths to start at /.

  • Switch off buffering and allow long timeouts. Otherwise chat answers arrive all at once at the end, or break off. With NGINX: nginx.ingress.kubernetes.io/proxy-buffering: "off".

  • Allow large request bodies for uploads (proxy-body-size).

  • Terminate TLS at the proxy. The containers speak plain HTTP.

A changed public address reaches a running Topic or Agent after you stop and start it in the UI.


7. Reaching AI servers and Docling

Topics and Agents call the AI servers and Docling servers you register under Admin. On Kubernetes, the address you register must work from inside a pod:

Where the server runs What to register

Cloud provider (OpenAI, Anthropic, Gemini)

The normal provider address. Nothing special to do

Managed by the app (Ollama or Docling started from the UI)

Nothing — the app sets the address inside the cluster by itself on the first start. Start a new managed server once before a Topic uses it

Another Deployment in the cluster

Its Service name, for example ollama.ai-tools.svc.cluster.local

A machine outside the cluster

An address of that machine that the pods can reach (IP address or DNS name)

Do not register localhost. Inside a pod, localhost is the pod itself. With Docker the app replaces localhost with the host machine, but Kubernetes has no such host. The Topic then starts, but every upload and chat fails with a connection error.

Keeping API keys out of the app (optional)

Normally the API key you enter for an AI server is passed to every Topic that uses it. If the key should not be stored in the app’s database, you can keep it in a Kubernetes Secret instead:

  1. Create the Secret with your keys:

    kubectl create secret generic aiknowledgefabric-api-keys \
      --from-literal=OPENAI_API_KEY=sk-...
  2. Under Admin → AI Servers, enter ${OPENAI_API_KEY} as the API Key — the name of the key in the Secret, in ${…}.

  3. The app itself also needs the key, to test the connection and to load the list of models. Enter OPENAI_API_KEY in Management API Key Env Var on the same form, and add the key to the env: list of the aiknowledgefabric container:

    - name: OPENAI_API_KEY
      valueFrom:
        secretKeyRef:
          name: aiknowledgefabric-api-keys
          key: OPENAI_API_KEY

    Without this step, the connection test fails and the model lists stay empty. You can still type the model name by hand.

Topics and GraphRAG Topics then read the key from the Secret when they start. If the Secret or the key is missing, the Topic still starts, but it cannot log in to the AI server: uploads and chats fail. A different Secret name is set with KUBERNETES_API_KEYS_SECRET. This works only for Topics and GraphRAG Topics.


8. CPU and memory

Each Topic, GraphRAG Topic and Agent gets a request (what the cluster reserves for it) and a limit (the most it may use). A higher request makes sure the work has room, but fewer pods fit on a node. A lower limit protects other workloads, but a pod that needs more memory is stopped and restarted by Kubernetes — you notice failed uploads or answers.

The defaults are set in the app’s env: list and apply to every new start:

Variables Default request / limit Applies to

K8S_TOPIC_CPU_REQUEST / K8S_TOPIC_CPU_LIMIT

250m / 2

Topics

K8S_TOPIC_MEMORY_REQUEST / K8S_TOPIC_MEMORY_LIMIT

512Mi / 2Gi

Topics

K8S_GRAPHRAG_CPU_REQUEST / K8S_GRAPHRAG_CPU_LIMIT

250m / 2

GraphRAG Topics

K8S_GRAPHRAG_MEMORY_REQUEST / K8S_GRAPHRAG_MEMORY_LIMIT

512Mi / 2Gi

GraphRAG Topics

K8S_AGENT_CPU_REQUEST / K8S_AGENT_CPU_LIMIT

250m / 1

Agents

K8S_AGENT_MEMORY_REQUEST / K8S_AGENT_MEMORY_LIMIT

512Mi / 1Gi

Agents

K8S_OLLAMA_CPU_REQUEST / K8S_OLLAMA_CPU_LIMIT

500m / 4

Managed Ollama servers

K8S_OLLAMA_MEMORY_REQUEST / K8S_OLLAMA_MEMORY_LIMIT

2Gi / 8Gi

Managed Ollama servers — larger models need more memory

K8S_DOCLING_CPU_REQUEST / K8S_DOCLING_CPU_LIMIT

250m / 2

Managed Docling servers

K8S_DOCLING_MEMORY_REQUEST / K8S_DOCLING_MEMORY_LIMIT

512Mi / 4Gi

Managed Docling servers — large PDFs need more memory

Single Topics and Agents can get their own values: on Kubernetes, their Configuration tab has a section Kubernetes Resources. GraphRAG Topics always use the defaults above. A change applies after the next stop and start.


9. Other settings

All settings of the Docker Compose installation also work here — set them in the env: list of the aiknowledgefabric container (secrets better as a secretKeyRef). Which settings are safe to change is on the page Supported settings. Settings only for Kubernetes:

Variable Default Description

KUBERNETES_STORAGE_CLASS

(empty — the cluster’s default class)

StorageClass of all volumes the app creates. Applies only to new volumes. See Step 2

KUBERNETES_KEYWORD_INDEX_SIZE

1Gi

Size of the keyword search volume of a GraphRAG Topic

KUBERNETES_AGENT_PIPELINE_STORE_SIZE

256Mi

Size of the volume that keeps an Agent’s pipelines

KUBERNETES_API_KEYS_SECRET

aiknowledgefabric-api-keys

Name of the Secret for API keys. See Keeping API keys out of the app

ORCHESTRATION_MODE

auto

auto detects Kubernetes by itself. Set kubernetes or docker only to force one

Volume sizes apply only to new volumes. An existing volume keeps its size, even after a stop and start.


10. Differences from Docker

  • No host ports. The port field of a Topic or Agent is not used. Topics and Agents are found by their Service names.

  • Local storage in pipelines. The KV Store Read / Write modules and File modules that use the local file system do not work on Kubernetes. The Agent refuses a pipeline that contains them. Use a storage outside the Agent instead.

  • No localhost servers. See Reaching AI servers and Docling.

  • Pod restarts by Kubernetes keep the settings the pod was started with. Changed settings — for example a new public address or license key — reach a Topic or Agent only when you stop and start it in the UI.


11. Updating

The images use a floating version tag and are pulled again on every start:

kubectl rollout restart deployment/aiknowledgefabric

Then stop and start your Topics, GraphRAG Topics and Agents in the UI, so that all parts run matching versions.


12. Uninstalling

# Stop all Topics, GraphRAG Topics and Agents in the UI first, then:
kubectl delete deployments,services,pvc -l managed-by=aiknowledgefabric   # all Topics and Agents incl. their data
kubectl delete -f k8s/deployment.yaml                                      # app, database and its volume
kubectl delete -f k8s/rbac.yaml
kubectl delete secret aiknowledgefabric-api-keys --ignore-not-found

This deletes all data, including the configuration database. It cannot be undone.


13. Troubleshooting

Symptom Cause and fix

Topics stay in Starting and then go to Error

For a GraphRAG Topic, often the volume cannot be created: kubectl get pvc shows Pending. Make sure the cluster has a default StorageClass, or set one (Step 2). Otherwise check kubectl describe pod topic-<id> (or graphrag-<id>) — for example the image download may be too slow (Start time)

A Topic cannot start at all, and the message says it has no vector database

The Topic was created without a vector database. That is no longer possible. Create a RAG Topic again with a vector database. For a GraphRAG Topic, edit it and select a vector database

Starting anything fails with a "forbidden" error in the app log

k8s/rbac.yaml was not applied, or applied to another namespace than the app

Python scripts or Docker-based MCP tools in pipelines fail

The Agent cannot start its helper pods or jobs. Apply the current k8s/rbac.yaml again

Topic is running, but uploads and chats fail with a connection error

The AI server or Docling server is registered with an address that pods cannot reach, for example localhost. See Reaching AI servers and Docling

Topic is running, but the AI server refuses the login

The API key is entered as ${…}, but the Secret or the key in it is missing

Metrics dashboard shows demo data only

CONTAINER_FRONTEND_URL points to the wrong namespace, or METRICS_API_KEY was changed and the Topics were not restarted

Long chat answers break off

Timeouts of the Ingress are too short. See Making the web UI reachable

Large uploads are refused

Body size limit of the Ingress. See Making the web UI reachable

"There is no valid license" when creating or starting

No valid license key. Add it under Admin → License, or as CYROCK_LICENSE_KEY in the Secret


Next steps

  • Getting Started — model provider, Docling, first Topic, upload, chat

  • 3.0 Configuration — AI servers, vector databases, users, and roles