Skip to main content

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:

RuleRationale
Base images pinned by @sha256: digestReproducible builds; prevents supply-chain drift
Final stage uses distroless or scratchMinimal attack surface
USER nonroot or numeric UIDAligns with Pod Security restricted profile
No apt-get install in final stageKeeps image small, reduces CVE surface
COPY --from=builder onlyNo secrets or build tools leak into runtime image

Build Pipeline Stages​

  1. Checkout + Validate — Clone repo, verify Dockerfile lint (hadolint), check base image digests are current.
  2. Lint & Test — Run unit tests, SAST scan, dependency audit.
  3. Build Image — docker buildx build --platform linux/amd64 with build args for version metadata.
  4. 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:

TagExamplePurpose
<semver>-<sha>1.4.2-a1b2c3dImmutable, traceable to exact commit
<semver>1.4.2Human-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:

VariableDescription
HARBOR_REGISTRYHarbor hostname (e.g., harbor.opencenter.example.com)
HARBOR_PROJECTTarget project (e.g., platform-dev)
COSIGN_KEYcosign private key reference for signing (stored in CI secrets)
TRIVY_SEVERITYSeverity 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​