| 1 | --- |
| 2 | title: Deployments |
| 3 | description: The fail-closed Compute deployment lifecycle — health-checked promotion, rollback recovery, old-generation cleanup, and env-only redeploys. |
| 4 | --- |
| 5 | |
| 6 | When the artifact or deployment configuration changes, |
| 7 | `Prisma.Compute` creates a new generation and walks it through a |
| 8 | fail-closed sequence: upload the artifact, start the candidate, verify |
| 9 | its preview health endpoint, promote it, confirm the app reports it as |
| 10 | latest, verify the stable endpoint — and only then touch the previous |
| 11 | deployment. |
| 12 | |
| 13 | ## Health checks and promotion |
| 14 | |
| 15 | `healthCheck.path` gates promotion. If the candidate never becomes |
| 16 | healthy, alchemy attempts to destroy it without changing the stable |
| 17 | deployment. When a previous deployment exists, it keeps serving: |
| 18 | |
| 19 | ```typescript |
| 20 | const app = yield* Prisma.Compute("api", { |
| 21 | project, |
| 22 | path: "./app", |
| 23 | port: 3000, |
| 24 | healthCheck: { path: "/api/health" }, |
| 25 | }); |
| 26 | ``` |
| 27 | |
| 28 | When promotion succeeds but the stable endpoint fails verification, |
| 29 | alchemy attempts to restore the previous deployment. If recovery |
| 30 | converges, it cleans up the failed candidate. If recovery cannot |
| 31 | converge—or no safe rollback target exists—alchemy fails the deploy, |
| 32 | preserves the generations needed for recovery, and retries recovery |
| 33 | before making further cloud changes. Terminally failed deployments |
| 34 | are never restarted or selected as rollback targets. |
| 35 | |
| 36 | ## Old-generation cleanup |
| 37 | |
| 38 | By default the previous deployment is kept (stopped) after a |
| 39 | successful promotion. `destroyOldDeployment: true` deletes it once |
| 40 | the replacement is fully promoted and healthy: |
| 41 | |
| 42 | ```typescript |
| 43 | const app = yield* Prisma.Compute("api", { |
| 44 | project, |
| 45 | path: "./app", |
| 46 | destroyOldDeployment: true, |
| 47 | }); |
| 48 | ``` |
| 49 | |
| 50 | If cleanup fails, alchemy records the pending action in state and |
| 51 | retries it before creating another generation. |
| 52 | |
| 53 | ## Env-only redeploys |
| 54 | |
| 55 | `skipCodeUpload: true` creates the next deployment from the currently |
| 56 | promoted artifact. It requires an existing promoted deployment and is |
| 57 | useful when only environment variables changed: |
| 58 | |
| 59 | ```typescript |
| 60 | const app = yield* Prisma.Compute("api", { |
| 61 | project, |
| 62 | skipCodeUpload: true, |
| 63 | env: { FEATURE_FLAG: "on" }, |
| 64 | }); |
| 65 | ``` |
| 66 | |
| 67 | ## Redeploying for changed inputs |
| 68 | |
| 69 | The low-level `Prisma.Deployment` resource owns no environment |
| 70 | variables, so it cannot see an env-value change on its own. Prisma |
| 71 | also snapshots environment variables into a deployment when the |
| 72 | deployment is created, so changing only a value updates the |
| 73 | platform's variable record but never reaches the running app. |
| 74 | |
| 75 | Declare the values the deployment must be recreated for with |
| 76 | `triggers`. When the resolved value changes, the next deploy |
| 77 | replaces the deployment (create-before-delete) even though the |
| 78 | artifact is unchanged: |
| 79 | |
| 80 | ```typescript |
| 81 | const deployment = yield* Prisma.Deployment("web", { |
| 82 | app, |
| 83 | artifactPath: "./dist/app.tar.gz", |
| 84 | triggers: { DATABASE_URL: Redacted.make(databaseUrl) }, |
| 85 | start: true, |
| 86 | promote: true, |
| 87 | }); |
| 88 | ``` |
| 89 | |
| 90 | The values are folded into the deployment fingerprint as a salted |
| 91 | hash and persisted `Redacted`; the plaintext never lands in state. |
| 92 | `Prisma.Compute` needs no equivalent — it owns `env` and already |
| 93 | folds those values into its own fingerprint. |
| 94 | |
| 95 | ## No-op convergence |
| 96 | |
| 97 | Deploys are hash-driven: when the built artifact and configuration |
| 98 | are unchanged, reconcile reuses the same healthy deployment instead |
| 99 | of creating a new generation — repeat deploys converge to exactly |
| 100 | one active deployment. |
| 101 | |
| 102 | ## Where next |
| 103 | |
| 104 | - [Apps](/prisma/compute/apps) — builds, Effect-native services, |
| 105 | and local dev. |
| 106 | |
| 107 | Reference: |
| 108 | |
| 109 | - [Compute API reference](/providers/prisma/compute) |
| 110 | - [Deployment API reference](/providers/prisma/deployment) |