+
+Complete guide for deploying VAPORA v1.0 to Kubernetes (self-hosted).
+Version: 0.1.0
+Status: Production Ready
+Last Updated: 2025-11-10
+
+
+
+- Overview
+- Prerequisites
+- Architecture
+- Deployment Methods
+- Building Docker Images
+- Kubernetes Deployment
+- Provisioning Deployment
+- Configuration
+- Monitoring & Health Checks
+- Scaling
+- Troubleshooting
+- Rollback
+- Security
+
+
+
+VAPORA v1.0 is a cloud-native multi-agent software development platform that runs on Kubernetes. It consists of:
+
+- 6 Rust services: Backend API, Frontend UI, Agents, MCP Server, LLM Router (embedded), Shared library
+- 2 Infrastructure services: SurrealDB (database), NATS JetStream (messaging)
+- Multi-IA routing: Claude, OpenAI, Gemini, Ollama support
+- 12 specialized agents: Architect, Developer, Reviewer, Tester, Documenter, etc.
+
+All services are containerized and deployed as Kubernetes workloads.
+
+
+
+
+- Kubernetes 1.25+ (K3s, RKE2, or managed Kubernetes)
+- kubectl (configured and connected to cluster)
+- Docker or Podman (for building images)
+- Nushell (for deployment scripts)
+
+
+
+- Provisioning CLI (for advanced deployment)
+- Helm (if using Helm charts)
+- cert-manager (for automatic TLS certificates)
+- Prometheus/Grafana (for monitoring)
+
+
+
+- Minimum: 4 CPU, 8GB RAM, 50GB storage
+- Recommended: 8 CPU, 16GB RAM, 100GB storage
+- Production: 16+ CPU, 32GB+ RAM, 200GB+ storage
+
+
+
+- Storage Class: Required for SurrealDB PersistentVolumeClaim
+- Options: local-path, nfs-client, rook-ceph, or cloud provider storage
+- Minimum: 20Gi for database
+
+
+
+- nginx-ingress controller installed
+- Domain name pointing to cluster ingress IP
+- TLS certificate (optional, recommended for production)
+
+
+
+┌─────────────────────────────────────────────────────┐
+│ Internet / Users │
+└───────────────────────┬─────────────────────────────┘
+ │
+┌───────────────────────▼─────────────────────────────┐
+│ Ingress (nginx) │
+│ - vapora.example.com │
+│ - TLS termination │
+└────┬────────┬─────────┬─────────┬──────────────────┘
+ │ │ │ │
+ │ │ │ │
+┌────▼────┐ ┌▼─────┐ ┌▼─────┐ ┌▼──────────┐
+│Frontend │ │Backend│ │ MCP │ │ │
+│(Leptos) │ │(Axum) │ │Server│ │ │
+│ 2 pods │ │2 pods │ │1 pod │ │ │
+└─────────┘ └───┬───┘ └──────┘ │ │
+ │ │ │
+ ┌──────┴──────┬──────────┤ │
+ │ │ │ │
+ ┌────▼────┐ ┌───▼─────┐ ┌▼───────┐ │
+ │SurrealDB│ │ NATS │ │ Agents │ │
+ │StatefulS│ │JetStream│ │ 3 pods │ │
+ │ 1 pod │ │ 1 pod │ └────────┘ │
+ └─────────┘ └─────────┘ │
+ │ │
+ ┌────▼────────────────────────────────┐ │
+ │ Persistent Volume (20Gi) │ │
+ │ - SurrealDB data │ │
+ └─────────────────────────────────────┘ │
+ │
+┌─────────────────────────────────────────────▼──┐
+│ External LLM APIs │
+│ - Anthropic Claude API │
+│ - OpenAI API │
+│ - Google Gemini API │
+│ - (Optional) Ollama local │
+└───────────────────────────────────────────────┘
+
+
+
+VAPORA supports two deployment methods:
+
+Pros:
+
+- Simple, well-documented
+- Standard K8s manifests
+- Easy to understand and modify
+- No additional tools required
+
+Cons:
+
+- Manual cluster management
+- Manual service ordering
+- No built-in rollback
+
+Use when: Learning, testing, or simple deployments
+
+Pros:
+
+- Automated cluster creation
+- Declarative workflows
+- Built-in rollback
+- Service mesh integration
+- Secret management
+
+Cons:
+
+- Requires Provisioning CLI
+- More complex configuration
+- Steeper learning curve
+
+Use when: Production deployments, complex environments
+
+
+
+# Build all images (local registry)
+nu scripts/build-docker.nu
+
+# Build and push to Docker Hub
+nu scripts/build-docker.nu --registry docker.io --push
+
+# Build with specific tag
+nu scripts/build-docker.nu --tag v0.1.0
+
+# Build without cache
+nu scripts/build-docker.nu --no-cache
+
+
+# From project root
+
+# Backend
+docker build -f crates/vapora-backend/Dockerfile -t vapora/backend:latest .
+
+# Frontend
+docker build -f crates/vapora-frontend/Dockerfile -t vapora/frontend:latest .
+
+# Agents
+docker build -f crates/vapora-agents/Dockerfile -t vapora/agents:latest .
+
+# MCP Server
+docker build -f crates/vapora-mcp-server/Dockerfile -t vapora/mcp-server:latest .
+
+
+
+- vapora/backend: ~50MB (Alpine + Rust binary)
+- vapora/frontend: ~30MB (nginx + WASM)
+- vapora/agents: ~50MB (Alpine + Rust binary)
+- vapora/mcp-server: ~45MB (Alpine + Rust binary)
+
+
+
+
+Edit kubernetes/03-secrets.yaml:
+stringData:
+ # Generate strong JWT secret
+ jwt-secret: "$(openssl rand -base64 32)"
+
+ # Add your LLM API keys
+ anthropic-api-key: "sk-ant-xxxxx"
+ openai-api-key: "sk-xxxxx"
+ gemini-api-key: "xxxxx" # Optional
+
+ # Database credentials
+ surrealdb-user: "root"
+ surrealdb-pass: "$(openssl rand -base64 32)"
+
+IMPORTANT: Never commit real secrets to version control!
+
+Edit kubernetes/08-ingress.yaml:
+spec:
+ rules:
+ - host: vapora.yourdomain.com # Change this!
+
+
+# Dry run to validate
+nu scripts/deploy-k8s.nu --dry-run
+
+# Deploy to default namespace (vapora)
+nu scripts/deploy-k8s.nu
+
+# Deploy to custom namespace
+nu scripts/deploy-k8s.nu --namespace my-vapora
+
+# Skip secrets (if already created)
+nu scripts/deploy-k8s.nu --skip-secrets
+
+
+# Apply manifests in order
+kubectl apply -f kubernetes/00-namespace.yaml
+kubectl apply -f kubernetes/01-surrealdb.yaml
+kubectl apply -f kubernetes/02-nats.yaml
+kubectl apply -f kubernetes/03-secrets.yaml
+kubectl apply -f kubernetes/04-backend.yaml
+kubectl apply -f kubernetes/05-frontend.yaml
+kubectl apply -f kubernetes/06-agents.yaml
+kubectl apply -f kubernetes/07-mcp-server.yaml
+kubectl apply -f kubernetes/08-ingress.yaml
+
+# Wait for rollout
+kubectl rollout status deployment/vapora-backend -n vapora
+kubectl rollout status deployment/vapora-frontend -n vapora
+
+
+# Check all pods are running
+kubectl get pods -n vapora
+
+# Expected output:
+# NAME READY STATUS RESTARTS
+# surrealdb-0 1/1 Running 0
+# nats-xxx 1/1 Running 0
+# vapora-backend-xxx 1/1 Running 0
+# vapora-backend-yyy 1/1 Running 0
+# vapora-frontend-xxx 1/1 Running 0
+# vapora-frontend-yyy 1/1 Running 0
+# vapora-agents-xxx 1/1 Running 0
+# vapora-agents-yyy 1/1 Running 0
+# vapora-agents-zzz 1/1 Running 0
+# vapora-mcp-server-xxx 1/1 Running 0
+
+# Check services
+kubectl get svc -n vapora
+
+# Check ingress
+kubectl get ingress -n vapora
+
+
+# Get ingress IP/hostname
+kubectl get ingress vapora -n vapora
+
+# Configure DNS
+# Point vapora.yourdomain.com to ingress IP
+
+# Access UI
+open https://vapora.yourdomain.com
+
+
+
+
+# Validate Provisioning workspace
+nu scripts/validate-provisioning.nu
+
+
+cd provisioning/vapora-wrksp
+
+# Validate configuration
+provisioning validate --all
+
+# Create cluster
+provisioning cluster create --config workspace.toml
+
+
+# Deploy infrastructure (database, messaging)
+provisioning workflow run workflows/deploy-infra.yaml
+
+# Deploy services (backend, frontend, agents)
+provisioning workflow run workflows/deploy-services.yaml
+
+# Or deploy full stack at once
+provisioning workflow run workflows/deploy-full-stack.yaml
+
+
+provisioning workflow run workflows/health-check.yaml
+
+See provisioning-integration/README.md for details.
+
+
+
+
+RUST_LOG=info,vapora=debug
+SURREALDB_URL=http://surrealdb:8000
+SURREALDB_USER=root
+SURREALDB_PASS=<secret>
+NATS_URL=nats://nats:4222
+JWT_SECRET=<secret>
+BIND_ADDR=0.0.0.0:8080
+
+
+RUST_LOG=info,vapora_agents=debug
+NATS_URL=nats://nats:4222
+BIND_ADDR=0.0.0.0:9000
+ANTHROPIC_API_KEY=<secret>
+OPENAI_API_KEY=<secret>
+GEMINI_API_KEY=<secret>
+VAPORA_AGENT_CONFIG=/etc/vapora/agents.toml # Optional
+
+
+RUST_LOG=info,vapora_mcp_server=debug
+# Port configured via --port flag
+
+
+Create custom configuration:
+kubectl create configmap agent-config -n vapora \
+ --from-file=agents.toml
+
+Mount in deployment:
+volumeMounts:
+- name: config
+ mountPath: /etc/vapora
+volumes:
+- name: config
+ configMap:
+ name: agent-config
+
+
+
+
+All services expose health check endpoints:
+
+- Backend:
GET /health
+- Frontend:
GET /health.html
+- Agents:
GET /health, GET /ready
+- MCP Server:
GET /health
+- SurrealDB:
GET /health
+- NATS:
GET /healthz (port 8222)
+
+
+# Backend health
+kubectl exec -n vapora deploy/vapora-backend -- \
+ curl -s http://localhost:8080/health
+
+# Database health
+kubectl exec -n vapora deploy/vapora-backend -- \
+ curl -s http://surrealdb:8000/health
+
+# NATS health
+kubectl exec -n vapora deploy/vapora-backend -- \
+ curl -s http://nats:8222/healthz
+
+
+All deployments have:
+
+- Liveness Probe: Restarts unhealthy pods
+- Readiness Probe: Removes pod from service until ready
+
+
+# View backend logs
+kubectl logs -n vapora -l app=vapora-backend -f
+
+# View agent logs
+kubectl logs -n vapora -l app=vapora-agents -f
+
+# View all logs
+kubectl logs -n vapora -l app --all-containers=true -f
+
+
+Deploy Prometheus + Grafana:
+# Install Prometheus Operator
+helm install prometheus prometheus-community/kube-prometheus-stack \
+ -n monitoring --create-namespace
+
+# Access Grafana
+kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80
+
+VAPORA services expose metrics on /metrics endpoint (future enhancement).
+
+
+
+# Scale backend
+kubectl scale deployment vapora-backend -n vapora --replicas=4
+
+# Scale frontend
+kubectl scale deployment vapora-frontend -n vapora --replicas=3
+
+# Scale agents (for higher workload)
+kubectl scale deployment vapora-agents -n vapora --replicas=10
+
+
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: vapora-backend-hpa
+ namespace: vapora
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: vapora-backend
+ minReplicas: 2
+ maxReplicas: 10
+ metrics:
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: 70
+
+Apply:
+kubectl apply -f hpa.yaml
+
+
+Adjust in deployment YAML:
+resources:
+ requests:
+ cpu: 200m
+ memory: 256Mi
+ limits:
+ cpu: 1000m
+ memory: 1Gi
+
+
+
+
+# Check pod status
+kubectl get pods -n vapora
+
+# Describe pod for events
+kubectl describe pod -n vapora <pod-name>
+
+# Check logs
+kubectl logs -n vapora <pod-name>
+
+# Check previous logs (if crashed)
+kubectl logs -n vapora <pod-name> --previous
+
+
+# Check SurrealDB is running
+kubectl get pod -n vapora -l app=surrealdb
+
+# Test connection from backend
+kubectl exec -n vapora deploy/vapora-backend -- \
+ curl -v http://surrealdb:8000/health
+
+# Check SurrealDB logs
+kubectl logs -n vapora surrealdb-0
+
+
+# Check NATS is running
+kubectl get pod -n vapora -l app=nats
+
+# Test connection
+kubectl exec -n vapora deploy/vapora-backend -- \
+ curl http://nats:8222/varz
+
+# Check NATS logs
+kubectl logs -n vapora -l app=nats
+
+
+# Check image pull secrets
+kubectl get secrets -n vapora
+
+# Create Docker registry secret
+kubectl create secret docker-registry regcred \
+ -n vapora \
+ --docker-server=<registry> \
+ --docker-username=<username> \
+ --docker-password=<password>
+
+# Add to deployment
+spec:
+ imagePullSecrets:
+ - name: regcred
+
+
+# Check ingress controller is installed
+kubectl get pods -n ingress-nginx
+
+# Check ingress resource
+kubectl describe ingress vapora -n vapora
+
+# Check ingress logs
+kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
+
+
+
+
+# View rollout history
+kubectl rollout history deployment/vapora-backend -n vapora
+
+# Rollback to previous version
+kubectl rollout undo deployment/vapora-backend -n vapora
+
+# Rollback to specific revision
+kubectl rollout undo deployment/vapora-backend -n vapora --to-revision=2
+
+
+cd provisioning/vapora-wrksp
+
+# List versions
+provisioning version list
+
+# Rollback to previous version
+provisioning rollback --to-version <version-id>
+
+
+
+
+
+- Kubernetes Secrets: Encrypted at rest (if configured in K8s)
+- External Secrets Operator: Sync from Vault, AWS Secrets Manager, etc.
+- RustyVault: Integrated with Provisioning
+
+
+Apply network policies to restrict pod-to-pod communication:
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+ name: vapora-backend
+ namespace: vapora
+spec:
+ podSelector:
+ matchLabels:
+ app: vapora-backend
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ app: vapora-frontend
+ ports:
+ - protocol: TCP
+ port: 8080
+
+
+Use cert-manager for automatic TLS:
+# Install cert-manager
+kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.yaml
+
+# Create ClusterIssuer
+kubectl apply -f - <<EOF
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+metadata:
+ name: letsencrypt-prod
+spec:
+ acme:
+ server: https://acme-v02.api.letsencrypt.org/directory
+ email: admin@yourdomain.com
+ privateKeySecretRef:
+ name: letsencrypt-prod
+ solvers:
+ - http01:
+ ingress:
+ class: nginx
+EOF
+
+Update ingress:
+metadata:
+ annotations:
+ cert-manager.io/cluster-issuer: "letsencrypt-prod"
+spec:
+ tls:
+ - hosts:
+ - vapora.yourdomain.com
+ secretName: vapora-tls
+
+
+
+
+# Create backup
+kubectl exec -n vapora surrealdb-0 -- \
+ surreal export --conn http://localhost:8000 \
+ --user root --pass <password> \
+ --ns vapora --db main backup.surql
+
+# Copy backup locally
+kubectl cp vapora/surrealdb-0:/backup.surql ./backup-$(date +%Y%m%d).surql
+
+
+# Copy backup to pod
+kubectl cp ./backup.surql vapora/surrealdb-0:/restore.surql
+
+# Restore
+kubectl exec -n vapora surrealdb-0 -- \
+ surreal import --conn http://localhost:8000 \
+ --user root --pass <password> \
+ --ns vapora --db main /restore.surql
+
+
+# Snapshot PVC (if supported by storage class)
+kubectl apply -f - <<EOF
+apiVersion: snapshot.storage.k8s.io/v1
+kind: VolumeSnapshot
+metadata:
+ name: surrealdb-snapshot
+ namespace: vapora
+spec:
+ source:
+ persistentVolumeClaimName: data-surrealdb-0
+EOF
+
+
+
+
+# Delete namespace (deletes all resources)
+kubectl delete namespace vapora
+
+# Or delete manifests individually
+kubectl delete -f kubernetes/
+
+
+# List PVCs
+kubectl get pvc -n vapora
+
+# Delete PVC (data will be lost!)
+kubectl delete pvc data-surrealdb-0 -n vapora
+
+
+
+After successful deployment:
+
+- Configure DNS: Point domain to ingress IP
+- Set up TLS: Configure cert-manager for HTTPS
+- Enable monitoring: Deploy Prometheus/Grafana
+- Configure backups: Schedule SurrealDB backups
+- Set up CI/CD: Automate deployments
+- Configure HPA: Enable autoscaling
+- Test disaster recovery: Practice rollback procedures
+
+
+
+
+- Deployment Issues: Check
kubernetes/README.md
+- Provisioning Issues: Check
provisioning-integration/README.md
+- Scripts Help: Run
nu scripts/<script-name>.nu --help
+- Kubernetes Docs: https://kubernetes.io/docs/
+
+
+VAPORA v1.0 - Cloud-Native Multi-Agent Platform
+Status: Production Ready ✅
+
+