Example: the Penvoice API
The generic recipe is in Onboard an app. This page is Penvoice filled in on this Project Loom node. Ayde, Z1, or the next API use the same folders with different names.
flowchart LR Push([merge app main]) --> CI[CI → GHCR sha] CI --> Stg[overlays/staging newTag] Stg --> Argo[Argo CD] Promo[Promote] --> Prod[overlays/prod same digest] Inf[Infisical GUI] -->|operator| Sec[(penvoice-api-kc)] Sec --> RO[Rollout] Argo --> RO
Staging host test.api.penvoice.app, prod api.penvoice.app. Namespaces penvoice-staging / penvoice-prod.
Distroless static arm64, tag ghcr.io/webb1es/penvoice-api:sha-<short>. Schema applies in-process at startup.
Manifests
Section titled “Manifests”ApplicationSet rows in apps/workloads.yaml. Files under workloads/penvoice/base/ plus overlay patches (namespace,
host, Infisical slug, image tag, analysis not present).
Infisical project penvoice, cells staging and prod. Git has projectId + slug only. Not in Infisical: DB_URL
(CNPG uri), container port.
Canary
Section titled “Canary”Prod: 25→50→75, 60s pauses. Staging: one replica, weight 100. The API may still export /metrics for a future
scrape stack — nothing in Git scrapes it today.