Kubernetes deployment (off-spec)
Running Olympus on K8s, out of supported scope but doable
Olympus is designed for single-host Compose (ADR 0001). Kubernetes is officially out of scope. But operators sometimes need K8s anyway. Here's the rough shape, without guarantees.
Why this is off-spec
- Olympus tests against Podman Compose, not Kubernetes.
- Compose features (volume mounts, service names) translate but with subtle differences.
- Olympus's single-host design loses some assumptions (e.g. shared Caddy data volume).
- No Helm chart is published or maintained.
If you do this anyway, you're on your own for upgrades.
Sketch
Per Olympus service, a Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ciam-kratos
spec:
replicas: 1 # KEEP AT 1, Kratos isn't tested for horizontal scale
selector: { matchLabels: { app: ciam-kratos } }
template:
metadata: { labels: { app: ciam-kratos } }
spec:
containers:
- name: kratos
image: oryd/kratos:v1.x@sha256:...
envFrom:
- secretRef: { name: olympus-secrets }
volumeMounts:
- { name: kratos-config, mountPath: /etc/config/kratos }
ports:
- { containerPort: 4433 }
- { containerPort: 4434 }
readinessProbe:
httpGet: { path: /health/ready, port: 4433 }
volumes:
- name: kratos-config
configMap: { name: ciam-kratos-config }
---
apiVersion: v1
kind: Service
metadata: { name: ciam-kratos }
spec:
selector: { app: ciam-kratos }
ports:
- { name: public, port: 5001, targetPort: 4433 }
- { name: admin, port: 5002, targetPort: 4434 }Repeat for: iam-kratos, ciam-hydra, iam-hydra, ciam-athena, iam-athena, ciam-hera, iam-hera, site.
Ingress
Replace Caddy with an Ingress + cert-manager:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: olympus
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts: [ciam.example.com, iam.example.com, www.example.com]
secretName: olympus-tls
rules:
- host: ciam.example.com
http:
paths:
- path: /
pathType: Prefix
backend: { service: { name: ciam-hera, port: { number: 3000 } } }
# ... per hostIssues:
- Olympus's Caddy rate_limit doesn't translate; use Ingress-NGINX's rate limit or a sidecar.
- Caddy's security headers must be re-implemented at the Ingress level.
Secrets
Use K8s Secrets or external-secrets-operator backed by AWS Secrets Manager / Vault:
apiVersion: v1
kind: Secret
metadata: { name: olympus-secrets }
type: Opaque
stringData:
ENCRYPTION_KEY: ...
SESSION_SIGNING_KEY: ...
DATABASE_URL_CIAM_KRATOS: ...Postgres
Use a managed Postgres (RDS, Cloud SQL, Neon) outside K8s. Don't run Postgres inside the cluster unless you really know what you're doing.
What you give up
- The supported single-host model. You're on a K8s island.
- Caddy's reproducible build with rate_limit. Re-implement.
- Daedalus's deploy automation. Don't apply on K8s.
- The IA-friendly compose pattern. K8s YAML is verbose.
What you gain
- Existing K8s tooling integration: Argo CD, Flux, K8s observability stack.
- Familiarity for K8s teams.
- Multi-host failover (more complex than the docs admit; still needs careful Postgres + Hydra signing-key handling).
Recommendation
If you're heavily K8s-invested, consider:
- Run Olympus single-host on a beefy VM (k3s minimum).
- Treat it as a managed service in your K8s estate.
This is closer to the supported model than fully K8s-native.