Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ S3_SECRET_ACCESS_KEY=your_s3_secret_key_here
# =============================================================================
# Basic Authentication (Required)
# =============================================================================
BASIC_AUTH="foo:$apr1$ryE0iE7H$F2SlPDNoFdGoaHrcla2HL/"
# Used for backend/admin endpoints and reused by the frontend's auth prompt.
BASIC_AUTH_USER=foo
BASIC_AUTH_PASSWORD=bar

# =============================================================================
# Langfuse Configuration (Required for observability)
Expand All @@ -27,12 +29,6 @@ LANGFUSE_INIT_USER_EMAIL="user@stackit.cloud"
LANGFUSE_INIT_USER_NAME="stackiteer"
LANGFUSE_INIT_USER_PASSWORD="stackit123"

# =============================================================================
# Frontend Authentication (Required)
# =============================================================================
VITE_AUTH_USERNAME=foo
VITE_AUTH_PASSWORD=bar

# =============================================================================
# LLM Provider API Keys (Choose one or more)
# =============================================================================
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
**/.env.langfuse
**/.nx/*
*.tgz
*/Chart.lock
Expand Down
32 changes: 21 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,28 +208,33 @@ For local deployment, a few env variables need to be provided by an `.env` file
The `.env` needs to contain the following values:

```dotenv
BASIC_AUTH=Zm9vOiRhcHIxJGh1VDVpL0ZKJG10elZQUm1IM29JQlBVMlZ4YkpUQy8K
# Basic auth (used by backend/admin ingress and the frontend prompt)
BASIC_AUTH_USER=...
BASIC_AUTH_PASSWORD=...

S3_ACCESS_KEY_ID=...
S3_SECRET_ACCESS_KEY=...

VITE_AUTH_USERNAME=...
VITE_AUTH_PASSWORD=...
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# Optional keys
RAGAS_OPENAI_API_KEY=...

STACKIT_VLLM_API_KEY=...
STACKIT_EMBEDDER_API_KEY=...

# ONLY necessary, if no init values are set. if init values are set,
# the following two values should match the init values or be commented out
# or be created via the langfuse UI.
LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Optional Langfuse init values (omit if you already created a project/user)
LANGFUSE_INIT_ORG_ID=...
LANGFUSE_INIT_PROJECT_ID=...
LANGFUSE_INIT_PROJECT_PUBLIC_KEY=...
LANGFUSE_INIT_PROJECT_SECRET_KEY=...
LANGFUSE_INIT_USER_EMAIL=...
LANGFUSE_INIT_USER_NAME=...
LANGFUSE_INIT_USER_PASSWORD=...

```

This results in a basic auth with username=`foo` and password=`bar`.
Using the defaults in `.env.template` results in a basic auth with username=`foo` and password=`bar`.

> 📝 NOTE: All values containing `...` are placeholders and have to be replaced with real values.
> This deployment comes with multiple options. You change the `global.config.envs.rag_class_types.RAG_CLASS_TYPE_LLM_TYPE` in the helm-deployment to on of the following values:
Expand All @@ -238,6 +243,12 @@ This results in a basic auth with username=`foo` and password=`bar`.
> - `ollama`: Uses ollama as an LLM provider.
>

##### Langfuse init secret (dev-only, Tilt + Kustomize)

- Copy `infrastructure/kustomize/langfuse/.env.langfuse.template` to `infrastructure/kustomize/langfuse/.env.langfuse` and fill in your Langfuse init values (org/project/user and API keys) before starting Tilt.
- Tilt runs Kustomize automatically to create a stable `langfuse-init-secrets` secret before Helm applies manifests.
- Use this helper only for local/dev. For production, manage secrets via your usual mechanism and point `secretKeyRef.name` in `values.yaml` to your precreated secrets.

#### 1.4.1 Environment Variables Setup

Before running the application, you need to configure environment variables. Copy the provided example file and fill in your values:
Expand Down Expand Up @@ -483,4 +494,3 @@ The linting-settings can be changed in the `services/rag-backend/pyproject.toml`
## 4. Contribution Guidelines

In order to contribute please consult the [CONTRIBUTING.md](./CONTRIBUTING.md).

42 changes: 17 additions & 25 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,14 @@ local_resource(
allow_parallel=True,
)

# Dev-only Langfuse init secrets via Kustomize (stable name, no hash suffix)
langfuse_kustomize_dir = "./infrastructure/kustomize/langfuse"
langfuse_env_file = "%s/.env.langfuse" % langfuse_kustomize_dir
if os.path.exists(langfuse_env_file):
watch_file(langfuse_env_file)
watch_file("%s/kustomization.yaml" % langfuse_kustomize_dir)
k8s_yaml(kustomize(langfuse_kustomize_dir))

########################################################################################################################
################################## build document extractor image and do live update ##############################################
########################################################################################################################
Expand Down Expand Up @@ -469,14 +477,13 @@ docker_build(
########################################################################################################################
value_override = [
# secrets env
"shared.secrets.s3.accessKey=%s" % os.environ["S3_ACCESS_KEY_ID"],
"shared.secrets.s3.secretKey=%s" % os.environ["S3_SECRET_ACCESS_KEY"],
"backend.secrets.basicAuth=%s" % os.environ["BASIC_AUTH"],
"backend.secrets.langfuse.publicKey=%s" % os.environ["LANGFUSE_PUBLIC_KEY"],
"backend.secrets.langfuse.secretKey=%s" % os.environ["LANGFUSE_SECRET_KEY"],
"backend.secrets.ragas.openaiApikey=%s" % os.environ["RAGAS_OPENAI_API_KEY"],
"frontend.secrets.viteAuth.VITE_AUTH_USERNAME=%s" % os.environ["VITE_AUTH_USERNAME"],
"frontend.secrets.viteAuth.VITE_AUTH_PASSWORD=%s" % os.environ["VITE_AUTH_PASSWORD"],
"shared.secrets.s3.accessKey.value=%s" % os.environ["S3_ACCESS_KEY_ID"],
"shared.secrets.s3.secretKey.value=%s" % os.environ["S3_SECRET_ACCESS_KEY"],
"shared.secrets.basicAuthUser.value=%s" % os.environ["BASIC_AUTH_USER"],
"shared.secrets.basicAuthPassword.value=%s" % os.environ["BASIC_AUTH_PASSWORD"],
"backend.secrets.langfuse.publicKey.value=%s" % os.environ["LANGFUSE_PUBLIC_KEY"],
"backend.secrets.langfuse.secretKey.value=%s" % os.environ["LANGFUSE_SECRET_KEY"],
"backend.secrets.ragas.openaiApikey.value=%s" % os.environ["RAGAS_OPENAI_API_KEY"],
# variables
"shared.debug.backend.enabled=%s" % backend_debug,
"features.frontend.enabled=true",
Expand All @@ -487,21 +494,6 @@ value_override = [
"features.mcp.enabled=true",
# ingress host names
"backend.ingress.host.name=rag.localhost",
# langfuse
"langfuse.langfuse.additionalEnv[0].name=LANGFUSE_INIT_ORG_ID",
"langfuse.langfuse.additionalEnv[0].value=\"%s\"" % os.environ["LANGFUSE_INIT_ORG_ID"],
"langfuse.langfuse.additionalEnv[1].name=LANGFUSE_INIT_PROJECT_ID",
"langfuse.langfuse.additionalEnv[1].value=\"%s\"" % os.environ["LANGFUSE_INIT_PROJECT_ID"],
"langfuse.langfuse.additionalEnv[2].name=LANGFUSE_INIT_PROJECT_PUBLIC_KEY",
"langfuse.langfuse.additionalEnv[2].value=%s" % os.environ["LANGFUSE_INIT_PROJECT_PUBLIC_KEY"],
"langfuse.langfuse.additionalEnv[3].name=LANGFUSE_INIT_PROJECT_SECRET_KEY",
"langfuse.langfuse.additionalEnv[3].value=%s" % os.environ["LANGFUSE_INIT_PROJECT_SECRET_KEY"],
"langfuse.langfuse.additionalEnv[4].name=LANGFUSE_INIT_USER_EMAIL",
"langfuse.langfuse.additionalEnv[4].value=%s" % os.environ["LANGFUSE_INIT_USER_EMAIL"],
"langfuse.langfuse.additionalEnv[5].name=LANGFUSE_INIT_USER_PASSWORD",
"langfuse.langfuse.additionalEnv[5].value=%s" % os.environ["LANGFUSE_INIT_USER_PASSWORD"],
"langfuse.langfuse.additionalEnv[6].name=LANGFUSE_INIT_USER_NAME",
"langfuse.langfuse.additionalEnv[6].value=%s" % os.environ["LANGFUSE_INIT_USER_NAME"],
]

def has_confluence_config():
Expand Down Expand Up @@ -532,13 +524,13 @@ if has_confluence_config():

if os.environ.get("STACKIT_VLLM_API_KEY", False):
stackit_vllm_settings = [
"backend.secrets.stackitVllm.apiKey=%s" % os.environ["STACKIT_VLLM_API_KEY"],
"backend.secrets.stackitVllm.apiKey.value=%s" % os.environ["STACKIT_VLLM_API_KEY"],
]
value_override.extend(stackit_vllm_settings)

if os.environ.get("STACKIT_EMBEDDER_API_KEY", False):
stackit_embedder_settings = [
"backend.secrets.stackitEmbedder.apiKey=%s" % os.environ["STACKIT_EMBEDDER_API_KEY"],
"backend.secrets.stackitEmbedder.apiKey.value=%s" % os.environ["STACKIT_EMBEDDER_API_KEY"],
]
value_override.extend(stackit_embedder_settings)

Expand Down
66 changes: 52 additions & 14 deletions infrastructure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ Default values for the deployment are provided in the `rag/values.yaml` file und
>
>All values containing `...` are placeholders and have to be replaced with real values.

**Dev helper via Kustomize/Tilt**
For local development you can let Tilt generate Langfuse init secrets automatically:
- Copy `infrastructure/kustomize/langfuse/.env.langfuse.template` to `.env.langfuse` and fill it with the Langfuse init env values.
- Tilt runs Kustomize on `infrastructure/kustomize/langfuse` and applies the resulting `langfuse-init-secrets` (hash disabled) before Helm resources.
- This is dev-only. For production, create/manage secrets with your secret manager and set `secretKeyRef.name` in `values.yaml` to your managed secret.

### 1.2 Qdrant

The deployment of the Qdrant can be disabled by setting the following value in the helm-chart:
Expand Down Expand Up @@ -233,6 +239,20 @@ langfuse:
The following values should be adjusted for the deployment:

```yaml
shared:
secrets:
# Required: Basic authentication used by backend/admin ingress and frontend auth modal
basicAuthUser:
value: ... # Username for basic auth
secretKeyRef:
name: "" # Optionally reference an existing secret instead of an inline value
key: "BASIC_AUTH_USER"
basicAuthPassword:
value: ... # Password for basic auth
secretKeyRef:
name: ""
key: "BASIC_AUTH_PASSWORD"

frontend:
envs:
vite:
Expand All @@ -246,11 +266,9 @@ frontend:
host:
name: ... # Your domain name (e.g., rag.yourdomain.com)

secrets:
viteAuth:
# Required: Credentials for backend authentication
VITE_AUTH_USERNAME: ... # Username for basic auth
VITE_AUTH_PASSWORD: ... # Password for basic auth
# In production, ensure a secret named "vite-auth" exists with keys
# VITE_AUTH_USERNAME and VITE_AUTH_PASSWORD set to your basic auth creds.
# (For local/dev, the chart can generate it from shared.secrets.)
```

### 1.5 Backend
Expand All @@ -260,24 +278,42 @@ The following values should be adjusted for the deployment:
```yaml
backend:
secrets:
# Required: Basic authentication for the backend API
basicAuth: ... # Set your basic auth credentials

# Basic auth is configured under shared.secrets (see frontend section)
# Required: Langfuse API keys for observability
langfuse:
publicKey: ... # Your Langfuse public key
secretKey: ... # Your Langfuse secret key
publicKey:
value: ... # Your Langfuse public key
secretKeyRef:
name: "" # Optionally reference an existing secret instead of an inline value
key: "LANGFUSE_PUBLIC_KEY"
secretKey:
value: ... # Your Langfuse secret key
secretKeyRef:
name: ""
key: "LANGFUSE_SECRET_KEY"

# Required: API keys for your chosen LLM provider
# STACKIT LLM provider
stackitEmbedder:
apiKey: ... # Your STACKIT embedder API key
apiKey:
value: ... # Your STACKIT embedder API key
secretKeyRef:
name: ""
key: "STACKIT_EMBEDDER_API_KEY"
stackitVllm:
apiKey: ... # Your STACKIT vLLM API key
apiKey:
value: ... # Your STACKIT vLLM API key
secretKeyRef:
name: ""
key: "STACKIT_VLLM_API_KEY"

# Optional: Only needed if using RAGAS evaluation with OpenAI
ragas:
openaiApikey: ... # Your OpenAI API key for RAGAS evaluation
openaiApikey:
value: ... # Your OpenAI API key for RAGAS evaluation
secretKeyRef:
name: ""
key: "RAGAS_OPENAI_API_KEY"

envs:
# Required: Choose your LLM and embedder providers
Expand Down Expand Up @@ -310,13 +346,15 @@ backend:
ERROR_MESSAGES_NO_ANSWER_FOUND: "I'm sorry, I couldn't find an answer with the context provided."
# Settings for the evaluation. You can specify the datasetname, as well as the path (in the container) where the dataset is located.
langfuse:
LANGFUSE_DATASET_NAME: "test_ds"
LANGFUSE_DATASET_NAME: "rag_test_ds"
LANGFUSE_DATASET_FILENAME: "/app/test_data.json"

ragas:
RAGAS_IS_DEBUG: false
RAGAS_MODEL: "gpt-4o-mini"
RAGAS_USE_OPENAI: true
RAGAS_TIMEOUT: 60
RAGAS_EVALUATION_DATASET_NAME: "eval-data"
RAGAS_MAX_CONCURRENCY: "5"

ingress:
Expand Down
8 changes: 8 additions & 0 deletions infrastructure/kustomize/langfuse/.env.langfuse.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copy to .env.langfuse and replace with your real Langfuse init values.
LANGFUSE_INIT_ORG_ID=your-org-id
LANGFUSE_INIT_PROJECT_ID=your-project-id
LANGFUSE_INIT_PROJECT_PUBLIC_KEY=your-project-public-key
LANGFUSE_INIT_PROJECT_SECRET_KEY=your-project-secret-key
LANGFUSE_INIT_USER_EMAIL=admin@example.com
LANGFUSE_INIT_USER_NAME=Admin
LANGFUSE_INIT_USER_PASSWORD=changeme
12 changes: 12 additions & 0 deletions infrastructure/kustomize/langfuse/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: rag

secretGenerator:
- name: langfuse-init-secrets
envs:
- .env.langfuse
type: Opaque
options:
# Keep a stable name so Helm/Tilt can reference the secret directly.
disableNameSuffixHash: true
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,42 @@
{{- printf "%s-stackit-vllm-secret" .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{- define "secret.langfuseRefName" -}}
{{- if .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}}
{{- .Values.backend.secrets.langfuse.publicKey.secretKeyRef.name -}}
{{- else if .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}}
{{- .Values.backend.secrets.langfuse.secretKey.secretKeyRef.name -}}
{{- else -}}
{{ template "secret.langfuseName" . }}
{{- end -}}
{{- end -}}

{{- define "secret.stackitVllmRefName" -}}
{{- if .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}}
{{- .Values.backend.secrets.stackitVllm.apiKey.secretKeyRef.name -}}
{{- else -}}
{{ template "secret.stackitVllmName" . }}
{{- end -}}
{{- end -}}

{{- define "secret.stackitEmbedderRefName" -}}
{{- if .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}}
{{- .Values.backend.secrets.stackitEmbedder.apiKey.secretKeyRef.name -}}
{{- else -}}
{{ template "secret.stackitEmbedderName" . }}
{{- end -}}
{{- end -}}

{{- define "secret.s3RefName" -}}
{{- if .Values.shared.secrets.s3.accessKey.secretKeyRef.name -}}
{{- .Values.shared.secrets.s3.accessKey.secretKeyRef.name -}}
{{- else if .Values.shared.secrets.s3.secretKey.secretKeyRef.name -}}
{{- .Values.shared.secrets.s3.secretKey.secretKeyRef.name -}}
{{- else -}}
{{ template "secret.s3Name" . }}
{{- end -}}
{{- end -}}

# configmaps
{{- define "configmap.s3Name" -}}
{{- printf "%s-s3-configmap" .Release.Name | trunc 63 | trimSuffix "-" -}}
Expand Down
Loading