Kubernetes Deployment
Deploy OpenPrime to Kubernetes using Helm for scalable, production-grade deployments.
Prerequisites​
- Kubernetes cluster 1.25+
- Helm 3.x
- kubectl configured
- Ingress controller (nginx-ingress recommended)
- cert-manager (for TLS)
- PostgreSQL (managed or in-cluster)
Helm Chart Installation​
Add Helm Repository​
helm repo add openprime https://charts.openprime.dev
helm repo update
Install with Default Values​
helm install openprime openprime/openprime \
--namespace openprime \
--create-namespace
Install with Custom Values​
helm install openprime openprime/openprime \
--namespace openprime \
--create-namespace \
-f values.yaml
Helm Values Configuration​
Complete values.yaml​
# Global configuration
global:
domain: yourdomain.com
environment: production
# Frontend configuration
frontend:
replicaCount: 2
image:
repository: openprime/frontend
tag: latest
pullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
env:
REACT_APP_API_URL: https://api.yourdomain.com
REACT_APP_KEYCLOAK_URL: https://auth.yourdomain.com
REACT_APP_KEYCLOAK_REALM: openprime
REACT_APP_KEYCLOAK_CLIENT_ID: openprime-app
# Backend configuration
backend:
replicaCount: 3
image:
repository: openprime/backend
tag: latest
pullPolicy: IfNotPresent
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
env:
NODE_ENV: production
LOG_LEVEL: info
secrets:
encryptionKey: "" # Set via --set or external secret
# Database configuration
postgresql:
enabled: true # Set false if using external database
auth:
username: openprime
password: "" # Set via --set
database: openprime
primary:
persistence:
size: 20Gi
# External database settings (if enabled: false)
external:
host: ""
port: 5432
database: openprime
existingSecret: ""
# Keycloak configuration
keycloak:
enabled: true # Set false if using external Keycloak
auth:
adminUser: admin
adminPassword: "" # Set via --set
postgresql:
enabled: true
# External Keycloak settings (if enabled: false)
external:
url: ""
realm: openprime
# Injecto service
injecto:
replicaCount: 2
image:
repository: openprime/injecto
tag: latest
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# Ingress configuration
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
hosts:
- host: yourdomain.com
paths:
- path: /
service: frontend
- host: api.yourdomain.com
paths:
- path: /
service: backend
- host: auth.yourdomain.com
paths:
- path: /
service: keycloak
tls:
- secretName: openprime-tls
hosts:
- yourdomain.com
- api.yourdomain.com
- auth.yourdomain.com
# Autoscaling
autoscaling:
enabled: true
frontend:
minReplicas: 2
maxReplicas: 10
targetCPUUtilization: 70
backend:
minReplicas: 3
maxReplicas: 20
targetCPUUtilization: 70
# Pod disruption budgets
podDisruptionBudget:
frontend:
minAvailable: 1
backend:
minAvailable: 2
# Service accounts
serviceAccount:
create: true
name: openprime
# Network policies
networkPolicy:
enabled: true
Deployment Steps​
1. Create Namespace​
kubectl create namespace openprime
2. Create Secrets​
# Database password
kubectl create secret generic openprime-db \
--namespace openprime \
--from-literal=password=your-db-password
# Encryption key
kubectl create secret generic openprime-encryption \
--namespace openprime \
--from-literal=key=$(openssl rand -hex 32)
# Keycloak admin password
kubectl create secret generic keycloak-admin \
--namespace openprime \
--from-literal=password=your-keycloak-password
3. Install Chart​
helm install openprime openprime/openprime \
--namespace openprime \
-f values.yaml \
--set postgresql.auth.existingSecret=openprime-db \
--set backend.secrets.existingSecret=openprime-encryption \
--set keycloak.auth.existingSecret=keycloak-admin
4. Verify Installation​
# Check pods
kubectl get pods -n openprime
# Check services
kubectl get svc -n openprime
# Check ingress
kubectl get ingress -n openprime
External Database​
For managed PostgreSQL (RDS, Cloud SQL, etc.):
# values.yaml
postgresql:
enabled: false
external:
host: your-db-host.rds.amazonaws.com
port: 5432
database: openprime
existingSecret: openprime-db-external
# Create secret
kubectl create secret generic openprime-db-external \
--namespace openprime \
--from-literal=username=openprime \
--from-literal=password=your-db-password
External Keycloak​
For existing Keycloak instance:
# values.yaml
keycloak:
enabled: false
external:
url: https://your-keycloak.com
realm: openprime
High Availability Configuration​
Multi-Zone Deployment​
# values.yaml
frontend:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: topology.kubernetes.io/zone
backend:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
topologyKey: topology.kubernetes.io/zone
Resource Quotas​
apiVersion: v1
kind: ResourceQuota
metadata:
name: openprime-quota
namespace: openprime
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
Monitoring​
Prometheus ServiceMonitor​
# values.yaml
serviceMonitor:
enabled: true
interval: 30s
labels:
release: prometheus
Grafana Dashboard​
Import the OpenPrime dashboard from the Helm chart:
kubectl get configmap openprime-grafana-dashboard -n openprime -o yaml
Upgrades​
Upgrade Chart​
# Update repo
helm repo update
# Upgrade release
helm upgrade openprime openprime/openprime \
--namespace openprime \
-f values.yaml
# Rollback if needed
helm rollback openprime 1 -n openprime
Database Migrations​
Migrations run automatically on backend pod startup. For manual execution:
kubectl exec -it deploy/openprime-backend -n openprime -- \
npm run db:migrate
Troubleshooting​
Check Pod Logs​
kubectl logs -f deploy/openprime-backend -n openprime
kubectl logs -f deploy/openprime-frontend -n openprime
Debug Pod​
kubectl run debug --rm -it --image=alpine -n openprime -- sh
Check Events​
kubectl get events -n openprime --sort-by='.lastTimestamp'