Skip to main content

Installation

The Avatar platform is packaged as a Helm chart, so it can be deployed into a Kubernetes cluster you already operate. All the architecture components — the API, the web client, the Dask scheduler and workers, the object store and the Authentik identity provider — are installed by that single chart.

Follow the steps below to deploy the Avatar platform into your cluster.

What the chart does and does not do

The chart deliberately does not create cluster infrastructure. It expects an ingress controller, a StorageClass, a PostgreSQL server and pull credentials to exist already, and it creates everything that runs on top of them — including the Avatar and Authentik databases. The prerequisites below list the split in full.

Cluster prerequisites​

Go through the requirements shared by both self-hosted paths, then check that everything in this list exists before you install.

  • Kubernetes cluster
    • An ingress-nginx controller, with a LoadBalancer (or NodePort, or MetalLB) in front of it
    • A default StorageClass — the object store runs as StatefulSets with PersistentVolumeClaims
    • A CNI that enforces NetworkPolicy (Calico, Cilium, …), if you want network isolation
    • kubectl and helm (v3) configured against the cluster
  • Network and TLS configuration
    • A domain name pointing at the load balancer. Every public URL the chart hands the API, the web client and Authentik is derived from this one name.
    • A kubernetes.io/tls Secret holding the certificate for that domain, in the release namespace. The chart never creates it.
    • If that certificate was issued by a private or internal Certificate Authority, the CA certificate itself — it has to be passed to the API as api.caBundle, or logins fail
    • An SMTP server reachable from the cluster, for password resets and invitations
    • Octopize has provided you with your quay.io credentials
  • Database
    • A PostgreSQL server reachable from the cluster
    • An administrative account on it. Both the Avatar database and Authentik's are created for you, using that account.
  • Network
    • The flows listed in the shared Requirements are open. The Helm chart artifact is pulled from quay.io as well.
What the chart creates for you
  • The Avatar database, its role, its tables and the first organization.
  • Authentik's role, its database and its extensions. Set authentikDatabase.createDatabase: false if a DBA has already created them.
  • The object store, when seaweedfs.enabled is true.
  • The Ingress objects and every public URL handed to the API, the web client and Authentik.

On the database side you supply a server and an admin account, and nothing else.

If you run an ingress controller other than ingress-nginx, set ingress.enabled: false and create your own Ingress objects. The URLs stay the same either way.

Container images​

The images and their sizes are listed in Requirements.

The avatar-service-api and avatar-web images are private, and so is avatar-connector if you enable the database connector. Octopize provides you with the quay.io credentials upon contract signature; the chart takes them as a base64-encoded Docker config.json in imageCredentials.dockerConfigJson, and creates the docker-local-pull-secret Secret from it:

base64 -w0 < ~/.docker/config.json

Prepare a values file​

The chart ships a complete, working example values file. Pull the chart and copy it:

helm pull oci://quay.io/octopize/helm/services-api/avatar --version <version> --untar
cp avatar/example-values.yaml my-values.yaml

Every PLACEHOLDER_ in that file has to be replaced, and each one carries the command that generates it.

The archive also contains a script that makes the credentials for you. Run it, and give the file that it writes to Helm after your own values file:

cd avatar && bash scripts/generate-secrets.sh

Use bash, and not ./. Helm packages each file with mode 0644, so the copy in the archive is not executable. Helm obeys the last --values file, so avatar-secrets.yaml replaces these keys in my-values.yaml. Keep the keys out of my-values.yaml, give the generated file to each upgrade, and keep it. See Generating the secrets.

The script does not make the values that belong to your own infrastructure. You still set these yourself. At a minimum, set:

ValueWhat it is
ingress.hostThe domain the platform is served on
ingress.tls.secretNameAn existing kubernetes.io/tls Secret for that domain
imageCredentials.dockerConfigJsonbase64 of a Docker config.json with quay.io/octopize credentials
api.image.tagThe API image tag
web.image.tagThe web client image tag
database.host / database.portYour PostgreSQL server
database.adminUsername / database.adminPasswordAdmin credentials, used once to create the databases
api.config.organizationNameYour organization's name
smtp.host and the other SMTP valuesYour SMTP server

See Configuration for the full values reference.

For a namespace enforcing the restricted Pod Security Standard, apply the example-values-restricted.yaml overlay on top of your own file with a second --values — see Restricted Pod Security Standard.

Two values have to agree with something else
  • dask.scheduler.image.tag and dask.worker.image.tag must equal api.image.tag.
  • storage.sseKek is generated once and never changed. When migrating an existing SeaweedFS, copy the value out of the old filer — see SeaweedFS encryption. Write it into avatar-secrets.yaml if you used the script, because Helm obeys that file last.

You set the four sso values one time. The API authenticates with clientId and clientSecret, and the bundled Authentik blueprint registers the same OAuth provider. apiToken and webhookSecret revoke the API keys of a user that you disable or delete in Authentik. Helm cannot write into the values of a subchart, so the AVATAR_AUTHENTIK_BLUEPRINT_* entries under authentik.global.env refer to the objects that the chart writes these four values into. Leave those entries as example-values.yaml has them. See SSO.

A certificate from a private CA needs api.caBundle

If your domain's certificate was issued by an internal or self-signed authority, every login fails with CERTIFICATE_VERIFY_FAILED until you set api.caBundle.

Install​

helm install avatar oci://quay.io/octopize/helm/services-api/avatar \
--version <version> \
--namespace avatar --create-namespace \
--values my-values.yaml

A missing required value fails the render with a message naming it, so an install that reports success has at least been given a complete configuration. The chart then prints the routing table for the deployment.

Watch it come up​

kubectl -n avatar get pods -w

The Authentik pods sit in Init:0/1 until their database answers. That is the wait-for-db init container doing its job, not a hang — read the bootstrap Job's logs to see where it is:

kubectl -n avatar get jobs
kubectl -n avatar logs job/avatar-authentik-db-init-<chart-version>

The Job is cleaned up after it finishes (authentikDatabase.ttlSecondsAfterFinished), so read its logs while it is still there.

Create the first Authentik admin​

Required, and not automated

An install where nobody has been through this flow has an identity provider nobody can administer.

Unlike the Docker installation, the chart does not set the AUTHENTIK_BOOTSTRAP_* variables — Octopize does not hold your identity provider's admin credential. Go through Authentik's own flow instead:

https://<ingress.host>/sso/if/flow/initial-setup/

Set the akadmin password there. That account then administers users, groups and the OAuth provider the Avatar API talks to — see User management.

Do it promptly: until you do, the flow is reachable by anyone who can reach the deployment. It stops working once the first admin exists.

Log in​

Browse to https://<ingress.host>/web. You are sent to Authentik to log in, and land back in the Avatar interface.

Next steps​

Once the stack is running, confirm everything is healthy by following the Verification & Troubleshooting guide.

To let your users copy and anonymize databases with database runs, enable the database connector. It is off by default.

Trying it out on a local cluster​

For an evaluation, the same values file installs on a single-node cluster — minikube, kind, k3s — with a handful of changes. There is nothing Avatar-specific about them; they are what a laptop cannot provide:

  • Enable an ingress controller and a default StorageClass. On minikube: minikube addons enable ingress default-storageclass storage-provisioner.
  • Point ingress.host at a name that resolves to the cluster — <cluster-ip>.nip.io works without touching DNS.
  • Set ingress.tls.enabled: false and leave ingress.tls.secretName empty. Every URL then uses http:// — fine for an evaluation, never for production.
  • Run a PostgreSQL in the cluster and point database.host at its Service.
  • Point the SMTP values at a local mail catcher. Mail has to work even locally, or user creation fails.
  • Shrink seaweedfs.volume.dataDirs[0].size and dask.worker.replicas, and match the -allowedOrigins arguments to your http:// host.
  • Clear the SeaweedFS pod anti-affinity (seaweedfs.master.affinity, .volume.affinity, .filer.affinity set to ""), which a single-node cluster cannot satisfy.

Everything else is unchanged from the example values file. The first-admin flow is still required.

Air-gapped deployments​

First go through the air-gapped checklist shared by both paths: mirrored images, the chart archive (helm pull … --untar, then install from the local directory), a local certificate and an internal SMTP server.

Then point the images at your mirror with global.imageRegistry:

global:
imageRegistry: registry.internal.example

It covers the API, the web client and SeaweedFS. Four more take their registry as part of a larger string and have to be pointed at the mirror by hand: dask.scheduler.image.repository, dask.worker.image.repository, authentik.global.image.repository and authentikDatabase.image.

Then turn off the two outbound calls the platform would otherwise make:

api:
config:
compatibilityMappingUrl: "disabled"
sentry:
enabled: false

For detailed information about mirroring the Authentik images, refer to the Authentik air-gapped documentation.