Skip to content

Deploy an app change

Two repos: code in the app repo, image tag in loom. You do not kubectl apply. Staging and prod are overlays on the same cluster. Every app ships this way — Penvoice is only an example.

flowchart LR
  A([merge app main]) --> CI[CI builds sha]
  CI --> Stg[overlays/staging newTag]
  Stg --> ArgoS[Argo syncs staging]
  ArgoS --> Promo[Promote Action]
  Promo --> Prod[overlays/prod same digest]
  Prod --> Canary[timed canary 25-50-75]

CI builds linux/arm64 and pushes ghcr.io/<owner>/<app>:sha-<sha>. Copy that tag from the Actions run.

The GHCR package must be public, or the pod needs an imagePullSecret.

Set images.newTag in workloads/<app>/overlays/staging/kustomization.yaml (not a raw image line in base/rollout.yaml if the overlay already pins the tag). Push. Argo syncs staging only.

Config-only: bump the *.app/redeploy annotation on the pod template so Rollouts sees a new revision.

GitHub Action Promote (workflow_dispatch, pick the app) copies staging newTag into the prod overlay and opens a PR — or you copy it by hand. Do not rebuild for prod.

Prod walks 25% → 50% → 75% with a 60s pause. Time only — no Prometheus gate. Staging is one replica and jumps to 100%.

Watch from Operate rollouts.