CommerceDeployment
Kubernetes
Deploy Hanzo Commerce on Kubernetes with Helm charts and autoscaling
Deploy Hanzo Commerce on Kubernetes for high availability, horizontal scaling, and production-grade orchestration.
Prerequisites
- Kubernetes 1.27+ cluster
kubectlconfigured for your cluster- Helm 3.12+
- A managed PostgreSQL instance (recommended) or in-cluster PostgreSQL
- A managed Redis instance or in-cluster Redis
Helm Chart
Install the Hanzo Commerce Helm chart:
helm repo add hanzo https://charts.hanzo.ai
helm repo updateCreate a values file:
replicaCount: 2
image:
repository: hanzoai/commerce
tag: latest
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 8090
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
hosts:
- host: commerce.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: commerce-tls
hosts:
- commerce.example.com
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
persistence:
enabled: true
storageClass: gp3
size: 50Gi
env:
COMMERCE_ENV: production
COMMERCE_PORT: "8090"
envFrom:
- secretRef:
name: commerce-secrets
- configMapRef:
name: commerce-configInstall the chart:
helm install commerce hanzo/commerce -f values.yaml -n commerce --create-namespaceSecrets
Create the Kubernetes Secret with sensitive values:
apiVersion: v1
kind: Secret
metadata:
name: commerce-secrets
namespace: commerce
type: Opaque
stringData:
DATABASE_URL: "postgresql://commerce:[email protected]:5432/commerce?sslmode=require"
KV_URL: "redis://:[email protected]:6379/0"
HANZO_API_KEY: "hk_live_..."
HANZO_CLIENT_ID: "your_client_id"
HANZO_CLIENT_SECRET: "your_client_secret"
STRIPE_SECRET_KEY: "sk_live_..."
STRIPE_WEBHOOK_SECRET: "whsec_..."
MEILI_MASTER_KEY: "your-meilisearch-key"kubectl apply -f commerce-secrets.yamlConfigMap
Non-sensitive configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: commerce-config
namespace: commerce
data:
COMMERCE_DIR: "/data"
COMMERCE_ENV: "production"
COMMERCE_LOG_LEVEL: "info"
S3_URL: "s3://key:[email protected]/commerce-uploads"
SEARCH_URL: "http://meilisearch.commerce.svc:7700"kubectl apply -f commerce-config.yamlStatefulSet (Alternative to Deployment)
If you need stable network identities or ordered startup, use a StatefulSet instead of the Helm chart's Deployment:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: commerce
namespace: commerce
spec:
serviceName: commerce
replicas: 2
selector:
matchLabels:
app: commerce
template:
metadata:
labels:
app: commerce
spec:
containers:
- name: commerce
image: hanzoai/commerce:latest
ports:
- containerPort: 8090
envFrom:
- secretRef:
name: commerce-secrets
- configMapRef:
name: commerce-config
readinessProbe:
httpGet:
path: /health/ready
port: 8090
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8090
initialDelaySeconds: 15
periodSeconds: 10
startupProbe:
httpGet:
path: /health/startup
port: 8090
failureThreshold: 30
periodSeconds: 5
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
volumeMounts:
- name: data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: gp3
resources:
requests:
storage: 50GiIngress Configuration
Nginx Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: commerce
namespace: commerce
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/rate-limit-window: "1m"
spec:
ingressClassName: nginx
tls:
- hosts:
- commerce.example.com
secretName: commerce-tls
rules:
- host: commerce.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: commerce
port:
number: 8090Horizontal Pod Autoscaling
The Helm chart includes an HPA. To configure it manually:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: commerce
namespace: commerce
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: commerce
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120Supporting Services
Meilisearch
apiVersion: apps/v1
kind: Deployment
metadata:
name: meilisearch
namespace: commerce
spec:
replicas: 1
selector:
matchLabels:
app: meilisearch
template:
metadata:
labels:
app: meilisearch
spec:
containers:
- name: meilisearch
image: getmeili/meilisearch:latest
ports:
- containerPort: 7700
env:
- name: MEILI_ENV
value: production
- name: MEILI_MASTER_KEY
valueFrom:
secretKeyRef:
name: commerce-secrets
key: MEILI_MASTER_KEY
volumeMounts:
- name: data
mountPath: /meili_data
volumes:
- name: data
persistentVolumeClaim:
claimName: meilisearch-pvc
---
apiVersion: v1
kind: Service
metadata:
name: meilisearch
namespace: commerce
spec:
selector:
app: meilisearch
ports:
- port: 7700Monitoring
Deploy a ServiceMonitor for Prometheus scraping:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: commerce
namespace: commerce
spec:
selector:
matchLabels:
app: commerce
endpoints:
- port: http
path: /metrics
interval: 15sUpgrading
Update the image tag and apply:
helm upgrade commerce hanzo/commerce -f values.yaml -n commerceOr for a rolling update:
kubectl set image deployment/commerce commerce=hanzoai/commerce:1.5.0 -n commerce
kubectl rollout status deployment/commerce -n commerceNext Steps
- Deploy your storefront to Vercel
- Set up a self-hosted deployment for full control
- Review architecture for scaling considerations
How is this guide?
Last updated on