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 Imagedocker 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