Platform requirements
Konduit ships in the Konstruct chart with the foreman-operator disabled (replicaCount: 0). Enabling it requires registry, build, and deployment infrastructure. Everything below was validated live on a Civo control plane with self-hosted GitLab.
Checklist
- Harbor registry — reachable at
harbor.<domain>behind the platform gateway. The operator needs admin credentials to create per-org projects and robot accounts. - kpack with a Paketo ClusterBuilder named
defaultthat pushes to Harbor. Grant its ServiceAccount adockerconfigjsonsecret for the registry. - A target cluster pool — each entry in the operator's
VALID_CLUSTERSmust exist as a named Argo CD cluster (the operator's Applications usedestination.name). - A
foreman-appsArgo CD Application watchingregistry/clusters/<pool-cluster>/in the GitOps repository the operator commits to (the org GitAccount's repository). - An apps wildcard listener on the gateway with a wildcard certificate for
*.<region>.<domain>(DNS-01 — HTTP-01 cannot issue wildcards). - foreman-operator enabled in the konstruct chart values.
Operator configuration
foreman-operator:
replicaCount: 1
config:
harbor:
existingSecret: foreman-operator-config
externalSecret: # sync HARBOR_URL/USERNAME/PASSWORD from Vault
enabled: true
secretStoreRef: { name: vault-kv-secret, kind: ClusterSecretStore }
remoteRefs:
url: { key: konstruct/foreman/harbor, property: url }
username: { key: konstruct/foreman/harbor, property: username }
password: { key: konstruct/foreman/harbor, property: password }
kpackBuilder: "default"
managedOrgNamespace: "<platform-org-namespace>"
baseDomain: "<domain>"
gitOps: { branch: main }
chart:
repoURL: "https://github.com/konstructio/konstruct-templates"
path: "templates/konstruct-web-service"
revision: "<branch-or-ref>"
validClusters:
- k-nyc1
Hard-won gotchas
A declarative cluster secret pointing at https://kubernetes.default.svc silently renames Argo CD's implicit in-cluster entry — every Application addressed by destination.name: in-cluster breaks. For a named pool entry on the same cluster, use the cluster's external API endpoint with credentials synced from Vault.
The konstruct-web-service chart's HTTPRoute parentRef expects the apps wildcard listener to be named exactly https-apps on gateway eg in namespace default. A differently named listener rejects every app route with "No listeners match this parent ref".
Paketo buildpack images live at docker.io/paketobuildpacks/*. The old gcr.io/paketo-buildpacks mirror is dead and fails with an authentication error.
The registry hostname must resolve DNS-only (no CDN/proxy in front). Proxied records break TLS to the origin and cap upload bodies below container-layer sizes.
Verify
# builder ready and pushed to Harbor
kubectl get clusterbuilder default
# operator running with Harbor credentials synced
kubectl get pods -n konstruct-system | grep foreman-operator
kubectl get externalsecret -n konstruct-system foreman-operator-config
# register a test app, then follow it
kubectl get foremanapps -A -w