A tiny FastAPI + psycopg2 app that exists for one reason: to prove, end to
end, that c2a daari secrets bind actually wires a Postgres-shaped Secret
into a running pod's environment. It's the demo app for
coordinator issue #187 (the appendServiceBinding
envFrom-patch fix).
GET /— friendly HTML landing page, links to/db-checkGET /db-check— opens a Postgres connection usingPOSTGRES_HOST/POSTGRES_PORT/POSTGRES_USER/POSTGRES_PASSWORD/POSTGRES_DBfrom the environment, runsSELECT 1, and returns:- success:
{"ok": true, "dbTimestamp": "...", "host": "...", "db": "..."} - failure:
{"ok": false, "error": "..."}with HTTP 500
- success:
The app fails fast at startup (SystemExit(1) with a clear stderr
message) if any of the four required env vars is missing. That's
deliberate — a silently-missing binding is exactly the failure mode this
app exists to catch, so we'd rather crash loudly on boot than serve
requests against vars that were never set.
Paketo auto-detects the Procfile (web: uvicorn app:app --host 0.0.0.0 --port $PORT) — no server.py/Node concerns, this is a pure Python
buildpack app.
c2aCLI installed and authenticated (c2a login)- An active project set (
c2a project use <name>— check withc2a project show) - A reachable Postgres instance (any disposable one works — a local
docker run postgres, an RDS dev instance, etc.) with credentials you're willing to paste into a Daari Secret
-
Confirm your active project (see the namespace gotcha below):
c2a project show
-
Create the Daari Secret holding the Postgres credentials:
c2a daari secrets create pg-hello-creds \ --from-literal POSTGRES_HOST=<host> \ --from-literal POSTGRES_PORT=5432 \ --from-literal POSTGRES_USER=<user> \ --from-literal POSTGRES_PASSWORD=<password> \ --from-literal POSTGRES_DB=<db>
Note the
k8sNameprinted in the output (in parentheses) — that's whatdaari secrets bindtakes as its second argument, not the display name you typed. -
Deploy the app from this directory's git remote (or any fork/mirror of it):
c2a app create pg-hello-py -g <git-url-for-this-repo-or-a-fork>
-
Bind the secret to the app:
c2a daari secrets bind pg-hello-py <k8sName-from-step-2>
This exercises the fixed
appendServiceBindingpath: it writes thepg-hello-py-service-bindingSecret'sC2A_SYSTEM_ENVJSON and additive-patches the ksvc'senvFromto reference it if it isn't already wired in — the part that used to silently no-op for out-of-lifecycle apps (coordinator#187 part A).C2A_SYSTEM_ENVis a single JSON blob (the platform's runtime binding contract — variables / secrets / bindings all serialized together). The platform init step unpacks it into plain env vars beforeapp.pystarts, so this app never parsesC2A_SYSTEM_ENVitself — it just readsPOSTGRES_HOSTetc. fromos.environas shown above. -
Wait for the new revision to become Ready, then verify:
c2a app show pg-hello-py -f url curl "$(c2a app show pg-hello-py -f url)/db-check"Expect
{"ok":true,"dbTimestamp":"...","host":"...","db":"..."}.
c2a daari secrets create uses the CLI's active project's namespace
with no override flag and no warning. If you're not sure which project is
active, secrets can land in the wrong namespace and go undetected until a
bind silently fails to find them. Always run c2a project show first.
See e2e.sh for a fully scripted version of the walkthrough
above (create secret → deploy app → bind → re-bind for idempotency → wait
for Ready → curl /db-check → assert ok:true).