Skip to content

Production Deployment

The NKZ GitOps Starter is the canonical way to deploy NKZ OS in production. It’s a template repo with an interactive setup wizard that configures your domain, generates secrets, and bootstraps the full platform via ArgoCD — in under 10 minutes.

nkz-gitops-starter (you fork it) Your K3s server
┌──────────────────────┐ ┌──────────────────────┐
│ config/*.yaml │ │ │
│ overlays/core/ │ ArgoCD │ NKZ OS platform │
│ overlays/modules/ │ ════════▶ │ (all services) │
│ bootstrap/ │ │ │
└──────────────────────┘ └──────────────────────┘

The starter uses a two-repo GitOps pattern:

  1. Public repo (nkz-os/nkz) — base Kubernetes manifests with placeholders
  2. Your private fork (nkz-gitops-starter) — production overlays with your actual domains, generated by the wizard

ArgoCD syncs both and keeps them reconciled. You never kubectl apply directly.

Terminal window
# 1. Clone the starter
git clone https://github.com/nkz-os/nkz-gitops-starter
cd nkz-gitops-starter
# 2. Run the wizard
./scripts/setup.sh

The wizard asks:

  • Domain (e.g., example.com) and subdomains (derived automatically)
  • Company name and admin email
  • Server IP (optional — auto-installs K3s + ArgoCD + cert-manager if provided)

It replaces all {{PLACEHOLDER}} tokens across 55+ overlay manifests, generates random secrets for PostgreSQL, Redis, MinIO, MongoDB, and Keycloak, and optionally bootstraps the server.

Terminal window
# 3. Create the secrets (copypaste from wizard output)
kubectl create namespace nekazari
kubectl create secret generic jwt-secret --from-literal=secret="..." -n nekazari
kubectl create secret generic redis-secret --from-literal=password="..." -n nekazari
# ... (six secrets total)
# 4. Push to your private fork
git init && git add -A
git commit -m "NKZ OS configured for example.com"
git remote add origin https://github.com/YOUR_ORG/nkz-gitops-config
git push -u origin main
# 5. Apply the ArgoCD root app
kubectl apply -f bootstrap/root-config.yaml
# 6. Watch the platform deploy
watch kubectl get apps -n argocd

Within 5–10 minutes, ArgoCD syncs all services. TLS certificates are issued automatically by cert-manager + Let’s Encrypt.

These DNS records must point to your server IP before deploying:

SubdomainServiceRequired
(your domain)Frontend appYes
api.(your domain)API GatewayYes
auth.(your domain)Keycloak SSOYes
minio.(your domain)Object storageYes
argo.(your domain)ArgoCD dashboardYes
vpn.(your domain)VPN / TailscaleOptional

A wildcard DNS record covers all of them.

ResourceMinimumRecommended
CPU2 cores4+ cores
RAM4 GB8 GB
Disk40 GB80+ GB SSD
OSUbuntu 22.04+Ubuntu 24.04
ServicePurpose
Orion-LDFIWARE NGSI-LD Context Broker
Keycloak 26OIDC / OAuth2 authentication
PostgreSQL + TimescaleDBRelational data + time-series telemetry
MongoDBOrion-LD entity registry
MinIOS3-compatible object storage
RedisCache, job queue, rate limiting
MosquittoMQTT broker for IoT devices
Traefik + cert-managerIngress with automatic TLS

Satellite indices (NDVI/SAVI/GNDVI), crop health engines, biological knowledge graph, time-series visualization, agrivoltaic orchestration, machinery routing, LiDAR 3D point clouds, terrain elevation, carbon accounting, cadastre integration, Spanish regulatory compliance (SIEX), n8n automation, team messaging, ERP, and VPN — see the Modules Catalog.

The starter generates random secrets for local use. For production, use one of:

  1. Access Keycloak at https://auth.YOUR_DOMAIN/auth → admin console
  2. Create a user with role PlatformAdmin
  3. Run scripts/keycloak-setup-mappers.sh (from the nkz repo)
  4. Verify modules appear in the dashboard
  5. Configure Grafana at https://YOUR_DOMAIN/grafana

ArgoCD apps stuck: kubectl patch app <name> -n argocd --type merge -p '{"operation":{"sync":{"revision":"HEAD"}}}'

Certificates not issued: DNS must resolve before cert-manager can issue. Check kubectl get challenges -A.

Out of memory: Disable optional modules by deleting their ArgoCD config apps: kubectl delete app zulip-config -n argocd.

Reset: kubectl delete ns nekazari && kubectl apply -f bootstrap/root-config.yaml