Skip to main content

Self-hosted installation

This guide installs AIP on your own Kubernetes cluster. It is separate from the trial SDK install, which only installs the Python client against Resaro's hosted trial platform — this guide installs the whole platform (API, web UI, database, object storage, and the analysis op runtime) into your infrastructure.

Resaro supplies AIP as one installer file. It downloads nothing at install time, so the same file installs on any cluster, with or without internet access.

Prerequisites​

Your cluster needs:

  • Kubernetes 1.35 — the version Resaro runs and tests AIP on.
  • Nodes matching the package architecture (amd64 or arm64).
  • A default StorageClass that can provision volumes.
  • An ingress controller AIP can attach to.
  • A method to issue HTTPS certificates, such as cert-manager.

You need:

  • A kubeconfig for the cluster, from an account that can install cluster-wide software. ./install.sh --dry-run names every action the account can't do.
  • A Linux or macOS workstation to run the commands.
  • A domain name for AIP, and the rights to create DNS records under it.

Unpack the installer​

The installer filename is aip-installer-<client-name>-<arch>-<version>.tar.gz — it holds your organization name, your cluster's architecture, and the version:

tar xzf aip-installer-*.tar.gz
cd aip-installer-*/

Run every command in this guide from that unpacked directory — it holds install.sh, zarf-config.yaml, and bin/, and every path in this guide is relative to it.

Set ZARF for your workstation (the computer running these commands — not your cluster). bin/ holds one Zarf program per workstation type, named zarf-<os>-<arch>; list them with ls bin/. Zarf sends the images across the network and your cluster runs them, so a macOS workstation program installs correctly to a Linux cluster:

# macOS on Apple silicon
export ZARF=./bin/zarf-darwin-arm64

# Linux on x86
export ZARF=./bin/zarf-linux-amd64

Set the namespace variables. AIP installs into three namespaces:

export AIP_NS=aip-v2 # API, web interface, PostgreSQL, and MinIO
export NUCLIO_NS=nuclio # function controller and op pods
export OBS_NS=monitoring # monitoring dashboards, only if installed

The Secret names aip-v2-ui-tls, aip-v2-api-tls, and aip-v2-minio-tls start with the same letters as $AIP_NS — they are Secret names, not namespaces.

Point your kubeconfig at the target cluster. Every command in this guide uses the current context:

$ZARF tools kubectl config current-context

Set four values in zarf-config.yaml (everything else has a working default):

  • BASE_DOMAIN — your domain for AIP, e.g. aip.example.org. The web interface uses this name; other services add a prefix (api., minio., grafana.). Lowercase letters, numbers, hyphens, and dots only — an underscore breaks ingress. Selecting the final domain now matters: a later change needs a new ingress install.
  • INIT_ADMIN_PASSWORD — the password for the admin login.
  • INGRESS_CLASS — your cluster's ingress class ($ZARF tools kubectl get ingressclass to find it).
  • CLUSTER_ISSUER — the certificate issuer, depending on which of the four certificate methods below Resaro built your package for.

Some analysis ops call an external model endpoint and need OPENAI_API_KEY, JUDGE_API_KEY, or HF_TOKEN in this file — Resaro tells you which keys your package needs.

Choose the certificate method​

Resaro builds your package for one of four methods; Resaro tells you which.

Your own cert-manager issuer — set CLUSTER_ISSUER to that issuer's name. Prepare nothing. Do not use --install-infra.

You supply the certificates — set CLUSTER_ISSUER to "". Before install, create three TLS Secrets in $AIP_NS: aip-v2-ui-tls (for <base-domain>), aip-v2-api-tls (for api.<base-domain>), and aip-v2-minio-tls (for minio.<base-domain>) — one certificate naming all three hosts (or <base-domain> + *.<base-domain>) can fill all three:

$ZARF tools kubectl create namespace $AIP_NS
for name in aip-v2-ui-tls aip-v2-api-tls aip-v2-minio-tls; do
$ZARF tools kubectl -n $AIP_NS \
create secret tls "$name" --cert=<path-to-your-cert> --key=<path-to-your-key>
done

If you also install the monitoring dashboards, Grafana needs a fourth Secret, obs-grafana-tls in $OBS_NS, covering grafana.<base-domain>.

You supply the certificate authority — keep CLUSTER_ISSUER: aip-ca, add --install-infra (the aip-ca issuer comes from the package). Create one Secret; AIP issues the three certificates itself, signed by your authority:

$ZARF tools kubectl create namespace cert-manager
$ZARF tools kubectl -n cert-manager create secret tls aip-ca \
--cert=<path-to-your-ca-cert> --key=<path-to-your-ca-key>

AIP creates its own authority — keep CLUSTER_ISSUER: aip-ca, add --install-infra, prepare nothing. After install, distribute the authority's certificate to your users (see Trust the certificate below).

What AIP installs​

install.sh reads zarf-config.yaml, checks what the cluster already has, and — only with --install-infra — supplies what's absent:

AIP looks forNamed byWith --install-infra, if absent
the IngressClassINGRESS_CLASSinstalls Traefik, only if INGRESS_CLASS is traefik
cert-manager—installs cert-manager
the ClusterIssuerCLUSTER_ISSUERcreates the aip-ca authority, only if CLUSTER_ISSUER is aip-ca

Without --install-infra, an absent item stops the install and names the remedy. If your cluster has no ingress controller and no cert-manager, keep the defaults traefik / aip-ca and add --install-infra.

Set INGRESS_CLASS to the class of your own controller if you have one — --install-infra doesn't change this. Keep traefik only if your cluster has no ingress controller at all; a second controller gets its own load balancer that your DNS records won't point at, and the installer stops if it finds that combination.

Install​

Two flags to decide before you start:

  • --install-infra — required if CLUSTER_ISSUER is aip-ca, or if your cluster has no ingress controller or cert-manager.
  • --components observability — installs the monitoring dashboards (Grafana, Loki, Tempo, Mimir) in the same run, showing service health, the logs/traces of a failed analysis run, and cluster load. Resaro strongly recommends these for every deployment; they use AIP's existing object storage, so nothing extra needs configuring.

Dry run first (changes nothing, checks the same options you'll actually pass):

./install.sh --dry-run # add --install-infra, --components observability, or both

It reports the target cluster, your account's access, the ingress class, the certificate issuer, the default StorageClass, and the components to deploy. The deploying line names everything AIP adds to the cluster — on a cluster that already has an ingress controller and cert-manager, it reads AIP only — no cluster infrastructure will be installed.

Then install, with the same options:

./install.sh # add --install-infra, --components observability, or both

A second run is safe — it continues an interrupted install, upgrades the platform in place (pods may restart), never resets a password, and never deletes data. Run it again with --components observability to add the dashboards later. Protect zarf-config.yaml: it holds the admin password and later runs need the file again.

Complete the setup​

Create the DNS records​

Find your ingress address:

$ZARF tools kubectl get svc -A --field-selector spec.type=LoadBalancer

Point these names at that address — they must resolve from your users' browsers, not only inside the cluster:

aip.example.org → <that address> the web interface
api.aip.example.org → <that address> the API, used by the Python SDK
minio.aip.example.org → <that address> object storage
grafana.aip.example.org → <that address> dashboards, only with --components observability

Do not omit the minio.aip.example.org record — dataset previews and downloads fail without it, since AIP signs its links against that exact name and a browser cannot change them. Publish grafana.<base-domain> only to the networks your operators use — Grafana has one shared admin login and no single sign-on yet, and it can read the AIP database.

Trust the certificate​

Applies only if you kept CLUSTER_ISSUER: aip-ca. If you supplied your own authority, open https://<your base domain> first — if the browser shows no warning, your machines already trust it. Otherwise, distribute the authority's certificate:

$ZARF tools kubectl -n cert-manager get secret aip-ca \
-o jsonpath='{.data.tls\.crt}' | base64 -d > aip-ca.crt

Send aip-ca.crt to your users' trust stores using the same method you use for other internal certificates.

Sign in​

Open https://<your base domain> — username admin, password the INIT_ADMIN_PASSWORD you set. If you deployed the monitoring dashboards, open https://grafana.<your base domain> and sign in as admin with the password AIP generated on your cluster (not the AIP password):

$ZARF tools kubectl -n $OBS_NS get secret grafana-admin-secret \
-o jsonpath='{.data.admin-password}' | base64 -d

Troubleshooting​

SymptomCause / fix
bundle signature verification FAILEDThe transfer damaged the file, or it was altered. Do not install it — ask Resaro for a new copy.
Auth error part-way through installA cluster credential expired mid-run. Re-authenticate, then run ./install.sh again — it continues from where it stopped.
A pod stays PendingKubernetes cannot schedule the pod — check node resources and taints.
Browser shows a certificate warningWith aip-ca, that machine doesn't have aip-ca.crt yet (see Trust the certificate). With your own issuer, run $ZARF tools kubectl -n $AIP_NS get certificate to check readiness.
Web interface opens but a dataset won't preview/downloadThe minio.<domain> DNS record is missing — see Create the DNS records.

To see the state of all components:

$ZARF tools kubectl get pods -n $AIP_NS
$ZARF tools kubectl get pods -n $NUCLIO_NS

Reference​

Where the components run

NamespaceContents
$AIP_NSAPI, web interface, PostgreSQL, object storage
$NUCLIO_NSFunction controller and the analysis ops
zarfIn-cluster image registry
traefikIngress. Present only if you used --install-infra
cert-managerCertificate issuance. Present only if you used --install-infra
$OBS_NSGrafana, Loki, Tempo, Mimir. Present only if you used --components observability

Installer options (run ./install.sh --help to see them all)

OptionEffect
--dry-runExamine the cluster and show the plan. Changes nothing
--components <list>Also install optional components, such as observability
--install-infraPermit AIP to install what the cluster lacks: ingress controller, cert-manager, the aip-ca authority. Off by default
--airgapVerify the cluster has no internet access. Fails if egress works
--skip-initOmit cluster initialization. The installer already omits it when the cluster holds a zarf namespace
--skip-smokeOmit the post-install check