Example: the Talon API
The generic recipe is in Onboard an app. This page is Talon filled in on this Project Loom
node. Same workloads/<app>/{base,overlays} shape, same Infisical wiring, same canary as
Penvoice — the platform doesn’t care that it’s a second Go app. Where it’s worth calling
out: unlike Penvoice, Talon has no client in this node’s Keycloak. It verifies its own
passwords and issues its own session, so Keycloak plays no part in it at all.
flowchart LR
Push([push app staging]) --> CI[checks → GHCR sha]
CI --> Stg[overlays/staging newTag]
Stg --> Argo[Argo CD]
Promo[Promote] --> Prod[overlays/prod same digest]
Inf[Infisical GUI] -->|operator|Sec[(talon-api-env)]
Sec --> RO[Rollout]
Argo --> RO
Staging host test.api.mytalon.co.zw, prod api.mytalon.co.zw. Namespaces talon-staging / talon-prod. The
browser holds an httpOnly session cookie; the API is the only party that ever sees a password or a session token.
Sessions live in the app’s own Postgres tables (CNPG, not a separate store) since this runs 2 replicas behind a
canary and an in-process session map wouldn’t survive that.
Manifests
Section titled “Manifests”ApplicationSet rows in apps/workloads.yaml. Files under workloads/talon/base/ plus overlay patches (namespace,
host, Infisical slug, image tag). Identical layout to Penvoice’s.
Infisical project talon, cells staging and prod, each holding FRONTEND_URL (the web origin for that
environment) and DEFAULT_PASSWORD. Git has projectId + slug only. Not in Infisical: DB_URL (CNPG uri) and the
container port (SERVER_PORT, hardcoded in the Rollout, same role as Penvoice’s API_PORT).
Runtime
Section titled “Runtime”The app runs its embedded migrations on boot (golang-migrate, advisory-locked, so replicas starting together are
safe), then seeds any missing baseline stores and the tadmin super admin. /healthz is process-only and backs the
liveness probe; /readyz pings Postgres and backs readiness, so a database outage takes pods out of rotation without
restarting them. A 5s preStop sleep keeps a terminating pod serving until Traefik drops its endpoint.
Local dev
Section titled “Local dev”Same Infisical project, a third cell: dev. talon-api’s .infisical.json points at the same projectId as the
overlays, defaultEnvironment: dev; infisical run -- air replaces manually-exported vars. dev holds all four
keys, including DB_URL and SERVER_PORT (no CNPG, no shared manifest locally). Recipe:
Onboard → Secrets § Wire local dev.
IntelliJ: a committed Shell Script run config (.run/Air - Development.run.xml, wrapping the same
infisical run -- air), the same one Penvoice uses.
Canary
Section titled “Canary”Prod: 25→50→75, 60s pauses. Staging: one replica, weight 100. Same strategy as Penvoice. The canary shape lives in the platform pattern, not the app.