Build System
Purpose: For contributors, provides image build pipeline details including Dockerfiles, multi-stage builds, and CI integration.
Overview
Platform service images are built in CI using multi-stage Dockerfiles. Every image pins its base by digest, produces an OCI-compliant artifact tagged with the Git SHA, and publishes build metadata as OCI annotations.
Dockerfile Conventions
All platform Dockerfiles follow this structure:
# syntax=docker/dockerfile:1
FROM golang:1.22.4@sha256:abc123... AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app ./cmd/server
FROM gcr.io/distroless/static-debian12:nonroot@sha256:def456...
COPY --from=builder /app /app
USER 65534:65534
ENTRYPOINT ["/app"]
Rules enforced by CI lint:
| Rule | Rationale |
|---|---|
Base images pinned by @sha256: digest | Reproducible builds; prevents supply-chain drift |
| Final stage uses distroless or scratch | Minimal attack surface |
USER nonroot or numeric UID | Aligns with Pod Security restricted profile |
No apt-get install in final stage | Keeps image small, reduces CVE surface |
COPY --from=builder only | No secrets or build tools leak into runtime image |
Build Pipeline Stages
- Checkout + Validate — Clone repo, verify Dockerfile lint (
hadolint), check base image digests are current. - Lint & Test — Run unit tests, SAST scan, dependency audit.
- Build Image —
docker buildx build --platform linux/amd64with build args for version metadata. - Push to Harbor — Tag with
<version>-<git-sha-short>and push to the dev Harbor project.
Tagging Strategy
Each image receives two tags on build:
| Tag | Example | Purpose |
|---|---|---|
<semver>-<sha> | 1.4.2-a1b2c3d | Immutable, traceable to exact commit |
<semver> | 1.4.2 | Human-friendly, updated on each build of that version |
The latest tag is never used. FluxCD ImagePolicy resources and Kyverno policies reject latest at admission.
OCI Annotations
Build pipelines attach standard annotations to every image:
{
"org.opencontainers.image.source": "https://github.com/opencenter-cloud/openCenter-gitops-base",
"org.opencontainers.image.revision": "a1b2c3d4e5f6",
"org.opencontainers.image.created": "2025-01-15T10:30:00Z",
"org.opencontainers.image.version": "1.4.2"
}
CI Integration
Platform images build in GitHub Actions. The workflow file lives at .github/workflows/build-image.yaml in each service repository.
Key environment variables:
| Variable | Description |
|---|---|
HARBOR_REGISTRY | Harbor hostname (e.g., harbor.opencenter.example.com) |
HARBOR_PROJECT | Target project (e.g., platform-dev) |
COSIGN_KEY | cosign private key reference for signing (stored in CI secrets) |
TRIVY_SEVERITY | Severity threshold for pre-push scan (default: CRITICAL,HIGH) |
Base Image Update Cadence
Base images (distroless, Go, Python) are reviewed weekly by Dependabot PRs. When a base image digest changes, CI rebuilds all dependent images and runs the full scan pipeline before promotion.
Further Reading
- Image Lifecycle Overview — End-to-end flow
- Security & SBOM — Scanning and signing details
- Lifecycle Management — Retention and deprecation policies