GitLab¶
GitLab EE runs in the bootstrap namespace, deployed via the official Helm chart with custom images for the webservice and sidekiq components.
Custom Images¶
Two components run custom EE images built from internal Dockerfiles:
registry.mdapi.ch/mdapi/gitlab-webservice-eeregistry.mdapi.ch/mdapi/gitlab-sidekiq-ee
Both use pullPolicy: Always — restarting the pods picks up the new image without a Helm upgrade. Images are mirrored to zot.mdapi.ch (an OCI-compatible registry) before each upgrade to ensure availability if the internal registry is temporarily unreachable during the upgrade process.
Upgrade Flow¶
GitLab must be upgraded one minor version at a time (e.g. 18.10 → 18.11, never 18.10 → 18.12). A Windmill flow (f/gitlab/upgrade_flow) automates the process:
flowchart LR
trigger["Trigger upgrade flow\nwindmill.mdapi.ch"]
check["Check current vs\ntarget version"]
build["Bump Dockerfile\ntag + trigger\nCI build"]
mirror["Mirror image\nto zot.mdapi.ch\n(skopeo)"]
helm["helm upgrade\ngitlab gitlab/gitlab\n--version <new>"]
verify["Verify pods\nready"]
trigger --> check --> build --> mirror --> helm --> verify
CI Pipeline — CVE Scanning¶
Every custom Docker image CI pipeline includes a security scan stage using Grype and Syft:
flowchart LR
build["build\ndocker buildx"] --> scan["scan\nSyft SBOM\nGrype CVE check"] --> notify["notify\nPushover alert\n(HIGH/CRITICAL only)"]
build --> push["push :latest\nto registry"]
- Syft generates an SPDX JSON SBOM, stored as a 7-day CI artifact
- Grype checks against the SBOM for HIGH and CRITICAL CVEs
- Builds are non-blocking (
allow_failure: true) — a CVE never stops a deployment - Alert threshold: any HIGH or CRITICAL finding triggers a Pushover notification at priority 1
This runs on 9 custom images: GitLab webservice/sidekiq, Keycloak, Chrony, Certspotter, Autoconfig, OpenNIC tier-2, Mirror, Threadfin, Joplin MCP, ZNC.
Runner Architecture¶
| Runner ID | Type | API visibility | Usage |
|---|---|---|---|
| 156, 159 | Group | Non-admin API visible | ~7 jobs/30d |
| 172 | Instance (Helm) | Invisible to non-admin /api/v4/runners |
~571 jobs/30d |
Instance runners (type instance) are not returned by the standard runner list API unless the caller has admin privileges. Use the Rancher API pod health check or mint a temporary admin PAT to verify instance runner health.
Zot OCI Registry¶
Zot runs in the zot namespace as an OCI-native registry mirror at zot.mdapi.ch. It holds mirrored copies of the custom GitLab images and serves as a fallback during upgrades.