Install with Helm
Install the Dibbla platform onto an existing Kubernetes cluster.
The Helm chart at oci://ghcr.io/dibbla-agents/charts/dibbla installs the full platform — six platform services (API Gateway, Auth Service, Deploy API, Workflow Server, Go Toolserver, Feedback Service) plus PostgreSQL, Redis, MinIO, Loki + Grafana Alloy for log shipping, and (by default) BuildKit and a container registry. This page assumes you already have a cluster; if not, start with K3s or MicroK8s.
The Self-hosting guide generates a values.yaml
tailored to your cluster type, auth mode, data plane, and TLS setup. This page
is the manual reference.
This page’s values.yaml assumes you’re running the bundled Auth Service in your cluster. If you’d rather point at Dibbla’s hosted auth (no OAuth setup, no in-cluster Postgres for auth), read Configure authentication first — it shows the values overrides and skips most of the secrets you’d otherwise need to gather below.
Prerequisites
- A Kubernetes cluster meeting the overview prerequisites.
helm3.8+ andkubectlconfigured for the target cluster.- A wildcard DNS record
*.<your-base-domain>pointing at your ingress IP. - cert-manager installed with a
ClusterIssuer(recommended for automatic TLS). - These secrets ready:
- GHCR PAT with
read:packagesto pull platform images. - OAuth client — Google client ID + secret, and/or Microsoft Entra
clientId/clientSecret/tenantId. At least one provider is required. - JWT secret and signing key — generate each with
openssl rand -hex 32. - Workflow root token + OAuth encryption key — two more 32-byte hex keys for
workflow-server. - Anthropic and/or OpenAI API keys — required by
go-toolserverfor the workflow tools. - PostgreSQL passwords —
dibblauser +postgressuperuser. Generate any way you like. - MinIO root password — required by the bundled object storage; generate any way you like.
- GHCR PAT with
Minimum values.yaml
global:
baseDomain: example.com
imagePullSecret:
create: true
registry: ghcr.io
username: <your-github-username>
token: <your-ghcr-pat>
postgresql:
enabled: true
username: dibbla
password: <your-postgres-password>
superuserPassword: <your-postgres-superuser-password>
redis:
enabled: true
minio:
enabled: true
rootUser: minio
rootPassword: <your-minio-root-password>
loki:
enabled: true
alloy:
enabled: true
auth-service:
google:
clientId: <your-google-client-id>
clientSecret: <your-google-client-secret>
# microsoft: # uncomment to also enable Microsoft Entra
# clientId: <your-ms-client-id>
# clientSecret: <your-ms-client-secret>
# tenantId: <your-ms-tenant-id>
jwt:
secret: <your-jwt-secret>
signingKey: <your-signing-key>
redirectBaseUrl: https://app.example.com
allowedRedirectBaseUrls: https://app.example.com
api-gateway:
ingress:
enabled: true
type: standard
className: nginx
hosts:
- host: app.example.com
- host: api.example.com
tls:
- secretName: dibbla-tls
hosts:
- app.example.com
- api.example.com
deploy-api:
ingressClass: nginx
# workflow-server reuses auth-service's OAuth + JWT credentials so it can
# validate the same tokens. Keep these in sync with auth-service above.
workflow-server:
rootToken: <your-workflow-root-token>
oauthEncryptionKey: <your-oauth-encryption-key>
googleClientId: <your-google-client-id>
googleClientSecret: <your-google-client-secret>
jwtSecret: <your-jwt-secret>
redirectBaseUrl: https://app.example.com
go-toolserver:
anthropicApiKey: <your-anthropic-key>
openaiApiKey: <your-openai-key>
The app.example.com host serves the Auth UI (sign-in) and Deploy UI (dashboard). The api.example.com host serves the API. Adjust to your conventions.
The example above is the bundled-everything path — Postgres, Redis, MinIO (object storage for workflow artifacts), Loki (log storage), and Alloy (log shipping) all run in-cluster. To bring your own managed Postgres / Redis / S3 / Loki, see External infrastructure below.
Install
helm install dibbla oci://ghcr.io/dibbla-agents/charts/dibbla \
--namespace dibbla --create-namespace \
-f values.yaml
After a minute or so:
kubectl -n dibbla get pods
You should see all platform services Running:
dibbla-api-gateway-… 1/1 Running
dibbla-auth-service-… 1/1 Running
dibbla-deploy-api-… 1/1 Running
dibbla-workflow-server-… 1/1 Running
dibbla-go-toolserver-… 1/1 Running
dibbla-feedback-service-… 1/1 Running
dibbla-postgresql-0 1/1 Running
dibbla-redis-master-0 1/1 Running
dibbla-minio-… 1/1 Running
dibbla-loki-0 1/1 Running
dibbla-alloy-… 1/1 Running # one per node (DaemonSet)
dibbla-buildkit-… 1/1 Running # if enabled
dibbla-container-registry-… 1/1 Running # if enabled
Continue to Configure authentication to create the first admin user.
Routing strategy
deploy-api.routingStrategy controls how the Deploy API wires DNS for newly deployed apps. Four valid values:
| Value | Behavior | Required values |
|---|---|---|
wildcard (default) | No DNS automation — the API Gateway routes by Host header. You manage your own wildcard DNS pointing at the ingress. | none |
k8s-ingress | Creates an Ingress per app and a Cloudflare CNAME pointing at the ingress entrypoint. | cloudflare.apiToken, cloudflare.zoneId, ingressHostTarget |
cloudflare-tunnel | Adds a tunnel route per app on the existing Cloudflare Tunnel. No Kubernetes Ingress per app. | full cloudflare.* block |
cloudflare-tunnel-ingress | Tunnel + Ingress hybrid (what Dibbla’s hosted platform uses). | cloudflare.apiToken, cloudflare.zoneId, cloudflare.tunnelId |
For most self-hosted installs the default wildcard is the right choice — point a wildcard A record at your ingress IP and you’re done. The Cloudflare modes are for installs that want per-app DNS records or run behind a Cloudflare Tunnel.
TLS
Add a cert-manager ClusterIssuer (Let’s Encrypt HTTP-01 or DNS-01) and annotate the ingress through the chart values. The example above expects a dibbla-tls secret to exist; cert-manager can produce it automatically when annotated correctly.
A minimal HTTP-01 issuer:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- http01:
ingress:
class: nginx
Then add to your api-gateway.ingress block:
api-gateway:
ingress:
annotations:
cert-manager.io/cluster-issuer: letsencrypt
External infrastructure
Disable the bundled subcharts and point at your managed instances:
global:
postgresql: { enabled: false }
redis: { enabled: false }
minio: { enabled: false }
loki: { enabled: false }
alloy: { enabled: true } # still needed to ship logs to externalLoki
externalPostgresql:
host: <your-postgres-host>
port: 5432
username: dibbla
password: <your-postgres-password>
sslmode: require
externalRedis:
host: <your-redis-host>
port: 6379
db: 0
externalMinio:
host: <your-s3-host>
port: 443
accessKey: <your-s3-access-key>
secretKey: <your-s3-secret-key>
useSsl: "true"
bucket: workflow-artifacts
externalLoki:
pushEndpoint: <your-loki-push-endpoint> # e.g. https://logs.example.com/loki/api/v1/push
queryEndpoint: <your-loki-query-endpoint> # used by deploy-api LOKI_URL
postgresql: { enabled: false }
redis: { enabled: false }
minio: { enabled: false }
loki: { enabled: false }
PostgreSQL must be reachable from the cluster, must support the dibbla user, and the chart will create databases (auth_db, agent_db, workflows, feedback_db) on first start. MinIO can be any S3-compatible object store (AWS S3, GCS in S3-compatibility mode, etc.). External Loki can be Grafana Cloud or self-hosted.
The chart ships single-pod Postgres (pgvector/pgvector:pg17 — Postgres 17
with pgvector) and Redis (redis:7-alpine) subcharts. Fine for evaluation
and small production. For HA, backups, or point-in-time recovery, disable
the bundled subchart and use external managed Postgres (CloudNativePG, RDS,
etc.) via global.externalPostgresql.*.
Optional components
BuildKit and the in-cluster container registry are enabled by default and can be disabled if you’d rather use external infrastructure:
global:
buildkit:
enabled: false
containerRegistry:
enabled: false
externalBuildkit:
addr: tcp://<your-buildkit-host>:1234
externalRegistry:
url: <your-registry-host>
The bundled container registry exposes itself on nodePort: 32000 by default; switch it to ClusterIP plus its own ingress if NodePort isn’t an option.