Self-host Code
Deployment prerequisites, verification, and recovery for Code.
Install one Code provider into a Kubernetes cluster you administer, then enable it in a test workspace. Code manages repositories, deploy keys, and collaborators on GitHub, and keeps one kind of state outside kcp: commit bundles and git snapshots in transit between the portal and its controller.
Prerequisites
- An existing hub and a Code provider kubeconfig from the common provider flow
, saved as
code.kubeconfig. - A hosting cluster context, Helm, and kubectl.
- Bundle storage: a PVC-capable StorageClass for a single replica, or an S3-compatible bucket for more than one.
- Network routes from the provider to the hub, the kcp endpoints in its kubeconfig, and
github.com. - Optional: a GitHub OAuth App for “Connect with GitHub” in the portal.
Prepare credentials and values
kubectl --context HOSTING-CONTEXT create namespace railgrid-provider-code
kubectl --context HOSTING-CONTEXT --namespace railgrid-provider-code \
create secret generic railgrid-provider-kubeconfig \
--from-file=kubeconfig=./code.kubeconfigCreate code-values.yaml. This is the single-replica form with a PVC and personal-access-token connections only:
replicaCount: 1
hub:
url: https://railgrid-hub.railgrid-system.svc.cluster.local:9443
tokenSecretRef:
name: ""
catalogEntry:
enabled: true
bundleStore:
backend: file
persistence:
enabled: true
size: 1Gi
githubOAuth:
enabled: falseDo not switch to bundleStore.emptyDir to hide a failed persistent-volume setup; in-flight commits are lost on every pod replacement.
More than one replica: S3 bundle storage
The replica that accepts an upload and the leader replica that consumes it must read the same bytes, so replicaCount > 1 requires bundleStore.backend: s3 (the chart refuses to render otherwise). Any S3-compatible bucket works: AWS S3, MinIO, or a cloud object store through its S3 API. Railgrid’s production runs two replicas against a Google Cloud Storage bucket:
replicaCount: 2
bundleStore:
backend: s3
s3:
endpoint: storage.googleapis.com
bucket: my-code-bundles
# GCS's S3 API takes "auto"; a real region makes the client look the
# bucket location up, which needs more than object permissions.
region: auto
useSSL: true
credentialsSecretRef:
name: code-s3 # keys accessKeyId, secretAccessKeyTwo things the bucket needs that are easy to miss:
storage.buckets.getfor the credential. The client checks that the bucket exists at start (HEAD bucket). On GCS, an HMAC key whose service account has onlyroles/storage.objectAdminfails that check; addroles/storage.legacyBucketReaderon the bucket.- A lifecycle rule. With S3 the provider deletes a bundle once consumed but does not sweep what a crash left behind. Expire the
commit-bundles/andgit-snapshots/prefixes (plusbundleStore.s3.prefixif set) after one day.
Provision the bucket outside the chart; createBucket is for development loops.
Optional: GitHub OAuth
With githubOAuth.enabled, the portal shows “Connect with GitHub” and mints tokens with the scopes the provider needs. Without it, users paste a personal access token, which drives repositories, deploy keys, and collaborators just as well.
Create a GitHub OAuth App separate from the one Dex uses: an OAuth App has exactly one callback URL. Set its Authorization callback URL to the hub’s /services proxy path, which forwards to the provider without extra ingress:
https://console.example.com/services/providers/code/oauth/github/callbackkubectl --context HOSTING-CONTEXT --namespace railgrid-provider-code \
create secret generic code-github-oauth --from-literal=clientSecret="<client-secret>"githubOAuth:
enabled: true
clientId: <client-id>
clientSecretRef:
name: code-github-oauth
key: clientSecret
redirectURL: https://console.example.com/services/providers/code/oauth/github/callback
portalOrigin: https://console.example.com # set it; empty broadcasts the token to "*"A 503 from the OAuth round trip right after install is the provider being unready until a workspace binds it , not a bad client ID.
Render and install
helm template code oci://ghcr.io/railgrid/charts/railgrid-code-provider --version CHART_VERSION \
--namespace railgrid-provider-code --values code-values.yaml > /tmp/code-rendered.yaml
helm upgrade --install code oci://ghcr.io/railgrid/charts/railgrid-code-provider --version CHART_VERSION \
--kube-context HOSTING-CONTEXT --namespace railgrid-provider-code \
--values code-values.yaml
kubectl --context HOSTING-CONTEXT --namespace railgrid-provider-code \
get pods,pvc -l app.kubernetes.io/instance=codeReview the rendered resources before installing. The chart initializes the API schema and applies its CatalogEntry through the provider kubeconfig into kcp; the CatalogEntry is not a hosting-cluster resource.
Verify the full connection
- Check that the pod is running and, with
backend: file, the bundle PVC is bound. - Check registration and heartbeat in the hub. A healthy pod alone does not verify hub-to-provider routing.
- Enable Code in a disposable workspace.
- Complete the Code quickstart with a test repository and confirm that its status is readable using the same workspace identity.
Diagnose an installation failure
| Symptom | Check | Fix |
|---|---|---|
Init container fails with x509 | Provider kubeconfig CA and hub trust | Refresh the kubeconfig after fixing the hub’s provider CA |
Pod ready, x509 against a kcp shard hostname in the logs | The hub’s provider CA bundle lacks the kcp server CA | Fix the bundle, refresh the kubeconfig |
| Crash at start with a bucket error | HEAD bucket denied, or endpoint/region wrong | Grant storage.buckets.get; use region: auto on GCS |
| PVC stays Pending | StorageClass and hosting-cluster events | Provision compatible persistent storage before retrying |
| ImagePullBackOff | Image tag, registry access, pod events | Pin a published image version |
| CreateContainerConfigError | Referenced Secrets, including hub.tokenSecretRef | Create the intended Secret or remove an unused optional reference |
| “Connect with GitHub” fails | Callback URL, portalOrigin, provider readiness | Match the OAuth App’s callback to redirectURL exactly; enable the provider in a workspace |
kubectl --context HOSTING-CONTEXT --namespace railgrid-provider-code get events --sort-by=.lastTimestamp
kubectl --context HOSTING-CONTEXT --namespace railgrid-provider-code \
logs -l app.kubernetes.io/instance=code --all-containers=true --tail=100Redact credentials and private repository details before sharing diagnostics.
Remove the test installation
Remove test resources and workspace bindings before retiring the provider registration. Review upstream repository deletion policies first. Then uninstall the release:
helm uninstall code --kube-context HOSTING-CONTEXT --namespace railgrid-provider-codeInspect retained PVCs and credential Secrets separately. Helm uninstall is not a repository backup. Follow operations and recovery for an existing shared provider.
Chart values and chart README are authoritative for the deployed version.