Skip to content
Documentation menu · version 0.1.0-alpha.4

Kubernetes installation (Helm)

Availability: the container images for this method are published with the 1.0 release. Until then, install on Ubuntu with the native bundle (no Docker needed).

The Helm chart runs the API (2–10 replicas in cluster mode), the console and optionally the License Center. Stateful dependencies are yours to provide, ideally as managed services. Chart reference: deployments/helm/yarma; availability design: high availability.

Prerequisites

  • Kubernetes 1.28+, an ingress controller (the defaults assume ingress-nginx), and cert-manager or another way to issue certificates.
  • A LoadBalancer (or NodePort) Service is possible for the agent port: agents use mutual TLS, so TCP 18443 must reach the API pods without TLS termination.
  • PostgreSQL 17 with TLS, Redis 7, NATS 2.10 with JetStream, S3-compatible storage (AWS S3, MinIO, SeaweedFS, Ceph RGW, …), ClamAV clamd, and a TURN server (coturn) using a static auth secret.
  • helm 3.16+, kubectl, openssl, Docker (to run yarma-api pki init), and the license issuer's public key license.pub.

1. Prepare the dependencies

  • PostgreSQL: create database yarma and user yarma that owns it. Migrations create the yarma_app role used by row-level security, so the user needs CREATEROLE the first time (or create yarma_app NOLOGIN and grant it to yarma yourself).
  • S3: create an access key with read/write on a bucket named yarma (created automatically when missing and the key may create buckets).
  • TURN: e.g. coturn with use-auth-secret and static-auth-secret=<TURN secret>, reachable from browsers and devices on UDP/TCP 3478 and its relay range.

2. Create the secrets

kubectl create namespace yarma
V=1.0.0
# Agent PKI (agent CA + agent-service certificate for the name agents connect to)
mkdir pki && docker run --rm --user "$(id -u)" -v "$PWD/pki:/out" \
  ghcr.io/javadmohebbi/yarma-api:$V pki init -dir /out -hosts agents.example.com
kubectl -n yarma create secret generic yarma-agent-pki --from-file=pki/

# Access-token signing key and license public key
openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -out signing.key
kubectl -n yarma create secret generic yarma-signing-key --from-file=signing.key
kubectl -n yarma create secret generic yarma-license-pub --from-file=license.pub

# Credentials and keys read as environment variables
kubectl -n yarma create secret generic yarma-env \
  --from-literal=YARMA_DATABASE_PASSWORD='…' \
  --from-literal=YARMA_REDIS_PASSWORD='…' \
  --from-literal=YARMA_AUTH_COOKIE_KEY="$(openssl rand -base64 32)" \
  --from-literal=YARMA_FILES_MASTER_KEY="$(openssl rand -base64 32)" \
  --from-literal=YARMA_TURN_SECRET='<same as coturn static-auth-secret>' \
  --from-literal=YARMA_FILES_S3_ACCESS_KEY='…' \
  --from-literal=YARMA_FILES_S3_SECRET_KEY='…'

Also create yarma-api-tls, a certificate for yarma-api.yarma.svc (the console proxies to it; with a release name that does not contain yarma it is <release>-yarma-api), and yarma-tls, the public certificate for the console host. cert-manager Certificate resources work for both. If the images are private, create a docker-registry secret and set image.pullSecrets.

Keep a copy of pki/, signing.key and the two random keys in your secrets manager: YARMA_FILES_MASTER_KEY decrypts stored files and recordings, and the agent CA is the trust anchor of every enrolled device. Then delete the local copies.

3. Install

values-prod.yaml:

host: yarma.example.com
config:
  database: { host: postgres.example.internal, ssl_mode: verify-full }
  redis: { addr: "redis.example.internal:6379" }
  nats: { url: "nats://nats.example.internal:4222" }
  turn:
    urls: ["turn:turn.example.com:3478?transport=udp", "turn:turn.example.com:3478?transport=tcp"]
  files:
    s3_endpoint: s3.example.internal
    s3_use_tls: true
    clamd_addr: "clamav.example.internal:3310"
  server:
    trusted_proxies: ["10.0.0.0/8"]    # pod / ingress CIDRs
agents:
  service:
    annotations: {}                     # e.g. internal or external load balancer
api:
  tlsCASecret: yarma-api-ca             # optional: console verifies the API certificate
helm install yarma yarma-$V.tgz -n yarma -f values-prod.yaml
kubectl -n yarma rollout status deploy/yarma-api

Point the console DNS name at the ingress and the agents name at the address of the yarma-agents LoadBalancer Service. Migrations run as a pre-install/pre-upgrade hook. If PostgreSQL needs a CA bundle for verify-full, mount it and set PGSSLROOTCERT through api.extraEnv.

4. First organization

kubectl -n yarma exec deploy/yarma-api -- env YARMA_BOOTSTRAP_ADMIN_PASSWORD='<password>' \
  /yarma-api -config-dir /etc/yarma bootstrap -tenant acme -name "Acme Corp" -admin-email [email protected]

Continue with first-time setup.

Upgrade

helm upgrade yarma yarma-NEW.tgz -n yarma -f values-prod.yaml

Back up the database first. The migration hook runs before new pods start; API pods roll one at a time behind their PodDisruptionBudget, and agents reconnect to the remaining replicas. Roll back with helm rollback yarma plus a database restore if a migration changed the schema.

Backup

Follow backup and DR: scripts/backup.sh as a CronJob or your database service's point-in-time recovery, object-store versioning or replication, and the secrets above in your secrets manager.

Uninstall

helm uninstall yarma -n yarma
kubectl delete namespace yarma      # removes the secrets too

The chart keeps no data in the cluster; drop the PostgreSQL database and the S3 bucket separately when you no longer need them.

Documentation for Yarma 0.1.0-alpha.4. Something unclear? .