Skip to main content

Custom resources

Two CRDs in the pagifier.io/v1alpha1 group. Developers never touch them — they are the operator's contract — but platform operators observe them directly.

Application

Long-lived; one per project per environment. Carries a pointer to the release that should be live.

apiVersion: pagifier.io/v1alpha1
kind: Application
metadata:
name: frontend
namespace: pgf-acme-prod
spec:
tenant: acme
environment: prod
activeRelease: frontend-r20260714-101530-ab12cd34 # set by the API
paused: false
status:
phase: Available # Pending | WaitingForBuild | Deploying | Available | Degraded | Failed | Paused
deployedRelease: frontend-r20260714-101530-ab12cd34
url: https://app.company.com
readyReplicas: 3
canary: # present during a canary rollout
release: frontend-r…
weight: 50
stepStartedAt: "2026-07-14T10:20:00Z"
analysisFailures: 0
lastAnalysis: all 2 gates passing
activeColor: green # blue/green strategy
colorReleases:
blue: frontend-r…
green: frontend-r…

kubectl get applications shows tenant, environment, phase, active release, canary weight, and URL as columns. Preview applications carry a pagifier.io/expires-at annotation and are garbage-collected on expiry (deleting an Application cascades to its Releases and workloads).

Release

Immutable; one per upload. Snapshots the artifact reference and the fully resolved configuration.

apiVersion: pagifier.io/v1alpha1
kind: Release
metadata:
name: frontend-r20260714-101530-ab12cd34
namespace: pgf-acme-prod
labels:
pagifier.io/fingerprint: 4f2a… # build-input identity (enables image reuse)
spec:
application: frontend
artifact:
bucket: pagifier-artifacts
key: artifacts/acme/frontend/prod/r…/app.zip
sha256: 9f86d08…
config: {} # resolved snapshot (JSON)
status:
phase: Deployed # Pending | Building | Built | Deploying | Deployed | Failed | Superseded
image: registry/acme/frontend:b-4f2a91c02be411aa
buildJob: build-frontend-r…
buildLog: | # tail, on build failure

message: image built and pushed

Phase semantics worth knowing:

  • Pending with a queued: message means the cluster-wide build concurrency limit is reached; the build starts when a slot frees.
  • Built without a build job means the image was reused — an earlier release had an identical build fingerprint.
  • Superseded releases are rollback targets; the rollback API re-arms them to Built.
  • Finished releases beyond the retention window are pruned in-cluster; full history remains in PostgreSQL.

Labels

LabelOnMeaning
app.kubernetes.io/namepods, selectorsWorkload/track identity (frontend, frontend-canary, frontend-blue)
pagifier.io/applicationeverythingApplication identity across all tracks — what NetworkPolicy and PDB select
pagifier.io/tenant, pagifier.io/environmenteverythingTenancy
pagifier.io/releaseworkloadsWhich release rendered this
pagifier.io/fingerprintreleasesBuild-input identity