Skip to main content

Kubernetes & Helm

Chronos provides a Helm chart for production Kubernetes deployments with Deployment, Service, Secret (or ExternalSecret via the External Secrets Operator), Ingress, HPA, PodDisruptionBudget, ServiceMonitor, and ServiceAccount templates. Pods run hardened by default — non-root user, read-only root filesystem, dropped Linux capabilities, and soft pod anti-affinity across nodes (configurable via podSecurityContext, securityContext, podAntiAffinity, and topologySpreadConstraints in values.yaml).

Quick Deploy​

helm install chronos deploy/helm/chronos/ \
--set image.tag=latest \
--set secrets.storageDSN="postgres://user:pass@db:5432/chronos"

Chart Structure​

deploy/helm/chronos/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
├── secret.yaml
├── externalsecret.yaml
├── ingress.yaml
├── hpa.yaml
├── pdb.yaml
├── servicemonitor.yaml
└── serviceaccount.yaml

Configuration​

values.yaml​

The chart exposes these values:

# Image
image:
repository: ghcr.io/spawn08/chronos
tag: "0.1.0"
pullPolicy: IfNotPresent

# Replicas (overridden by HPA when enabled)
replicaCount: 2

# Storage backend selector, exported as CHRONOS_STORAGE_BACKEND
storage:
backend: postgres

# Service
service:
type: ClusterIP
port: 8420

# Secrets (stored as Kubernetes Secret; create=false + externalSecret.enabled=true
# for production instead of the plaintext dev-only values below)
secrets:
create: true
name: chronos-secrets
storageDSN: "postgres://chronos:changeme@postgres:5432/chronos?sslmode=disable"
apiKey: ""
embeddingsKey: ""

# Ingress
ingress:
enabled: false
className: ""
hosts:
- host: chronos.local
paths:
- path: /
pathType: Prefix
tls: []

# Autoscaling
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilization: 70
targetMemoryUtilization: 80

# Resources
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi

# Service Account
serviceAccount:
create: true
name: "chronos-os"
annotations: {}

Secrets​

API keys and database credentials are stored as Kubernetes Secrets:

helm install chronos deploy/helm/chronos/ \
--set secrets.storageDSN="postgres://user:pass@db:5432/chronos" \
--set secrets.apiKey="sk-..." \
--set secrets.embeddingsKey="sk-..."

Only storageDSN is automatically wired into the Deployment's environment; apiKey and embeddingsKey are stored in the Secret for you to reference (e.g. via extraEnv in values.yaml) but are not consumed by chronos serve itself:

Secret KeyEnvironment Variable
storageDSNCHRONOS_STORAGE_DSN (via secretKeyRef on key storage-dsn)
apiKeynot auto-wired — reference key api-key from extraEnv if needed
embeddingsKeynot auto-wired — reference key embeddings-key from extraEnv if needed

Ingress​

Enable external access with an Ingress controller:

helm install chronos deploy/helm/chronos/ \
--set ingress.enabled=true \
--set ingress.hosts[0].host=chronos.example.com \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=Prefix

With TLS:

helm install chronos deploy/helm/chronos/ \
--set ingress.enabled=true \
--set ingress.hosts[0].host=chronos.example.com \
--set ingress.tls[0].secretName=chronos-tls \
--set ingress.tls[0].hosts[0]=chronos.example.com

Autoscaling​

Enable horizontal pod autoscaling:

helm install chronos deploy/helm/chronos/ \
--set autoscaling.enabled=true \
--set autoscaling.minReplicas=2 \
--set autoscaling.maxReplicas=10 \
--set autoscaling.targetCPUUtilization=70

Observability & Availability​

Enable a Prometheus Operator ServiceMonitor to scrape /metrics automatically:

helm install chronos deploy/helm/chronos/ \
--set metrics.serviceMonitor.enabled=true \
--set metrics.serviceMonitor.interval=30s

A PodDisruptionBudget (enabled by default, minAvailable: 1) keeps capacity during voluntary disruptions like node drains and rolling upgrades — tune it under podDisruptionBudget in values.yaml.

Production Checklist​

ItemRecommendation
StorageUse PostgreSQL, not SQLite
SecretsUse external secret manager (Vault, AWS SM)
IngressEnable TLS termination
AutoscalingEnable HPA with CPU/memory targets
ResourcesSet requests and limits
Health checksLiveness and readiness probes on /health/live and /health/ready
LoggingStructured JSON logs to stdout
MonitoringExport metrics via /metrics endpoint

Production example​

A complete, opinionated production manifest set — PostgreSQL storage, JWT/JWKS authentication, TLS termination at the ingress, HPA, and liveness/readiness probes wired to /health/live and /health/ready — lives in deploy/production/ in the repository. Start from it rather than duplicating the Helm values above. See The ChronosOS Server and Authentication & Authorization for what those manifests configure.

Upgrading​

helm upgrade chronos deploy/helm/chronos/ \
--set image.tag=v0.3.0

Uninstalling​

helm uninstall chronos