Skip to content

Deployments

When the artifact or deployment configuration changes, Prisma.Compute creates a new generation and walks it through a fail-closed sequence: upload the artifact, start the candidate, verify its preview health endpoint, promote it, confirm the app reports it as latest, verify the stable endpoint — and only then touch the previous deployment.

healthCheck.path gates promotion. If the candidate never becomes healthy, alchemy attempts to destroy it without changing the stable deployment. When a previous deployment exists, it keeps serving:

const app = yield* Prisma.Compute("api", {
project,
path: "./app",
port: 3000,
healthCheck: { path: "/api/health" },
});

When promotion succeeds but the stable endpoint fails verification, alchemy attempts to restore the previous deployment. If recovery converges, it cleans up the failed candidate. If recovery cannot converge—or no safe rollback target exists—alchemy fails the deploy, preserves the generations needed for recovery, and retries recovery before making further cloud changes. Terminally failed deployments are never restarted or selected as rollback targets.

By default the previous deployment is kept (stopped) after a successful promotion. destroyOldDeployment: true deletes it once the replacement is fully promoted and healthy:

const app = yield* Prisma.Compute("api", {
project,
path: "./app",
destroyOldDeployment: true,
});

If cleanup fails, alchemy records the pending action in state and retries it before creating another generation.

skipCodeUpload: true creates the next deployment from the currently promoted artifact. It requires an existing promoted deployment and is useful when only environment variables changed:

const app = yield* Prisma.Compute("api", {
project,
skipCodeUpload: true,
env: { FEATURE_FLAG: "on" },
});

The low-level Prisma.Deployment resource owns no environment variables, so it cannot see an env-value change on its own. Prisma also snapshots environment variables into a deployment when the deployment is created, so changing only a value updates the platform’s variable record but never reaches the running app.

Declare the values the deployment must be recreated for with triggers. When the resolved value changes, the next deploy replaces the deployment (create-before-delete) even though the artifact is unchanged:

const deployment = yield* Prisma.Deployment("web", {
app,
artifactPath: "./dist/app.tar.gz",
triggers: { DATABASE_URL: Redacted.make(databaseUrl) },
start: true,
promote: true,
});

The values are folded into the deployment fingerprint as a salted hash and persisted Redacted; the plaintext never lands in state. Prisma.Compute needs no equivalent — it owns env and already folds those values into its own fingerprint.

Deploys are hash-driven: when the built artifact and configuration are unchanged, reconcile reuses the same healthy deployment instead of creating a new generation — repeat deploys converge to exactly one active deployment.

  • Apps — builds, Effect-native services, and local dev.

Reference: