# Runbook: Deploy — 0pt > Status 2026-11-02: **live on the SIAX fleet (Coolify)** at `https://0pt.app`. > The automatic chain and the manual path are both verified: a signed image is > attested, Coolify is called, the container restarts on the new commit, and > `/api/version` reports it. ## Pipeline (automatic) ``` git push main ├─ ci.yml quality (typecheck, contrast, tests, build) │ integration (live OpenSearch + ClickHouse) │ security (Trivy, blocking) ├─ security.yml push/PR/weekly scan ├─ release.yml build + SBOM + blocking vuln scan + cosign attest + push │ → git.cloud.siax.io/sax3l/0pt:sha-<12> └─ cd.yml waits for THIS commit's attestation, verifies it against cosign.pub, then POSTs to Coolify prod-smoke.yml every 30 min: ready + db/stripe + running commit == main ``` - One run per ref (`concurrency`); `push` is main-only, PRs are covered by the `pull_request` event. Deploys have their own non-cancelling group so two runs never race the same app. - Dependency caches: pnpm store (Node jobs), npm (doc0/n0d), pip (0pt-motor). ## Manual deploy (proven) Trigger the same, signed path — do not POST to Coolify directly unless the pipeline itself is broken: ```bash curl -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \ -d '{"ref":"main"}' \ https://git.siax.io/api/v1/repos/admin/0pt/actions/workflows/cd.yml/dispatches ``` Emergency only (bypasses the attestation gate; still builds the branch head): ```bash curl -X POST -H "Authorization: Bearer $COOLIFY_API_TOKEN" -H "Content-Type: application/json" \ -d '{"uuid":""}' https://cloud.siax.io/api/v1/deploy ``` ## Verify a deploy ```bash curl -s https://0pt.app/api/ready # {"ready":true,"db":"ok","stripe":"ok",...} curl -s https://0pt.app/api/health # liveness envelope curl -s https://0pt.app/api/version # {"commit":""} ``` `commit` must equal the current `main` SHA. `prod-smoke.yml` enforces exactly that every 30 minutes; a green deploy is never confused with a current service. ## Rollback Coolify builds from the branch head, so a rollback is a normal revert: ```bash git revert --no-edit && git push origin main ``` That runs the same chain and deploys the reverted tree. Coolify's own "redeploy previous deployment" is the break-glass alternative. ## Configuration (names only — values live in Coolify/Infisical) - Coolify app: `dockerfile` build pack, repo `git.siax.io/sax3l/0pt`, branch `main`, health check `/api/health`, domains `0pt.app` + `api.0pt.app`. - Repository variable: `COOLIFY_APP_ID`. - Repository secrets: `COOLIFY_TOKEN`, `REGISTRY_USER`, `REGISTRY_TOKEN`, `COSIGN_PRIVATE_KEY`, `COSIGN_PASSWORD`, `SIAX_CI_TOKEN`. - App env: `DATABASE_URL`, `STRIPE_SECRET_KEY`, `AUTH_SECRET`… see `.env.example` for the full, documented list (DOC0, INF0/decision Ollama, OpenFGA/project grants, model policy, credit price book, OIDC). ## Known limitation Coolify rebuilds from source; `/api/v1/deploy` has no digest parameter, so the verified digest is recorded as provenance for the deploy rather than pinned as the running bytes. True digest pinning would require a Coolify `dockerimage` resource — an infrastructure decision, not a CI-YAML change.