Skip to content

Harbor as Container Registry

Date: 2026-03-23 Status: Accepted Context: Choosing where to store container images built by student CI pipelines

Decision

Run a self-hosted Harbor instance on the platform cluster as the container registry for all projects.

Organization

harbor.prod.fontysvenlo.dev/
├── prj2-2026/              # Per-year project, one per cohort
│   ├── group01-backend
│   ├── group01-frontend
│   ├── group02-backend
│   └── ...
├── spohf/                   # Research project images
└── platform/                # Platform internal images (docs-site, db-init, etc.)

Rationale

  • Full control over retention, access policies, and cleanup. When a project ends, delete the Harbor project and all images are gone — clean lifecycle management.
  • Project-based model maps naturally to team isolation. Each year/cohort gets a project; each team gets image repositories within it.
  • Simpler integration with ArgoCD Image Updater — Image Updater polls Harbor's API directly with a single set of credentials. No complex token management per-org.
  • GHCR access control is messy — GitHub Container Registry's permission model is tied to GitHub orgs/users in ways that make bulk management and cleanup painful. Harbor's project model is simpler and more predictable.
  • Data sovereignty — images stay on our own infrastructure, not dependent on GitHub's availability or policy changes.
  • Educational value — having a self-hosted registry is part of showing students a realistic production setup.
  • Trivy vulnerability scanning as a bonus — images are scanned on push without extra tooling.

Alternatives Considered

GitHub Container Registry (GHCR)

  • ✅ No infrastructure to maintain
  • ✅ Close to student repositories
  • ❌ Access control is complex and poorly documented for education use cases
  • ❌ Cleanup across organizations/repos is manual and tedious
  • ❌ Dependency on external service availability
  • Rejected: Operational friction outweighs convenience

Docker Hub

  • ✅ Most well-known registry
  • ❌ Rate limits on free tier
  • ❌ No project-based organization model
  • ❌ Public by default (private repos cost money)
  • Rejected: Rate limits and cost model don't fit

Quay (Red Hat)

  • ✅ Open-source, feature-rich
  • ❌ Extra hosted service to manage or another self-hosted component
  • ❌ No significant advantage over Harbor for our use case
  • Rejected: No compelling reason to choose over Harbor

Consequences

Positive

  • Clean project lifecycle (create project → teams push → delete project when done)
  • Image Updater integration is straightforward
  • Vulnerability scanning without extra tooling
  • Full audit trail of image pushes

Negative

  • Another service to host and maintain on the cluster
  • Harbor's internal PostgreSQL and Redis add resource consumption
  • Harbor upgrades require careful planning (stateful service)
  • Admin password currently in plaintext in values file (known TODO)