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. helm3.16+,kubectl,openssl, Docker (to runyarma-api pki init), and the license issuer's public keylicense.pub.
1. Prepare the dependencies
- PostgreSQL: create database
yarmaand useryarmathat owns it. Migrations create theyarma_approle used by row-level security, so the user needsCREATEROLEthe first time (or createyarma_app NOLOGINand grant it toyarmayourself). - 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-secretandstatic-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? .