nivq
This install section is for Enterprise / on-prem customers who self-host nivq.

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 kubectl pointed at it.
  • A reachable PostgreSQL 16+ with pgvector and 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:

Shell
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.

YAML
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:

Shell
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.yaml

This 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

Shell
kubectl -n nivq rollout status deploy/nivq

Helm 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:

Shell
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/upload

Or 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 (or kubectl -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.