N Nexus Docs
Deployment

Kubernetes

Deploy NexusCommerce to a Kubernetes cluster with Helm, HPA autoscaling, and Ingress TLS.

Overview

The NexusCommerce Helm chart deploys the full platform to any Kubernetes cluster. It includes deployments with health probes, horizontal pod autoscalers for the API and workers, StatefulSets for Redis and ClickHouse, and an Ingress resource with cert-manager TLS.

The chart lives at infrastructure/k8s/nexuscommerce/.

Key Concepts

Helm Chart — A templated Kubernetes manifest collection with configurable values. NexusCommerce ships a single chart that deploys all services.

HPA (Horizontal Pod Autoscaler) — Automatically scales API pods (2-10 replicas) and worker pods (1-8 replicas) based on CPU utilization.

StatefulSets — Redis and ClickHouse use StatefulSets with persistent volume claims for data durability across pod restarts.

Ingress — A single Ingress resource routes traffic to the API and frontend based on path, with a separate host rule for Grafana on a subdomain.

Getting Started

Prerequisites

  • A Kubernetes cluster (1.28+)
  • Helm 3.15+
  • kubectl configured for your cluster
  • nginx-ingress controller installed
  • cert-manager installed (for automatic TLS)

Step 1: Create namespace and secret

kubectl create namespace nexuscommerce

kubectl create secret generic nexuscommerce-secret \
  --namespace nexuscommerce \
  --from-literal=NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co \
  --from-literal=NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... \
  --from-literal=SUPABASE_SERVICE_ROLE_KEY=eyJ... \
  --from-literal=SUPABASE_DB_URL=postgresql://... \
  --from-literal=CLICKHOUSE_PASSWORD=your-password \
  --from-literal=GRAFANA_ADMIN_PASSWORD=your-password

Step 2: Configure values

Review and customize values.yaml:

cp infrastructure/k8s/nexuscommerce/values.yaml my-values.yaml

At minimum, set global.domain to your production domain.

Step 3: Install

helm install nexuscommerce infrastructure/k8s/nexuscommerce \
  --namespace nexuscommerce \
  --values my-values.yaml \
  --set existingSecret=nexuscommerce-secret

Step 4: Verify

kubectl get pods -n nexuscommerce
kubectl get ingress -n nexuscommerce

All pods should reach Running status within 2 minutes. The Ingress should show your domain with the TLS certificate.

Features

Resources Deployed

ResourceKindReplicasNotes
WebDeployment2Next.js standalone
APIDeployment2NestJS, HPA 2-10
WorkersDeployment2Python FastAPI, HPA 1-8
RedisStatefulSet15 Gi PVC
ClickHouseStatefulSet150 Gi PVC
GrafanaDeployment1Optional

Autoscaling

The API and workers have horizontal pod autoscalers:

ServiceMinMaxTarget CPU
API21070%
Workers1880%

Disable HPA for staging by setting api.hpa.enabled: false and workers.hpa.enabled: false in your values file.

Health Probes

All deployments include liveness and readiness probes:

ServiceProbe PathInitial DelayPeriod
WebGET /15s (live), 5s (ready)30s / 10s
APIGET /api/v1/health15s / 5s30s / 10s
WorkersGET /health20s / 10s30s / 10s
GrafanaGET /api/health30s / 10s30s / 10s

Ingress Routing

HostPathBackend
app.nexuscommerce.io/api/v1API service (3001)
app.nexuscommerce.io/docsAPI service (3001)
app.nexuscommerce.io/Web service (3000)
grafana.nexuscommerce.io/Grafana service (3000)

TLS is handled by cert-manager with a letsencrypt-prod ClusterIssuer.

Values Files

FilePurpose
values.yamlProduction defaults
values-staging.yamlStaging overrides (1 replica, smaller resources, no HPA)
values-production.yamlProduction overrides (domain only)

Configuration

Upgrading

helm upgrade nexuscommerce infrastructure/k8s/nexuscommerce \
  --namespace nexuscommerce \
  --values my-values.yaml \
  --set global.imageTag=sha-abc1234

Using an External Secret Manager

Set existingSecret to the name of a Kubernetes Secret created by your secret manager (e.g., External Secrets Operator, Vault):

existingSecret: my-external-secret

When set, the chart skips creating its own Secret and references yours instead.

Disabling Optional Services

redis:
  enabled: false  # Use managed Redis (e.g., ElastiCache)
clickhouse:
  enabled: false  # Use managed ClickHouse
grafana:
  enabled: false  # Use external Grafana

When disabled, set the connection URLs directly in the ConfigMap or Secret.

Resource Defaults

ServiceCPU RequestMemory RequestCPU LimitMemory Limit
Web100m256 Mi500m512 Mi
API200m384 Mi1000m768 Mi
Workers200m512 Mi1000m1 Gi
Redis50m128 Mi250m320 Mi
ClickHouse250m1 Gi2000m4 Gi
Grafana50m128 Mi500m512 Mi