Run CIHub on Kubernetes
Install CIHub on a Kubernetes cluster with its Helm chart, get a Postgres for it (CloudNativePG, a managed service or your own server), expose it, and update it.
The Helm chart installs a Job that applies the migrations at each install and upgrade, a Deployment of identical replicas, a Service, and, if you want, an Ingress or a Gateway API HTTPRoute.
You need:
- A Kubernetes cluster (1.25 or later) and Helm.
- A Postgres 17: the next section gives three ways.
- The App of your CIHub and its keys: Create the GitHub App.
Get a Postgres
CIHub needs a database that it owns, through a role that is neither a superuser nor BYPASSRLS. CIHub isolates the
organizations with the row level security of Postgres, which such a role ignores: CIHub refuses to start with one.
You give CIHub the URL of the database in a Secret, under the key uri.
With the CloudNativePG operator in the cluster, one resource creates the database, its
owner, which is not a superuser, and the Secret cihub-db-app, whose key uri holds the URL:
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: cihub-db
spec:
instances: 2
imageName: ghcr.io/cloudnative-pg/postgresql:17
bootstrap:
initdb:
database: cihub
owner: cihub
storage:
size: 10Gikubectl apply -f cihub-db.yamlThe Secret of the database is cihub-db-app: you create none.
Create the Secrets
One Secret holds the keys of the App, and one the sealing key, at least 32 bytes, which seals the GitHub tokens of the people who sign in. With the keys of the App:
kubectl create secret generic cihub-github \
--from-file=private-key.pem=<path to the private key> \
--from-literal=webhook-secret='<webhook secret>' \
--from-literal=client-secret='<client secret>'
kubectl create secret generic cihub-sealing \
--from-literal=secret="$(openssl rand -hex 32)"Keep the sealing key: a new one signs every person out.
Install the chart
helm install cihub oci://ghcr.io/getcihub/charts/cihub \
--set database.existingSecret=cihub-db-app \
--set database.secretExistingSecret=cihub-sealing \
--set github.existingSecret=cihub-github \
--set github.appId='<App ID>' \
--set github.clientId='<Client ID>' \
--set publicUrl=https://cihub.example.com \
--set replicas=2publicUrl,github.clientIdand the client secret turn on the sign-in to the dashboard. Without them, only the API tokens work.- Two replicas keep one that receives the webhooks while a pod or a node is lost. The replicas share the work through
Postgres; each one opens up to
database.poolSizeconnections (10). - For a GitHub Enterprise Server, add
--set github.url=https://<your GitHub server>.
The migration Job runs first, then the pods start. Check them:
kubectl get pods -l app.kubernetes.io/instance=cihub
helm test cihubhelm test posts an unsigned delivery to the Service: CIHub must refuse it.
Expose CIHub
GitHub and the people reach CIHub on one address, with every path: the dashboard, /api, /auth and
/webhooks/github. With an Ingress:
ingress:
enabled: true
className: nginx
hosts:
- host: cihub.example.com
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- cihub.example.com
secretName: cihub-tlsOr with a Gateway: httpRoute.enabled: true, with httpRoute.hostnames and httpRoute.parentRefs.
The dashboard keeps a stream open on /api/v1/orgs/<org>/stream: the proxy must not buffer it, and must keep it open
past 15 seconds without data. Serve HTTP/2 to the browsers.
Every value of the chart is in helm/cihub/README.md.
Create an API token
Once the App is installed on your organization, a script or a CI that calls the API needs a token of the organization. The command prints it once:
kubectl exec deploy/cihub -- cihub-server token create --config /etc/cihub/server.yaml --org <login of the organization>Update CIHub
helm upgrade cihub oci://ghcr.io/getcihub/charts/cihub --reuse-valuesThe migration Job applies the migrations of the new version before the pods roll.
Go back to an older version
When the older version has fewer migrations, the running version reverts its own first, then Helm rolls back.
--to takes the newest migration of the older version: the last file of migrations/ in its tag.
kubectl exec deploy/cihub -- cihub-server migrate down --config /etc/cihub/server.yaml --to <version>
helm rollback cihubThe data of the reverted migrations is lost, and the pods of the newer version fail until the rollback ends.
Next
Install the App on your repositories, then merge your first pull request.
Run CIHub with Docker
Run CIHub, its Postgres and an HTTPS proxy on one machine with Docker Compose, then update it.
Merge your first pull request
The last steps of the installation, protect the target branch, check that your CI runs on the tests of the queue, then submit a first pull request and follow it to the merge.