What Weβre Building
A new deploy/zhi/ directory containing an alternative deployment approach using zhi. This includes:
- A zhi config plugin (Go) defining all deployment parameters currently spread across
values.yaml,values-shared.yaml, andvalues-dedicated.yaml - A zhi workspace with Go templates generating raw Kubernetes YAML manifests matching the Helm chartβs full resource set
- Apply targets for deployment lifecycle (apply, stop, destroy, restart, infrastructure)
- A hybrid strategy where zhi owns Glyphoxa resources and optional infrastructure components (PostgreSQL, sealed-secrets) are deployed via Helm through a separate apply target
Why This Approach
The Helm chart works but zhi offers interactive configuration editing (TUI/Web/MCP), cross-value validation, component toggling, and a typed config plugin β advantages for operators who want guided setup. The hybrid approach (Approach A) was chosen because:
- Zhi handles Glyphoxa-specific resources with full validation and metadata
- Infrastructure components (PostgreSQL, sealed-secrets) stay as upstream Helm charts β battle-tested and maintained by their communities
- Operators who manage infrastructure separately just skip the
infrastructureapply target - Helm is already a known tool in the ecosystem (itβs the current deployment method)
Key Decisions
Topology: Single workspace with topology value (not separate workspaces)
A core/topology config value (shared or dedicated) controls replica counts, anti-affinity, node selectors via template conditionals. The config plugin validates topology-specific constraints (e.g., warn if dedicated has 3+ replicas). Transform or validation logic enforces topology defaults.
Rationale: The topology differences are value-level (replica count, node labels, affinity toggles), not structural. One workspace is simpler to maintain.
Components
| Component | Paths | Mandatory | Dependencies | |β|β|β|β| | gateway | gateway/ | Yes | β | | worker | worker/ | Yes | β | | mcp-gateway | mcp-gateway/ | No | β | | network-policy | network-policy/ | No | β | | autoscaling | autoscaling/ | No | β | | postgresql | postgresql/ | No | β | | sealed-secrets | sealed-secrets/ | No | β |
Infrastructure via Helm (opt-in)
The infrastructure apply target runs helm upgrade --install for PostgreSQL and sealed-secrets using config values from the zhi tree (chart version, passwords, persistence size, etc.). Operators with externally managed infrastructure skip this target entirely and just provide a database/dsn.
Feature Parity with Helm Chart
The following Kubernetes resources will be generated via zhi templates:
Always generated:
- Gateway Deployment + Service
- Worker Job Template ConfigMap
- Application ConfigMap (
/etc/glyphoxa/config.yaml) - ServiceAccount + Role + RoleBinding (job-manager RBAC)
- Secrets (admin API key)
Conditional on components:
- MCP Gateway Deployment + Service (component:
mcp-gateway) - NetworkPolicies for gateway, worker, mcp-gateway (component:
network-policy) - HorizontalPodAutoscaler (component:
autoscaling)
Via infrastructure apply target:
- PostgreSQL (Bitnami Helm chart)
- Sealed-secrets controller (Bitnami Labs Helm chart)
Config Plugin Structure
The plugin defines values mirroring the Helm values with metadata for interactive editing:
core/β namespace, topology (shared/dedicated), image repo/tag/pullPolicygateway/β replicaCount, ports, resources, adminKey, podAntiAffinity, nodeSelector, tolerations, serviceAccountworker/β resourceProfile (cloud/whisper-native/local-llm), profiles, activeDeadlineSeconds, ttlSecondsAfterFinished, ports, nodeSelector, tolerations, gpu settingsmcp-gateway/β replicaCount, ports, resources, nodeSelector, tolerationsdatabase/β dsn (manual or auto-built from postgresql component values)network-policy/β enabled flag (component toggle handles this)autoscaling/β minReplicas, maxReplicas, targetCPUUtilizationPercentagepostgresql/β auth (postgresPassword, database), persistence size, chart versionsealed-secrets/β chart version
Validation Rules
core/topologymust besharedordedicatedgateway/replicaCountwarning if >2 in dedicated topologygateway/adminKeyrequired (blocking) for non-dev deploymentsdatabase/dsnrequired ifpostgresqlcomponent is disabledworker/resourceProfilemust be one ofcloud,whisper-native,local-llm- Cross-value: if
worker/resourceProfileislocal-llm, warn if no GPU tolerations set
Apply Targets
apply:
default:
command: "./scripts/apply.sh"
pre-export: true
timeout: 300
infrastructure:
command: "./scripts/infra.sh"
pre-export: true
timeout: 300
stop:
command: "kubectl delete -f ./generated/ --ignore-not-found"
pre-export: false
destroy:
command: "./scripts/destroy.sh"
pre-export: false
restart:
command: "kubectl rollout restart deployment -l app.kubernetes.io/part-of=glyphoxa"
pre-export: false
Template Structure
deploy/zhi/
βββ plugin/
β βββ main.go
β βββ metadata.go # ValueDef helper (same pattern as home-server)
β βββ values.go # All config paths, defaults, metadata
β βββ validate.go # Validation rules
β βββ validate_test.go
β βββ values_test.go
β βββ go.mod
β βββ zhi-plugin.yaml
βββ workspace/
β βββ zhi.yaml # Components, export, apply targets
β βββ zhi-workspace.yaml # Metadata and dependencies
β βββ templates/
β β βββ gateway-deployment.yaml.tmpl
β β βββ gateway-service.yaml.tmpl
β β βββ mcp-gateway-deployment.yaml.tmpl
β β βββ mcp-gateway-service.yaml.tmpl
β β βββ worker-job-template-configmap.yaml.tmpl
β β βββ configmap.yaml.tmpl
β β βββ secrets.yaml.tmpl
β β βββ serviceaccount.yaml.tmpl
β β βββ networkpolicy.yaml.tmpl
β β βββ hpa.yaml.tmpl
β β βββ apply.sh.tmpl
β β βββ infra.sh.tmpl
β β βββ destroy.sh.tmpl
β βββ scripts/ # Generated by export (gitignored)
β βββ generated/ # Generated K8s manifests (gitignored)
β βββ .gitignore
Open Questions
- Should the zhi workspace publish to GHCR as an OCI artifact (like zhi-home-server), or is it only consumed from the monorepo?
- Should there be a CI workflow that validates the plugin builds and templates render correctly?
- Do we want a
statusapply target that runskubectl getcommands to show deployment state?
Next Steps
-> /workflows:plan for implementation details