Skip to main content

System Requirements

OpenBox is Kubernetes-only

OpenBox targets Kubernetes as the sole runtime platform. Every service is designed for horizontal scale via HPA — running the platform on bare processes or Docker Compose is not supported. All requirements below assume a K8s cluster ≥ 1.27.

1. Operating Systems

Kubernetes node OS

The chart works on any OS supported by your K8s distribution. Recommended (tested in prod reference):

OSVersionNotes
Amazon Linux 2023AL2023 (kernel 6.1+)EKS Auto Mode default; recommended for AWS
Ubuntu Server22.04 LTS / 24.04 LTSBroad tooling support; common for self-managed K8s
RHEL / Rocky Linux / AlmaLinux8.8+ / 9.xEnterprise-friendly; SELinux compatible
Bottlerocket1.20+Minimal container-OS for EKS; hardened defaults
SUSE Linux Enterprise15 SP5+Rare but supported

Not supported:

  • Windows nodes — OpenBox has no Windows container images
  • macOS as K8s node OS (not a Kubernetes-supported OS in general)
  • Alpine as node OS (some ML models need glibc — Alpine musl breaks PyTorch etc.)

Container runtime

  • containerd ≥ 1.6 (default in modern K8s ≥ 1.24) — required
  • Docker Engine as runtime is NOT supported (removed from K8s 1.24+)
  • CRI-O ≥ 1.27 works but is not the reference target

Client / workstation OS

For running kubectl, helm, terraform, aws CLI on your admin workstation:

OSSupportNotes
macOS12 Monterey+ (13+ recommended)Universal via Homebrew
LinuxUbuntu 22.04+ / Fedora 38+ / RHEL 8+ / other modern distrosNative tooling
WindowsWindows 11 with WSL2 (Ubuntu recommended)Native Windows shell not tested

2. Software Requirements

Kubernetes baseline

ComponentMin versionNotes
Kubernetes API server1.27Chart annotation kubeVersion: ">=1.27.0-0"
kubelet1.27+Matches API server
CNI pluginanyMust support NetworkPolicy (AWS VPC CNI / Calico / Cilium)
CoreDNSv1.10+Default; other DNS providers untested
metrics-serverv0.6+Required for HPA

Required cluster add-ons

Add-onVersionRequired?Purpose
metrics-server0.6+RequiredHPA scaling
Ingress controlleranyRequiredPublic HTTPS routing (Istio / NGINX / ALB / Traefik)
Default StorageClassany RWORequiredPostgres + Redis + Elasticsearch PVCs

Optional cluster add-ons

Add-onVersionWhen required
cert-manager1.13+Automated TLS certs from Let's Encrypt / ACM
External Secrets Operator0.9+Sync secrets from AWS SM / Vault / GCP SM
Argo Rollouts1.6+Canary deploy strategy (else chart falls back to Deployment)
Istio1.20+mTLS mesh + advanced traffic management (chart default)
NVIDIA Device Plugin0.14+Only if using GPU workloads (LlamaFirewall vllm)

Runtime languages per service

Each service ships as a pre-built container image — you do not install language runtimes on nodes. This table documents what's inside each image for capacity planning + vulnerability tracking:

ServiceRuntimeVersion
openbox-backendNode.js20 LTS
openbox-core (all 5 containers)Python + Temporal SDKPython 3.11 / Temporal SDK 1.24
openbox-core-codecPython3.11
openbox-feNode.js22 LTS (Next.js SSR)
identity-service (Keycloak)OpenJDK21 LTS
opa-appGo (statically linked)OPA v0.65+
guardrails-apiPython3.11
model-host-detect-pii / -nsfw / -toxicityPython + PyTorch3.11 / PyTorch 2.4
llamafirewall-serverPython3.11
vllmPython + CUDA3.11 / CUDA 12.4
postgresql (Bitnami)C (Postgres)PostgreSQL 16+
openbox-core-redisC (Redis)Redis 7+
temporal-server (self-hosted variant)GoTemporal v1.24
elasticsearch (self-hosted Temporal only)OpenJDKES 7.17.3 / JDK bundled

Pin image tags in prod (image.tag: 0.1.0) — never :latest.

Client-side tooling

Install on your admin workstation:

ToolMin versionPurpose
kubectl1.27+K8s CLI (match server version ± 1 minor)
helm3.12+Chart install/upgrade
jq1.6+JSON parsing (for output extraction)
yq4.30+YAML parsing
aws CLI2.xAWS scenarios (S1, S2 Turnkey/Fresh AWS)
terraform1.5+S2 Terraform IaC path
docker24+S8 Local PoC (Minikube/kind driver)
minikube or kindlatestS8 Local PoC
eksctllatestOptional — EKS provisioning (alternative to Terraform/CFN)
cfn-lintlatestOptional — validate S2 CloudFormation template

3. Hardware Requirements

Assumption: Kubernetes cluster with HPA + Cluster Autoscaler (or Karpenter). Per-service resource limits are per pod; total cluster capacity is (pod resource × HPA maxReplicas) + node overhead.

Per-pod resource matrix

Requests are the HPA scheduling floor; limits are the burst ceiling. All values from charts/openbox/values.yaml.

ServiceReq CPUReq RAMLim CPULim RAMReplicas (min → max)GPU?
openbox-backend500m1 Gi1500m2 Gi1 → 8 (HPA @ 70% CPU)
openbox-core (pod = 5 containers)1 vCPU2.5 Gi5 vCPU10 Gi1 → 5
↳ each container200m500 Mi1 vCPU2 Gi(× pod)
openbox-core-codec200m500 Mi1 vCPU2 Gi1
openbox-core-redis200m521 Mi500m1 Gi1 (StatefulSet)
openbox-fe200m512 Mi500m1 Gi2 → 6
identity-service (Keycloak)200m1700 Mi500m2 Gi3 → 5
opa-app200m1.5 Gi1 vCPU3 Gi1 → 5
guardrails-api500m1 Gi1 vCPU2 Gi2 → 10
model-host-detect-pii1 vCPU3.5 Gi2 vCPU4 Gi1 → 10
model-host-nsfw1 vCPU3.5 Gi2 vCPU4 Gi1 → 10
model-host-toxicity1 vCPU3.5 Gi2 vCPU4 Gi1 → 10
llamafirewall-server200m512 Mi500m1 Gi1 → 3
vllm (Qwen3-8B)2 vCPU6 Gi3 vCPU14 Gi11 × A10G 24 GB
Temporal server (self-hosted) — 4 pods~200m each~512 Mi each~1 vCPU each~1 Gi each4 (fixed)
Elasticsearch (self-hosted Temporal) — 3 pods250m each1 Gi each500m each1 Gi each3 (fixed)

Cluster sizing — min → max scale

Deployment sizeConcurrent agentsNodes (approx)Total vCPUTotal RAMGPUReference workload
PoC / Dev< 101 (Minikube/kind)48 GBLaptop
Small prod< 1008 mixed~24 vCPU~128 GB1 × A10G1× r7i.xl + 1× m7i.xl + 2× c7i.xl + 1× g5.xl + 3× m7a.xl (AWS)
Medium prod~50020 mixed~68 vCPU~250 GB1 × A10GFull HPA scale-out
Enterprise> 100040+ mixed~150 vCPU~500 GB2-4 × A10G/L4Multi-AZ + multi-GPU
On-prem small< 1008 bare-metal~48 phys cores~256 GB1 × T4/A10G2-socket / node × 24 cores + storage nodes + GPU node

How to size for your workload:

  1. Start with Small prod baseline
  2. Measure p95 CPU + RAM per service under expected load
  3. Set HPA maxReplicas = (peak load ÷ per-pod capacity) × 1.5 safety factor
  4. Configure Cluster Autoscaler / Karpenter to add nodes when HPA can't schedule

Prod reference uses 5 taints to isolate workload classes — HPA behaves better when noisy neighbors are excluded:

TaintInstance class (AWS example)Hosts
workload-line=cpu:NoSchedulec/r/t gen 6+Backend, core, fe, opa, keycloak, redis, codec
workload-line=memory:NoSchedulem/r/t/x gen 6+Temporal server + web + admintools + Elasticsearch
workload-line=database:NoSchedulem7a.xlarge3× PostgreSQL clusters
workload-line=llm:NoScheduleg5.xlarge (1 × A10G GPU)vllm Qwen3-8B
workload-line=guardrails:NoSchedulec7i.xlargeguardrails-api + 3× model-hosts

Not required — you can run everything on a single general-purpose node pool. Isolation matters at Medium+ scale.

GPU requirements (only if guardrails-api.llamafirewall.enabled: true)

GPUVRAMCloud instanceNotes
NVIDIA A10G (default)24 GBAWS g5.xlargeReference — Qwen3-8B fits with headroom
NVIDIA L424 GBGCP g2-standard-8Same VRAM, similar throughput
NVIDIA T416 GBAWS g4dn.xlarge / Azure NCasT4_v3Tight — may OOM on long contexts. Reduce max_model_len
NVIDIA A100 40/80 GB40/80 GBAWS p4d / Azure ND A100 v4Overkill; use for larger custom models

Requires NVIDIA Device Plugin installed on cluster (kubectl get pods -n kube-system | grep nvidia-device-plugin).

Zero-GPU mode: guardrails-api.llamafirewall.enabled: false — PII/NSFW/toxicity CPU classifiers still work; deep prompt-injection detection unavailable.

Storage

Volume sizing per PVC. All must be ReadWriteOnce.

PVCMinRecommended prodMax (long-lived)BackendNotes
App Postgres20 GB100 GB500 GB+gp3 / equivalentEnable PITR
Identity Postgres5 GB20 GB50 GBgp3Keycloak realms/users
Temporal Postgres (self-hosted only)10 GB100 GB500 GBgp3Grows with workflow history
Elasticsearch (× 3 pods, self-hosted Temporal only)30 GB each50 GB each100 GB eachgp3Configurable retention
Redis (openbox-core-redis)5 GB5 GB10 GBgp3Cache — low durability priority
OPA policy bundles< 1 GB1 GB5 GBS3 (object)Not a PVC — S3 bucket
Container image cache (per node)20 GB30 GB40 GBNode root diskPrune old tags via ImagePolicy

IOPS: gp3 default (3000 IOPS / 125 MB/s) is fine up to Medium prod. Enterprise → provision gp3 IOPS to 6000+ for Postgres.

Network

RequirementValue
IngressHTTPS 443 (external)
Inter-servicegRPC 7233 (Temporal), REST 8xxx, JDBC 5432, Redis 6379
Bandwidth (steady)~50-200 Mbps mixed
Bandwidth (peak)~500 Mbps+ under bursts
Latency SLO (internal p99)< 20 ms service-to-service
EgressImage pulls + KMS API + S3 GET + customer's telemetry
Multi-AZRecommended for Medium prod+ (spread nodes ≥ 2 AZ)

4. Database

OpenBox uses PostgreSQL for transactional data + Redis for session cache + (optionally) Elasticsearch for Temporal visibility. Postgres is the critical dependency.

4.1 PostgreSQL

Version: 16.x (chart default) or newer. 15.x is EOL — do not use. 17.x tested and supported.

Three separate DB clusters recommended in prod:

DB nameOwnerPurposeSize growth
openboxopenbox-backend + openbox-coreApp transactional data, agent state, audit logsLinear with agent activity
keycloakidentity-serviceRealms, users, tokens, sessionsSlow — bounded by user count
temporalTemporal server (self-hosted variant only)Workflow history + task queuesGrows with workflow retention (configurable)

You can consolidate to 1 Postgres instance with 3 databases for smaller deploys — cheaper, tighter blast radius per shared instance.

Sizing:

ScaleInstance class (AWS RDS/Aurora)StorageIOPS
PoCdb.t4g.micro (in-cluster Bitnami OK)20 GB gp3Default (3000)
Small proddb.r6i.large (2 vCPU / 16 GB)100 GB gp3Default (3000)
Medium proddb.r6i.xlarge (4 vCPU / 32 GB)250 GB gp36000 provisioned
Enterprisedb.r6i.2xlarge (8 vCPU / 64 GB) + read replica500 GB+12000+ provisioned

Recommended settings:

max_connections = 200        # tune to (pod count × 20 avg connections per pod)
shared_buffers = 25% RAM # standard PG guidance
effective_cache_size = 75% RAM
work_mem = 16 MB # per-query sort/hash
maintenance_work_mem = 512 MB # for VACUUM, CREATE INDEX

Extensions required:

  • pgcrypto — used by openbox-backend for field-level encryption
  • uuid-ossp — UUID generation

Managed alternatives (recommended over in-cluster Bitnami for prod):

CloudServiceNotes
AWSAmazon Aurora PostgreSQL OR RDS PostgreSQLAurora Global DB enables T3+ DR tier
AzureAzure Database for PostgreSQL Flexible Server
GCPCloud SQL for PostgreSQL
On-premCloudNativePG operatorK8s-native Postgres, HA + PITR

Config lives under openbox-backend.db.*, identity-service.db.*, and (self-hosted Temporal) openbox-core.temporal.server.db.* values.

See Customization → External database endpoint for the full wiring.

Backup / DR:

  • Backup retention ≥ 7 days (chart default for the in-cluster Bitnami is 0 — override in prod)
  • Enable point-in-time recovery (PITR) — RDS default is 7 days
  • Test restore quarterly

4.2 Redis

Version: 7.x (chart default redis:7-alpine). 6.x is legacy; 8.x untested.

Purpose: session cache for openbox-core-server. Data is ephemeral by design — session loss on restart is acceptable.

Sizing:

ScaleInstanceStoragePersistence
PoC1 pod (in-cluster)5 GB gp3AOF disabled
Small prodcache.t4g.small (ElastiCache) OR 1 pod5 GBAOF disabled
Medium prodcache.t4g.medium OR ReplicaCount=210 GBAOF fsync-per-sec
EnterpriseElastiCache cluster mode + replica20 GB+AOF + snapshotting

Managed alternatives:

CloudService
AWSElastiCache for Redis (cluster mode enabled for HA)
AzureAzure Cache for Redis
GCPMemorystore for Redis
On-premBitnami Redis chart (chart default)

Config lives under openbox-core.redis.external.host / .port values. See Customization → External database endpoint.

Not required:

  • Redis Cluster mode (unless you're at Enterprise scale)
  • Redis persistence in most tiers (session data is regenerable from Postgres + Keycloak)

4.3 Elasticsearch (self-hosted Temporal variant only)

If openbox-core.temporal.mode: self-hosted, the Temporal server needs Elasticsearch 7.17.3 for visibility store.

Version: ES 7.17.x (fixed by Temporal upstream — do NOT upgrade to ES 8.x, not yet supported)

Sizing:

  • 3 pods (fixed by Bitnami chart, HA quorum)
  • 250m CPU / 1 Gi RAM per pod (requests) — bump to 500m / 2 Gi for Medium+
  • 30 GB gp3 per pod → 90 GB total baseline; grows with workflow visibility retention

Not required if temporal.mode: cloud — Temporal Cloud handles visibility internally.

Retention tuning: Temporal namespace retention config drives ES growth. Default 30 days = ~30 GB per 1M workflow completions. Tune per compliance needs.


Quick reference by scenario

ScenarioClusterStorageGPUCompute (approx)
S1 TurnkeyOpenbox provisions300 GB total1 × A10GSmall-Medium prod baseline
S2 Fresh AWSCustomer provisions via Terraform/CFN250-500 GB1 × A10GSmall prod baseline (~24 vCPU)
S3 BYOCReuse existing K8sDepends on clusterOptionalFits into existing capacity
S8 Local PoCMinikube/kind30 GB laptop4 vCPU / 8 GB laptop

For per-scenario cost estimates see the brainstorm report §8.


Verification checklist

Before helm install, verify on your cluster:

# K8s version
kubectl version --output=json | jq -r '.serverVersion.gitVersion'
# Expect: v1.27.x or newer

# Nodes ready
kubectl get nodes --no-headers | grep -c ' Ready '
# Expect: ≥ 3 for prod, ≥ 1 for PoC

# metrics-server
kubectl get deployment metrics-server -n kube-system
# Expect: 1/1 Ready

# StorageClass
kubectl get storageclass | grep '(default)'
# Expect: 1 line with (default) annotation

# IngressClass
kubectl get ingressclass
# Expect: 1+ classes

# GPU (if using LlamaFirewall)
kubectl get nodes -o custom-columns=NAME:.metadata.name,GPU:.status.capacity.'nvidia\.com/gpu'
# Expect: at least 1 node with a GPU count > 0

Full checklist in S3 Prerequisites checklist.