Skip to content

Kubernetes

zach115th edited this page Aug 1, 2026 · 9 revisions

Kubernetes

IRIS-NG ships a Helm chart at deploy/kubernetes/charts.

Status: experimental. The chart is inherited from upstream DFIR-IRIS and has not been brought forward to the iris-ng stack. Read Before you start — there are two gaps you have to close yourself, and one of them fails silently. For evaluating IRIS-NG, Docker Compose on a single host is the supported path.

Try it on DigitalOcean

DigitalOcean Referral Badge

DigitalOcean Kubernetes (DOKS) is a straightforward place to run the chart, and the badge above is a referral link — it gives you free starting credit, and credits this project. Nothing in IRIS-NG depends on DigitalOcean; the chart is plain Helm and runs on any conformant cluster.

Images

Public images are on GHCR as of v2.5.0-beta.1+iris-ng.7, multi-arch (linux/amd64, linux/arm64), and pullable anonymously — no registry secret needed:

docker pull ghcr.io/zach115th/iriswebapp_app:v2.5.0-beta.1-iris-ng.7
docker pull ghcr.io/zach115th/iriswebapp_db:v2.5.0-beta.1-iris-ng.7
docker pull ghcr.io/zach115th/iriswebapp_nginx:v2.5.0-beta.1-iris-ng.7

The image tag is not the version string. + is not a valid character in a Docker tag, so the release tag v2.5.0-beta.1+iris-ng.7 is published as v2.5.0-beta.1-iris-ng.7 — a dash, not a plus. latest also tracks the most recent release.

The chart has no nginx deployment (the ingress controller terminates TLS instead), so a cluster install uses the app and db images. Building your own is still an option — docker build -f docker/webApp/Dockerfile -t <your-registry>/iriswebapp_app:local . — and on DOKS, doctl registry login plus doctl kubernetes cluster registry add <cluster> wires the pull secret in.

Before you start

Two things stand between the chart as committed and a working deployment. Until this release there was a third — no published images — which is now closed.

1. values.yaml ships placeholders, not defaults

The committed values contain literal placeholder strings that Helm will happily render into unusable manifests:

Key Committed value
postgres.image / .tag <postgres_image> / <tag>
irisapp.image / .tag <irisapp_image> / <tag>
irisworker.image / .tag <irisworker_image> / <tag>
irisapp.env.POSTGRES_SERVER postgres.<name_space>.svc.cluster.local
ingress.hosts[].host <host_name>

Copy it and fill every one before installing:

cp deploy/kubernetes/charts/values.yaml my-values.yaml
$EDITOR my-values.yaml

The image keys can now point at the published images rather than a registry of your own — note the dash form of the tag:

postgres:
  image: ghcr.io/zach115th/iriswebapp_db
  tag: v2.5.0-beta.1-iris-ng.7
irisapp:
  image: ghcr.io/zach115th/iriswebapp_app
  tag: v2.5.0-beta.1-iris-ng.7
irisworker:
  image: ghcr.io/zach115th/iriswebapp_app   # same image, different entrypoint
  tag: v2.5.0-beta.1-iris-ng.7

POSTGRES_SERVER and ingress.hosts[].host still have to be filled in by hand.

2. The chart has no ai_worker — this one fails silently

The chart deploys rabbitmq, postgres, iris_app, iris_worker and an ingress. It predates the split-out AI worker, and its appVersion is still 2.4.5.

IRIS-NG routes AI work to a dedicated ai_worker container consuming a separate ai_queue (single concurrency, because it is GPU-bound). Without that deployment the executive case summary and case chat enqueue jobs that are never consumed — the UI shows them queued forever rather than reporting an error. Every non-AI feature works.

Two options: leave the AI layer unconfigured (everything else is unaffected), or add an ai_worker Deployment mirroring iris_worker with the entrypoint target iris-ai-worker.

See AI Features → Async job queue.

Installing

# Ingress controller (once per cluster)
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress ingress-nginx/ingress-nginx -n iris --create-namespace

# IRIS-NG
helm install iris-ng ./deploy/kubernetes/charts -n iris -f my-values.yaml

Point DNS at the ingress load balancer once it has an external IP:

kubectl get svc -n iris ingress-ingress-nginx-controller

For TLS, install cert-manager and add a ClusterIssuer plus ingress.tls; the chart does not manage certificates. Nginx is not part of the chart — the ingress controller terminates TLS in its place.

Persistence and backups

Postgres is the only stateful component that matters. On DOKS, DigitalOcean Block Storage is the default StorageClass — confirm your PVC is bound and set an appropriate ReclaimPolicy before putting real case data on it:

kubectl get pvc -n iris

Case data, evidence and AI artifacts all live in Postgres, so back up that volume. scripts/import_vanilla_db.sh covers migrating an existing database in.

Sizing

Roughly what the stack wants for a small team:

Component Requests
iris_app 1 CPU / 2 GB
iris_worker 0.5 CPU / 1 GB
ai_worker (if added) 0.5 CPU / 1 GB
postgres 1 CPU / 2 GB + 20 GB volume
rabbitmq 0.25 CPU / 512 MB

Two 4 GB nodes is a reasonable starting point. The AI layer's real cost is wherever the model runs — if that is a local LM Studio or Ollama, size that host separately, and note it must be reachable from the cluster.

Simpler: Docker Compose on one host

For evaluation, a single 4 GB Droplet running the compose stack is faster to stand up and is the configuration this project actually tests:

git clone https://github.com/zach115th/iris-ng.git && cd iris-ng
bash scripts/generate_dev_certs.sh
bash scripts/iris_helper.sh --init
docker compose -f docker-compose.dev.yml up -d --build

Full walkthrough in Getting Started.

Helping fix the chart

Bringing the chart up to the current stack is a well-scoped contribution, and smaller now that images exist: add the ai_worker Deployment, replace the placeholders with the published images as defaults, and bump appVersion off 2.4.5. See Development Guide and CONTRIBUTING.md.

Clone this wiki locally