AI-Q Helm Deployment

July 30, 2026 · View on GitHub

This directory contains Helm charts for deploying AI-Q to a Kubernetes cluster.

Directory Structure

deploy/helm/
├── README.md                  # This file — NGC chart install & shared configuration
├── deployment-k8s/            # Source chart wrapper (for repo-based deployments)
│   ├── Chart.yaml             #   Depends on helm-charts-k8s/aiq
│   ├── values.yaml            #   Deployment values
│   └── README.md              #   Source chart instructions & Kind local dev guide
└── helm-charts-k8s/
    └── aiq/                   # Base application Helm chart (templates, helpers)

Deployment Methods

MethodWhen to use
NGC Helm chartInstall a pre-built chart from the NGC Helm repository
Source chartYou cloned the repository and want to build/deploy from source

All examples use ns-aiq. The repository source chart derives every namespaced resource from Helm's .Release.Namespace, supplied with -n; use a different namespace consistently across Helm, Secrets, kubectl, and external identity bindings. The aiq.namespace.create value controls whether the source chart renders a Namespace object and does not override -n. The NGC instructions below install published chart 2.2.0. Use the source chart when you need behavior from the checked-out repository.

Prerequisites

  • Kubernetes cluster (EKS, GKE, AKS, or a local cluster such as Kind or Minikube)
  • kubectl configured with cluster access
  • helm v3.x installed
  • NGC API key (NGC_API_KEY environment variable)
  • Required API keys (refer to Secrets below)

Install from NGC Helm Repository

This section installs the pre-built chart aiq2-web version 2.2.0 from the NGC Helm repository (https://helm.ngc.nvidia.com/nvidia/blueprint/charts/).

1. Create the namespace

kubectl create namespace ns-aiq --dry-run=client -o yaml | kubectl apply -f -

2. Create secrets

API credentials for the application:

kubectl create secret generic aiq-credentials -n ns-aiq \
  --from-literal=NVIDIA_API_KEY="$NGC_API_KEY" \
  --from-literal=TAVILY_API_KEY="$TAVILY_API_KEY" \
  --from-literal=DB_USER_NAME="aiq" \
  --from-literal=DB_USER_PASSWORD="aiq_dev"

Image pull secret for the NGC container registry:

kubectl create secret docker-registry ngc-secret -n ns-aiq \
  --docker-server=nvcr.io \
  --docker-username='$oauthtoken' \
  --docker-password=$NGC_API_KEY

3. Pull the chart and install

Pull, verify, then install from local file:

helm pull https://helm.ngc.nvidia.com/nvidia/blueprint/charts/aiq2-web-2.2.0.tgz \
  --username='$oauthtoken' \
  --password=<YOUR_NGC_API_KEY>

# Verify the chart was pulled correctly
helm show chart aiq2-web-2.2.0.tgz

# Install from the local file
helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq --create-namespace \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret'
  • Replace <YOUR_NGC_API_KEY> with your NGC API key (or use $NGC_API_KEY if set in your environment).
  • To avoid exposing the key in shell history, use a variable: --password=$NGC_API_KEY.

Optional — Install directly from the chart URL (without pulling first):

helm upgrade --install aiq https://helm.ngc.nvidia.com/nvidia/blueprint/charts/aiq2-web-2.2.0.tgz \
  --username='$oauthtoken' \
  --password=$NGC_API_KEY \
  -n ns-aiq --create-namespace \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret'

Override values

Pass additional --set flags to customize the deployment:

helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret' \
  --set aiq.apps.backend.image.tag=<tag>

Or supply a custom values file:

helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  -f custom-values.yaml

Inspect default values

To see what values the chart supports before installing:

helm show values aiq2-web-2.2.0.tgz

Amazon OpenSearch Serverless

The backend image can be overridden through values without forking the chart:

aiq:
  apps:
    backend:
      image:
        repository: <registry>/<aiq-agent-image>
        tag: <tag>

For Amazon OpenSearch Serverless, set the backend workflow config to configs/config_web_opensearch.yml and configure SigV4 through environment values:

aiq:
  apps:
    backend:
      env:
        CONFIG_FILE: configs/config_web_opensearch.yml
        OPENSEARCH_URL: https://abc123.us-west-2.aoss.amazonaws.com
        OPENSEARCH_AUTH_TYPE: sigv4
        OPENSEARCH_AWS_SERVICE: aoss
        OPENSEARCH_INDEX_PREFIX: aiq
        AWS_REGION: us-west-2
        OPENSEARCH_INGESTION_MODE: auto
        OPENSEARCH_DASK_FILE_TRANSFER: bytes

A complete example is available at deploy/helm/examples/aws-opensearch-serverless-values.yaml.

For EKS Pod Identity, associate the IAM role with the backend service account for this release. These examples install into ns-aiq, and the backend service account is aiq-backend. If you change -n, create the association in that same release namespace. EKS Pod Identity associations are created through EKS, not by annotating the service account. The role also needs OpenSearch Serverless IAM access and a data access policy for the target collection/index pattern.

Verify

kubectl get pods -n ns-aiq

Expected output:

NAME                            READY   STATUS    RESTARTS   AGE
aiq-backend-xxx                 1/1     Running   0          30s
aiq-frontend-xxx                1/1     Running   0          30s
aiq-postgres-xxx                1/1     Running   0          30s

Health check

kubectl port-forward -n ns-aiq svc/aiq-backend 8000:8000 &
curl http://localhost:8000/live
curl http://localhost:8000/health

The backend liveness probe uses /live, which checks only that the API process responds. The readiness probe uses /health, which checks required dependencies and can return HTTP 503 without causing Kubernetes to restart the process.

The backend API docs are available at http://localhost:8000/docs while the port-forward is active.

Access the application

# Frontend UI
kubectl port-forward -n ns-aiq svc/aiq-frontend 3000:3000

# Backend API
kubectl port-forward -n ns-aiq svc/aiq-backend 8000:8000

Open http://localhost:3000 to access the web UI.

Upgrade

To upgrade an existing release to a newer chart version, pull the new chart archive (same NGC URL pattern with the new version, e.g. aiq2-web-<version>.tgz) or use the new chart URL for direct install, then run:

helm upgrade aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret'

Uninstall

helm uninstall aiq -n ns-aiq

# Optionally remove namespace and secrets
kubectl delete namespace ns-aiq

Configuration

The backend loads a workflow config at startup. Switch configs with --set:

Config fileDescription
configs/config_web_default_llamaindex.ymlDefault — LlamaIndex backend (no external RAG required)
configs/config_web_frag.ymlFoundational RAG mode (requires a running RAG service)
configs/config_web_frag_mcp_auth.ymlFoundational RAG with optional per-user MCP authentication
helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret' \
  --set aiq.apps.backend.env.CONFIG_FILE=configs/config_web_frag.yml

Per-user MCP authentication with external Redis

The chart does not install Redis. When selecting the per-user authentication config, provide a Redis service that the backend and its workers can both reach. The deployer owns its availability, persistence, networking, and backup.

Add REDIS_PASSWORD to the existing aiq-credentials Secret when the Redis service requires authentication, then create a values file:

# aiq-per-user-auth-values.yaml
aiq:
  apps:
    backend:
      env:
        CONFIG_FILE: configs/config_web_frag_mcp_auth.yml
        MCP_TOKEN_STORE_TYPE: redis
        REDIS_HOST: redis.example.com
        REDIS_PORT: "6379"
      secretEnv:
        REDIS_PASSWORD: REDIS_PASSWORD

Apply it to either the downloaded chart or a source-chart installation:

helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  -f aiq-per-user-auth-values.yaml

Configure MCP_GDRIVE_URL, AIQ_PUBLIC_URL, and any OAuth client credentials required by the protected MCP source through the same env and secretEnv maps. NAT 1.8's Redis object store in this image supports host, port, database, and optional password; this example does not support TLS, ACL usernames, Sentinel, or Redis Cluster.

FRAG Integration

To use the Foundational RAG (FRAG) config, you need a running NVIDIA RAG Blueprint deployment. Refer to the RAG Blueprint Helm deployment guide for setup instructions.

Same-cluster RAG connection

If the RAG Blueprint is deployed in the same Kubernetes cluster, use internal service DNS:

helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret' \
  --set aiq.apps.backend.env.CONFIG_FILE=configs/config_web_frag.yml \
  --set aiq.apps.backend.env.RAG_SERVER_URL=http://rag-server.<rag-namespace>.svc.cluster.local:8081/v1 \
  --set aiq.apps.backend.env.RAG_INGEST_URL=http://ingestor-server.<rag-namespace>.svc.cluster.local:8082/v1

Replace <rag-namespace> with the namespace where the RAG Blueprint is deployed.

External RAG connection

If the RAG service is running outside the cluster:

helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  --set 'aiq.apps.backend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.frontend.imagePullSecrets[0].name=ngc-secret' \
  --set 'aiq.apps.postgres.imagePullSecrets[0].name=ngc-secret' \
  --set aiq.apps.backend.env.CONFIG_FILE=configs/config_web_frag.yml \
  --set aiq.apps.backend.env.RAG_SERVER_URL=http://<rag-host>:8081/v1 \
  --set aiq.apps.backend.env.RAG_INGEST_URL=http://<rag-ingest-host>:8082/v1

Values file approach

For complex overrides, create a values file instead of passing many --set flags:

# aiq-frag-values.yaml
aiq:
  apps:
    backend:
      env:
        CONFIG_FILE: configs/config_web_frag.yml
        RAG_SERVER_URL: http://rag-server.rag-namespace.svc.cluster.local:8081/v1
        RAG_INGEST_URL: http://ingestor-server.rag-namespace.svc.cluster.local:8082/v1
helm upgrade --install aiq aiq2-web-2.2.0.tgz -n ns-aiq \
  --wait --timeout 10m \
  -f aiq-frag-values.yaml

Secrets

Required

KeyDescription
NVIDIA_API_KEYAPI key for NIM inference models
TAVILY_API_KEYTavily API key for web search
DB_USER_NAMEPostgreSQL username (default: aiq)
DB_USER_PASSWORDPostgreSQL password (default: aiq_dev)

Optional

KeyDescription
SERPER_API_KEYSerper API key for Google search
JINA_API_KEYJina API key
WANDB_API_KEYWeights & Biases API key
MODAL_TOKEN_IDModal sandbox token ID
MODAL_TOKEN_SECRETModal sandbox token secret
AIQ_ARTIFACT_BLOB_PROVIDERArtifact byte storage provider; unset or sql keeps bytes in SQL, s3 uses S3-compatible storage
AIQ_ARTIFACT_S3_BUCKETRequired when AIQ_ARTIFACT_BLOB_PROVIDER=s3
AIQ_ARTIFACT_S3_ENDPOINT_URLUnset for AWS S3; set for MinIO or compatible storage
AIQ_ARTIFACT_S3_REGIONOptional S3 region
AIQ_ARTIFACT_S3_PREFIXOptional object-key prefix; defaults to artifacts/v1
AWS_ACCESS_KEY_IDDevelopment-only S3-compatible access key; use workload identity in production
AWS_SECRET_ACCESS_KEYDevelopment-only S3-compatible secret key; use workload identity in production

Production artifact storage is operator-managed infrastructure. Configure the service account or workload with a short-lived role, restrict object operations to the AI-Q worker identity and configured bucket prefix, enable Block Public Access and TLS-only access, and enable storage-layer encryption such as SSE-KMS. AI-Q API ownership checks do not protect direct bucket access, and AI-Q does not application-encrypt artifact blob bytes.

Updating secrets

kubectl delete secret aiq-credentials -n ns-aiq
kubectl create secret generic aiq-credentials -n ns-aiq \
  --from-literal=NVIDIA_API_KEY="new-key" \  # pragma: allowlist secret
  --from-literal=TAVILY_API_KEY="new-key" \  # pragma: allowlist secret
  --from-literal=DB_USER_NAME="aiq" \
  --from-literal=DB_USER_PASSWORD="aiq_dev"

kubectl rollout restart deployment -n ns-aiq aiq-backend aiq-frontend

Troubleshooting

Pod status

kubectl get pods -n ns-aiq
kubectl describe pod <pod-name> -n ns-aiq
kubectl get events -n ns-aiq --sort-by='.lastTimestamp'

Logs

# Backend logs
kubectl logs -n ns-aiq -l component=backend -f

# Frontend logs
kubectl logs -n ns-aiq -l component=frontend -f

# Database init container logs
kubectl logs -n ns-aiq <backend-pod> -c db-init

Common issues

SymptomCauseFix
ImagePullBackOffMissing or incorrect image pull secretVerify ngc-secret exists and credentials are valid. Check kubectl describe pod <pod>.
CrashLoopBackOffMissing credentials or bad configCheck kubectl logs <pod> -n ns-aiq. Verify aiq-credentials secret has all required keys.
Pod stuck in PendingInsufficient cluster resources or PVC not boundCheck kubectl describe pod <pod> for scheduling errors. Verify PVC status with kubectl get pvc -n ns-aiq.
FRAG mode: RAG connection refusedRAG service not reachableVerify RAG pods are running and service DNS resolves. Test with kubectl exec into the backend pod and curl the RAG URL.
Health check failsBackend not fully startedWait for init containers to complete. Check kubectl logs <pod> -c db-init -n ns-aiq for database init issues.

Source Chart Deployment

For deploying from the cloned repository (building from source charts, local images, NGC images), refer to the deployment-k8s README.