Self-Hosting Overview
Forginate is a multi-tenant AI software-factory SaaS that you can run entirely on your own Kubernetes cluster. A single Helm chart — deploy/helm/forginate — installs the whole control plane: API gateway, orchestrator, chat-editor, Postgres, Redis, MinIO, backups, ingress, and TLS certificates.
This section walks a DevOps engineer through a production-grade install, from prerequisites to upgrades. Everything is environment-driven: no hardcoded domains, no assumptions about your cloud provider. If your cluster can run CloudNativePG and cert-manager, it can run Forginate.
Architecture at a glance
browser ── https://forginate.example.com
│
▼
Ingress (your ingress class, TLS via cert-manager)
│
▼
api-gateway ─────────────► serves the SPA, REST API, WebSockets, /metrics
│ :8080 public OAuth sign-in via GitHub; sessions are JWTs
│ :8081 internal (cluster-only, agent-token auth — never on an Ingress)
│
├── orchestrator ──► claims queued runs, creates k8s Jobs in a dedicated
│ runs namespace (factory-runner / qa-runner pods)
├── chat-editor ───► SSE-streaming doc-editing agent (own HPA)
├── forginate-db ──► Postgres 17 via CloudNativePG (CNPG)
├── redis ─────────► sessions, rate limits, pub/sub, deploy-agent commands
└── minio ─────────► S3-compatible object storage (docs, artifacts,
chat attachments, database backups)Factory runs execute as one-shot Kubernetes Jobs in a separate namespace (orchestrator.runsNamespace), locked down by a default-deny NetworkPolicy that only permits DNS, the gateway's internal listener, the OTLP collector, and public HTTPS egress (with an in-runner hostname allowlist on top).
What the chart installs
| Component | Workload | Notes |
|---|---|---|
forginate-db | CNPG Cluster | Postgres 17, app user from a bootstrap secret |
redis | StatefulSet | password-protected, AOF persistence |
minio | StatefulSet | buckets auto-provisioned on first write |
api-gateway | Deployment + 2 Services + Ingress | public HTTP/WS + internal listener |
orchestrator | Deployment | schedules factory/QA runs as Jobs |
chat-editor | Deployment + HPA | scales on active SSE streams |
forginate-pg-backup | CronJob | daily pg_dump → MinIO |
| Runs namespace | Namespace + RBAC + NetworkPolicy | created by the chart |
| ServiceMonitor + Grafana dashboard | optional | requires prometheus-operator |
Container images are published to ghcr.io/the-pizza/forginate-<service>: forginate-api-gateway, forginate-orchestrator, forginate-factory-runner, forginate-qa-runner, forginate-chat-editor, and forginate-deploy-agent (the customer-cluster agent, shipped as a separate chart — deploy/helm/forginate-deploy-agent).
Hard prerequisites
You must have these installed before the chart will deploy cleanly:
- Kubernetes with Helm 3 and a working default
StorageClass(set viaglobal.storageClass). - CloudNativePG operator — the chart creates a
postgresql.cnpg.io/v1 Cluster; without the operator the CR sits unreconciled and nothing gets a database. - cert-manager with a
ClusterIssuer(name goes inglobal.certIssuer). The tenant-apps wildcard certificate requires a DNS-01 capable issuer. - An ingress controller and its
IngressClassname (global.ingressClass). - DNS you control: an A/CNAME record for your app domain and, if you host tenant apps, a wildcard record for
*.apps.<your-domain>.
Optional but strongly recommended:
- prometheus-operator / kube-prometheus-stack —
apiGateway.serviceMonitor.enableddefaults totrue; disable it if you don't have theServiceMonitorCRD. - An OTLP collector (e.g. Grafana Alloy) at
observability.otlpEndpointfor traces. - Loki if you want the admin UI's "System Logs" tab (
apiGateway.lokiUrl).
ServiceMonitor CRD
With apiGateway.serviceMonitor.enabled: true (the default) the chart renders a monitoring.coreos.com/v1 ServiceMonitor. If the CRD is not installed, helm upgrade --install fails. Set it to false on clusters without prometheus-operator.
Secrets model
The chart never templates credentials. Secrets are created out of band in the release namespace and referenced by fixed names (forginate-db-app-user, forginate-jwt, forginate-github-oauth, forginate-minio, and so on). A helper script, deploy/scripts/bootstrap-secrets.sh, generates the random infrastructure passwords; the rest you create with kubectl create secret. The full list is in Configuration.
Several secrets are declared optional: true in the pod specs (GitHub App, Stripe, AWS, registry-pull), so the platform boots before those integrations are configured and each feature simply stays dark until its secret exists.
Recommended reading order
- Installation — operators, secrets, first
helm install. - Configuration — every values key and secret, explained.
- Ingress & Domains — app domain, tenant-apps wildcard, share host.
- GitHub App — tenant repo access.
- LLM Providers — platform keys vs. per-org BYO keys.
- Deploy Targets — customer clusters and AWS account vending.
- Backups, Observability, Upgrading.
Optional integrations
GitHub App, Stripe billing, AWS account vending, and the observability stack are all optional. A minimal self-hosted install needs only: the three bootstrap secrets, a database URL secret, a JWT secret, a GitHub OAuth app for sign-in, a credential-vault key, and an internal service token.