Ory Kratos can be deployed to Kubernetes using Helm charts or raw Kubernetes manifests.
Helm chart
The recommended way to deploy Kratos on Kubernetes is using the official Helm chart:
Add the Ory Helm repository
helm repo add ory https://k8s.ory.sh/helm/charts
helm repo update
Install Kratos
helm install kratos ory/kratos \
--namespace kratos \
--create-namespace
Verify the installation
kubectl get pods -n kratos
kubectl get svc -n kratos
Helm values configuration
Create a values.yaml file to customize your deployment:
kratos:
config:
dsn: postgres://user:password@postgres:5432/kratos?sslmode=require
serve:
public:
base_url: https://auth.example.com
cors:
enabled: true
allowed_origins:
- https://example.com
admin:
base_url: https://admin-auth.example.com
selfservice:
default_browser_return_url: https://example.com/
allowed_return_urls:
- https://example.com
identity:
default_schema_id: default
schemas:
- id: default
url: base64://ewogICIkaWQiOiAiaHR0cHM6Ly9zY2hlbWFzLm9yeS5zaC9wcmVzZXRzL2tyYXRvcy9pZGVudGl0eS5lbWFpbC5zY2hlbWEuanNvbiIsCiAgInRpdGxlIjogIlBlcnNvbiIsCiAgInR5cGUiOiAib2JqZWN0IiwKICAicHJvcGVydGllcyI6IHsKICAgICJ0cmFpdHMiOiB7CiAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICJwcm9wZXJ0aWVzIjogewogICAgICAgICJlbWFpbCI6IHsKICAgICAgICAgICJ0eXBlIjogInN0cmluZyIsCiAgICAgICAgICAiZm9ybWF0IjogImVtYWlsIiwKICAgICAgICAgICJvcnkuc2gva3JhdG9zIjogewogICAgICAgICAgICAiY3JlZGVudGlhbHMiOiB7CiAgICAgICAgICAgICAgInBhc3N3b3JkIjogewogICAgICAgICAgICAgICAgImlkZW50aWZpZXIiOiB0cnVlCiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICAidmVyaWZpY2F0aW9uIjogewogICAgICAgICAgICAgICJ2aWEiOiAiZW1haWwiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJyZWNvdmVyeSI6IHsKICAgICAgICAgICAgICAidmlhIjogImVtYWlsIgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9LAogICAgICAicmVxdWlyZWQiOiBbImVtYWlsIl0KICAgIH0KICB9Cn0=
replicaCount: 2
image:
repository: oryd/kratos
tag: v25.4.0
pullPolicy: IfNotPresent
service:
public:
enabled: true
type: ClusterIP
port: 80
admin:
enabled: true
type: ClusterIP
port: 80
ingress:
public:
enabled: true
className: nginx
hosts:
- host: auth.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: auth-tls
hosts:
- auth.example.com
admin:
enabled: true
className: nginx
hosts:
- host: admin-auth.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: admin-auth-tls
hosts:
- admin-auth.example.com
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
job:
automigrate:
enabled: true
Install with your custom values:
helm install kratos ory/kratos \
-f values.yaml \
--namespace kratos \
--create-namespace
Raw Kubernetes manifests
If you prefer not to use Helm, here’s a basic Kubernetes deployment:
Namespace
apiVersion: v1
kind: Namespace
metadata:
name: kratos
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: kratos-config
namespace: kratos
data:
kratos.yml: |
version: v0.13.0
dsn: postgres://kratos:secret@postgresql:5432/kratos?sslmode=require
serve:
public:
base_url: https://auth.example.com/
cors:
enabled: true
admin:
base_url: https://admin.example.com/
selfservice:
default_browser_return_url: https://example.com/
flows:
login:
ui_url: https://example.com/auth/login
registration:
ui_url: https://example.com/auth/registration
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: kratos
namespace: kratos
spec:
replicas: 2
selector:
matchLabels:
app: kratos
template:
metadata:
labels:
app: kratos
spec:
containers:
- name: kratos
image: oryd/kratos:v25.4.0
command: ["kratos"]
args: ["serve", "-c", "/etc/config/kratos.yml"]
ports:
- name: public
containerPort: 4433
- name: admin
containerPort: 4434
volumeMounts:
- name: config
mountPath: /etc/config
env:
- name: DSN
valueFrom:
secretKeyRef:
name: kratos-secrets
key: dsn
livenessProbe:
httpGet:
path: /health/alive
port: admin
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: admin
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: config
configMap:
name: kratos-config
Services
apiVersion: v1
kind: Service
metadata:
name: kratos-public
namespace: kratos
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 4433
name: public
selector:
app: kratos
---
apiVersion: v1
kind: Service
metadata:
name: kratos-admin
namespace: kratos
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 4434
name: admin
selector:
app: kratos
Database migration job
Run database migrations before starting Kratos:
apiVersion: batch/v1
kind: Job
metadata:
name: kratos-migrate
namespace: kratos
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migrate
image: oryd/kratos:v25.4.0
command: ["kratos"]
args: ["-c", "/etc/config/kratos.yml", "migrate", "sql", "-e", "--yes"]
volumeMounts:
- name: config
mountPath: /etc/config
env:
- name: DSN
valueFrom:
secretKeyRef:
name: kratos-secrets
key: dsn
volumes:
- name: config
configMap:
name: kratos-config
Secrets management
Store sensitive data in Kubernetes Secrets:
apiVersion: v1
kind: Secret
metadata:
name: kratos-secrets
namespace: kratos
type: Opaque
stringData:
dsn: postgres://kratos:secret@postgresql:5432/kratos?sslmode=require
secrets-default: "your-32-character-secret-here"
secrets-cookie: "your-32-character-cookie-secret"
secrets-cipher: "your-32-character-cipher-secret"
Never commit secrets to version control. Use tools like Sealed Secrets, External Secrets Operator, or Vault for production.
Health checks
Kratos exposes health check endpoints:
/health/alive - Liveness probe (checks if Kratos is running)
/health/ready - Readiness probe (checks if Kratos can handle requests)
Scaling considerations
Horizontal pod autoscaling
Configure HPA based on CPU and memory:apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: kratos
namespace: kratos
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: kratos
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
Database connection pooling
Configure connection limits in your DSN:postgres://user:pass@host/db?max_conns=20&max_idle_conns=10
Next steps
Database setup
Configure production database
Configuration
Complete configuration reference