Kubernetes (Helm)
Deploy nivq to a Kubernetes cluster with the official Helm chart — image pull secret, values, install, activation, ingress, and scaling.
Running on a cluster? nivq has an official Helm chart. The chart installs the application only — you bring the PostgreSQL (with pgvector) and Redis/Valkey; it doesn't bundle datastores. Managed services and ones you run in-cluster both work.
Before you start
- A Kubernetes cluster (1.27+) and Helm 3, with
kubectlpointed at it. - A reachable PostgreSQL 16+ with
pgvectorand a Redis 7+ / Valkey. - A registry token (or the offline image tarball for air-gapped clusters).
- Access to the Helm chart, published as a private OCI artifact at
oci://ghcr.io/nivorbit/charts/nivq— same credentials as the image.
1. Create the pull secret
The image is private, so the cluster needs credentials to pull it. Create a pull secret in the namespace you'll install into:
kubectl create secret docker-registry ghcr-pull \
--docker-server=ghcr.io \
--docker-username=<username> \
--docker-password=<token>No token yet? Ask the Nivorbit team or email [email protected]. You'll reference this secret from the values file with imagePullSecrets (step 3).
Air-gapped clusters
With no registry egress, skip the pull secret. Load the image tarball into your internal registry (or onto each node with docker/ctr load), then point image.repository at that internal location.
2. Write the values file
Your configuration goes in nivq-values.yaml. These are the keys you'll reach for most; each has a sensible default in the chart, so you only set what you need.
replicaCount: 2
image:
repository: ghcr.io/nivorbit/images/nivq
tag: "1.4.0" # pin a real release in production
imagePullSecrets:
- name: ghcr-pull
# --- Datastores (yours) ---
postgres:
url: jdbc:postgresql://my-postgres:5432/nivqdb
username: nivq
password: "a-strong-value" # → Kubernetes Secret
redis:
host: my-redis
port: 6379
# --- Security (required) ---
# 32-byte base64 key (openssl rand -base64 32). Losing it makes stored credentials
# unrecoverable, so back it up. The chart refuses to install if this is empty.
encryptionKeyV1: "base64-32-bytes-here"
# --- Platform-managed LLM ---
platformLlm:
provider: anthropic
model: claude-haiku-4-5-20251001
apiKey: "sk-..." # → Secret
# Optional self-learning embeddings — all three, or none (see Configuration).
embeddingProvider: ""
embeddingModel: ""
embeddingApiKey: ""
# --- Identity ---
oauth:
google:
clientId: "..."
clientSecret: "..." # → Secret
# --- Public URLs (browser-reachable) ---
urls:
backend: https://api.example.com
frontend: https://app.example.com
# --- Licensing ---
licensing:
# Optional: seed a licence so the pod boots VALID. Leave empty to activate after rollout.
seedLicense: ""
# --- Ingress (optional) ---
ingress:
enabled: true
className: nginx
host: api.example.com
tls:
- secretName: nivq-tls
hosts: [api.example.com]
# --- Web client (the browser UI) ---
# Deployed by default. Its API URL is taken from urls.backend; serve it at urls.frontend.
web:
enabled: true
ingress:
enabled: true
className: nginx
host: app.example.com # must match urls.frontend
tls:
- secretName: nivq-web-tls
hosts: [app.example.com]Keep secrets out of plain files
For real deployments, keep encryptionKeyV1, the database password, and API keys in a sealed/SOPS-encrypted values file or your secret manager — never commit them. The chart writes them into a Kubernetes Secret for you.
Anything not surfaced as a value can be passed through extraEnv (a list of {name, value}) using the same variable names as Configuration.
3. Install
Log in to the chart registry (same credentials as the image), then install straight from OCI, pinning the release version:
echo "<token>" | helm registry login ghcr.io -u <username> --password-stdin
helm install nivq oci://ghcr.io/nivorbit/charts/nivq --version 0.2.4 \
-n nivq --create-namespace -f nivq-values.yamlThis creates a Deployment, a Service (ClusterIP on port 8080), a ConfigMap and a Secret for configuration, and — if enabled — an Ingress. With web.enabled (the default) it also deploys the web client as its own Deployment, Service, and Ingress, configured from urls.backend at startup — no separate build. The application runs in production mode for you — there's nothing to configure.
Serve the web client at exactly urls.frontend: the API auto-registers its OIDC redirect URI as <urls.frontend>/auth/callback, so the web ingress.host must match. See Web client for the full picture.
Air-gapped clusters
With no registry access, Nivorbit provides the chart as a packaged nivq-0.2.4.tgz. Install from the local file instead: helm install nivq nivq-0.2.4.tgz -n nivq --create-namespace -f nivq-values.yaml.
4. Watch the rollout
kubectl -n nivq rollout status deploy/nivqHelm prints next-step notes after install, including the exact licensing commands for your release.
5. Activate the licence
If you seeded a licence (licensing.seedLicense), nivq boots VALID — you're done. Otherwise it boots activation-pending; activate it once:
kubectl -n nivq port-forward deploy/nivq 8080:8080
# in another shell
curl http://localhost:8080/v1/license/fingerprint # → NIVQ-FP-...
curl -F "[email protected]" http://localhost:8080/v1/license/uploadOr set licensing.seedLicense and run helm upgrade. See Licensing & activation for the full lifecycle.
6. Expose it
The Service is ClusterIP by default. The simplest way out is the chart's built-in ingress (shown above) — set ingress.enabled: true, your controller's className, the public host, and a tls secret. Terminate TLS at the ingress and make sure urls.backend / urls.frontend are the public HTTPS URLs, so OAuth redirects and links resolve correctly.
Scaling and upgrades
- Scale out with
replicaCount(orkubectl -n nivq scale deploy/nivq --replicas=N). Every replica resolves to the same host fingerprint by default, so scaling, rolling updates, and reschedules keep the licence valid with no extra wiring. - Upgrade to a new release with
helm upgrade nivq oci://ghcr.io/nivorbit/charts/nivq --version 0.2.4 -n nivq -f nivq-values.yaml. Config or secret changes automatically roll the pods.
For backups, TLS, and observability that apply to every install method, see Production hardening.