OKP Deployment and Configuration Guide
This document explains how to deploy the Offline Knowledge Portal (OKP) as a RAG source and configure Lightspeed Stack and OGX to use it. You will:
- Deploy and verify the OKP Solr service
- Configure Lightspeed Stack for OKP (inline or tool RAG)
- Install dependencies and launch Lightspeed Stack
- Confirm the end-to-end stack with a sample query
For general RAG concepts, BYOK vector stores, and manual OGX configuration, see the RAG Configuration Guide.
Table of Contents
- Introduction
- Prerequisites
- Step 1: Launch OKP
- Step 2: Install Dependencies and Set Environment Variables
- Step 3: Configure Lightspeed Stack
- Step 4: Launch Lightspeed Stack
- Step 5: Verify the Stack
Introduction
OKP (Offline Knowledge Portal) provides a Solr-backed RAG source that
Lightspeed Stack can use for both Inline RAG (context injected before the
LLM request) and Tool RAG (context retrieved on demand via the
file_search tool). This guide walks through deploying the OKP container,
configuring Lightspeed Stack for OKP, and
validating that queries return referenced chunks.
Prerequisites
- lightspeed-stack repository cloned with submodules:
git clone --recursive https://github.com/lightspeed-core/lightspeed-stack.gitIf you already cloned without
--recursive, run:git submodule update --init - Podman (or Docker) to run the OKP image
- uv for Python dependency management
- An OpenAI API key (for inference when using OpenAI in your run config)
Step 1: Launch OKP
Start the OKP RAG service with Podman or Docker:
Using Podman:
podman login registry.redhat.io
podman run --rm -d -p 8081:8080 registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
Using Docker:
docker login registry.redhat.io
docker run --rm -d -p 8081:8080 registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
Note: Remove
-dto run in the foreground.
- The service listens on port 8081 on the host (mapped from 8080 in the container). Lightspeed Stack itself listens on
8080, so this avoids port conflicts. -
Confirm it is running by opening in a browser or with
curl:curl -s http://localhost:8081Or visit: http://localhost:8081
Note: The default OKP URL is configured via the
RH_SERVER_OKPenvironment variable (see Step 2). You can override this by setting a different value forRH_SERVER_OKP, or by changing theokp.rhokp_urlfield inlightspeed-stack.yaml. β
Step 2: Install Dependencies and Set Environment Variables
Install dependencies:
uv sync --group dev --group ogxlibdev
Set required environment variables:
export OPENAI_API_KEY=<your-openai-api-key>
# Set OKP URL env var, using special hostname for container-to-host networking
# when running locally
# Podman:
export RH_SERVER_OKP=http://host.containers.internal:8081
# Docker:
# export RH_SERVER_OKP=http://host.docker.internal:8081
Step 3: Configure Lightspeed Stack
Enable OKP in Lightspeed Stack
Edit your Lightspeed Stack config file (e.g. lightspeed-stack.yaml) and add
the following top-level sections so that OKP is used for either inline or tool
RAG:
Inline RAG:
# RAG configuration
rag:
retrieval:
inline:
sources:
- okp
max_chunks: 3 # Final tight cap on chunks returned to user
okp:
rhokp_url: ${env.RH_SERVER_OKP}
offline: true
max_chunks: 5 # Initial generous fetch from OKP
Tool RAG:
# RAG configuration
rag:
retrieval:
tool:
sources:
- okp
max_chunks: 10 # Tool RAG limit
okp:
rhokp_url: ${env.RH_SERVER_OKP}
offline: true
max_chunks: 5
rag.retrieval.inlineandrag.retrieval.tool: Enable OKP as the RAG source for inline context injection and for the RAG tool. Tool RAG means the LLM will be provided a search tool it can choose to invoke to find relevant content and augment the user prompt. The tool may or may not be invoked. Inline RAG means a RAG search and prompt augmentation will always occur.okp.offline: Whentrue, source URLs useparent_id(offline/Mimir-style). Whenfalse, usereference_url(online).okp.search_mode: Default Solr search strategy for OKP queries. Controls how Solr ranks chunks, not which documents are eligible (that ischunk_filter_queryand per-requestsolr.filters). Allowed values:hybrid(default when the field is omitted): combines vector similarity with keyword (BM25) text search. Requires an embedding model. This is the global default.semantic: pure vector search against Solr embeddings. Requires an embedding model. Best when the query is conceptual rather than matching document wording.keyword: BM25 text search only. No embedding model is needed, so it is the right choice for air-gapped or embedding-free deployments, and it is typically faster than hybrid.
max_chunksbehavior:- Inline RAG:
rag.retrieval.inline.max_chunksis the final tight cap on chunks returned in the response, whilerag.okp.max_chunksis the initial generous fetch from OKP before filtering and ranking. - Tool RAG:
rag.retrieval.tool.max_chunkssets the limit on chunks available to the tool.
- Inline RAG:
If you want to filter the docs to a specific product, you can include a static query filter such as:
okp:
offline: true
search_mode: keyword
chunk_filter_query: "product:*openshift* AND product_version:4.21"
A per-request solr.mode on /v1/query (or streaming/responses) overrides this YAML default for that call. Per-request lexical is treated as keyword.
Important: When running OGX in Server mode, changes to static OKP settings such as
chunk_filter_queryandsearch_moderequire an OGX restart to take effect. They are applied when Lightspeed Stack enriches OGX configuration at startup and will not propagate automatically during runtime.
When you launch Lightspeed Stack it will augment the OGX configuration (the synthesized run.yaml in unified mode, or your external run.yaml in the deprecated legacy mode) with configuration for OKP.
Dynamic Metadata Filtering
In addition to static filters configured in lightspeed-stack.yaml, you can apply dynamic filters per query using structured filter objects in the request. Dynamic filters are combined with static filters using AND logic.
Supported Filter Operations
Comparison Filters:
eq- Equal to (exact match)ne- Not equal toin- Value in listnin- Value not in list
Compound Filters:
and- All filters must matchor- Any filter must match
Note: Range operators (
gt,gte,lt,lte) are not supported because they use lexicographic comparison on string fields, which can produce unexpected results.
Dynamic Filter Examples
Simple equality filter:
curl -sX POST http://localhost:8080/v1/query \
-H "Content-Type: application/json" \
-d '{
"query": "How to install ansible?",
"solr": {
"mode": "hybrid",
"filters": {
"filters": {
"type": "eq",
"key": "product",
"value": "ansible_automation_platform"
}
}
}
}'
Multiple values with βinβ filter:
curl -sX POST http://localhost:8080/v1/query \
-H "Content-Type: application/json" \
-d '{
"query": "Security best practices",
"solr": {
"mode": "semantic",
"filters": {
"filters": {
"type": "in",
"key": "product",
"value": ["openshift_container_platform", "ansible_automation_platform", "red_hat_enterprise_linux"]
}
}
}
}'
Compound filters (AND/OR):
curl -sX POST http://localhost:8080/v1/query \
-H "Content-Type: application/json" \
-d '{
"query": "Advanced configuration",
"solr": {
"mode": "hybrid",
"filters": {
"filters": {
"type": "and",
"filters": [
{"type": "eq", "key": "product", "value": "openshift_container_platform"},
{"type": "eq", "key": "product_version", "value": "4.21"}
]
}
}
}
}'
Nested compound filters:
curl -sX POST http://localhost:8080/v1/query \
-H "Content-Type: application/json" \
-d '{
"query": "Troubleshooting guide",
"solr": {
"mode": "hybrid",
"filters": {
"filters": {
"type": "and",
"filters": [
{"type": "eq", "key": "doc_type", "value": "guide"},
{
"type": "or",
"filters": [
{"type": "eq", "key": "product", "value": "openshift_container_platform"},
{"type": "eq", "key": "product", "value": "ansible_automation_platform"}
]
}
]
}
}
}
}'
Filter Behavior
- Static filters preserved: The configured
chunk_filter_query(e.g.,"product:*openshift*") is always applied - Dynamic filters added: Request filters are combined with static filters using AND logic
- String escaping: Special Solr characters in filter values are automatically escaped
- Works with all search modes: Filters apply whether the search mode is
semantic,hybrid, orkeyword(per-requestlexicalis an alias ofkeyword).
Step 4: Launch Lightspeed Stack
Then launch Lightspeed Stack using your Lightspeed Stack
config(lightspeed-stack.yaml) which references the provided default
Effective OGX config (the synthesized run.yaml β in legacy mode, your external run.yaml):
make run
Lightspeed Stack has launched successfully and is available when you see this log output:
INFO 2026-03-17 11:20:31,347 uvicorn.error:62 uncategorized: Application startup complete.
INFO 2026-03-17 11:20:31,349 uvicorn.error:224 uncategorized: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
Step 5: Verify the Stack
Confirm that the full stack (Lightspeed Stack + OGX + OKP) is working by sending a query and checking that the response includes referenced chunks from OKP:
curl -sX POST http://localhost:8080/v1/query \
-H "Content-Type: application/json" \
-d '{"query": "configure remote desktop using gnome"}' | jq .
- Adjust the URL and port if your Lightspeed Stack API is exposed elsewhere.
- In the JSON response, look for
rag_chunksthat indicate OKP/Solr results were retrieved.
Example response excerpt:
"rag_chunks": [
{
"content": "You can connect from a Red Hat Enterprise Linux client to a remote desktop server by using the\n**Connections**\napplication. The connection depends on the remote server configuration.\n**Prerequisites**\n- Desktop sharing or remote login is enabled on the server. For more information, see [Enabling desktop sharing on the server by using GNOME](#enabling-desktop-sharing-on-the-server-by-using-gnome) or [Configuring GNOME remote login](#configuring-gnome-remote-login) .\n- For desktop sharing, a user is logged in to the GNOME graphical session on the server.\n- The `gnome-connections` package is installed on the client.\n**Procedure**\n1. On the client, launch the **Connections** application.\n2. Click the + button in the top bar to open a new connection.\n4. Enter the IP address of the server.\n5. Choose the connection type based on the operating system you want to connect to: Remote Desktop Protocol (RDP) Use RDP for connecting to Windows and RHEL 10 servers. Virtual Network Computing (VNC) Use VNC for connecting to servers with RHEL 9 and previous versions.\n6. Click Connect .\n**Verification**\n1. On the client, check that you can see the shared server desktop.\n2. On the server, a screen sharing indicator appears on the right side of the top panel: You can control screen sharing in the **System** menu of the server.",
"source": "okp",
"score": 826.40784,
"attributes": {
"doc_url": "https://mimir.corp.redhat.com/documentation/en-us/red_hat_enterprise_linux/10/html-single/administering_rhel_by_using_the_gnome_desktop_environment/index",
"document_id": "/documentation/en-us/red_hat_enterprise_linux/10/html-single/administering_rhel_by_using_the_gnome_desktop_environment/index"
}
}
],
Note: The first time you query the system,
hybridorsemanticsearch may take additional time because OGX must download the embedding model used for vector search.keywordsearch skips that download.
If you see no RAG context, verify:
- OKP is up at http://localhost:8081
lightspeed-stack.yamlhasokpunderrag.inlineand/orrag.toolas in Step 4
The Behave suite okp_rag.feature (@cfg_okp) runs in Konflux in CI. To stand up OKP + OGX + LCS on a laptop and run a matching scenario, see Running OKP RAG tests locally.