This document describes the complete deployment process for publishing task code to production environments. It covers the flow from CLI command execution through deployment initialization, image building, task indexing, and finalization. For local development workflows, see Local Development. For Docker image building details, see Docker Build Pipeline. For registry configuration, see Registry Configuration.
The deployment process handles:
Deployments progress through a well-defined state machine tracked in the WorkerDeployment table.
Status Descriptions:
Sources: internal-packages/database/prisma/schema.prisma665-675 apps/webapp/app/components/runs/v3/DeploymentStatus.tsx52-165
The WorkerDeployment model tracks all deployment metadata and state:
| Field | Type | Purpose |
|---|---|---|
friendlyId | String | User-facing deployment ID (e.g., deployment_xyz) |
shortCode | String | 8-character unique code for URLs |
version | String | Semantic version (e.g., 20250101.1) |
status | WorkerDeploymentStatus | Current state in lifecycle |
contentHash | String | Hash of deployment content for deduplication |
imageReference | String | Full Docker image reference with tag |
imagePlatform | String | Target platform (e.g., linux/amd64) |
externalBuildData | Json | Depot build credentials (buildId, buildToken, projectId) |
buildServerMetadata | Json | Native build server metadata (artifactKey, configFilePath) |
type | WorkerDeploymentType | MANAGED (v4) or V1 (v3) |
startedAt | DateTime | When deployment processing began |
installedAt | DateTime | When dependencies finished installing |
builtAt | DateTime | When image build completed |
deployedAt | DateTime | When deployment finalized |
canceledAt | DateTime | When deployment was canceled |
canceledReason | String | Reason for cancellation |
git | Json | Git metadata (commit, branch, PR info) |
runtime | String | Runtime identifier (node, node-22, bun) |
triggeredVia | String | Deployment trigger source |
Sources: internal-packages/database/prisma/schema.prisma1453-1560
The trigger deploy command orchestrates the entire deployment process from the developer's machine.
Key Command Options:
--env: Target environment (prod, staging, preview)--local-build: Build image locally instead of using Depot--skip-promotion: Skip automatic promotion to current deployment--native-build-server: Use server-side build queue--detach: Return immediately after enqueuing buildSources: packages/cli-v3/src/commands/deploy.ts243-751
Before deployment, the CLI compiles TypeScript task files and generates a manifest:
Sources: packages/cli-v3/src/commands/deploy.ts380-401
The InitializeDeploymentService creates the deployment record and prepares for building.
Initialization Paths:
Traditional CLI Path (isNativeBuild: false):
initialStatus: "BUILDING"Native Build Server Path (isNativeBuild: true):
initialStatus: "PENDING"Sources: apps/webapp/app/v3/services/initializeDeployment.server.ts19-282
The deployment image reference follows a strict naming convention:
{registry-host}/{namespace}/{project-ref}:{version}.{env}.{shortcode}
Example:
123456789012.dkr.ecr.us-east-1.amazonaws.com/trigger/proj_abc123:20250101.1.prod.x7f3m9k2
For ECR registries, the system automatically creates repositories with:
IMMUTABLE_WITH_EXCLUSION (only cache tag is mutable)DEPLOY_REGISTRY_ECR_TAGSSources: apps/webapp/app/v3/getDeploymentImageRef.server.ts103-266
After initialization, the deployment enters the build phase. The process differs between local and remote builds.
Sources: packages/cli-v3/src/deploy/buildImage.ts354-671
Key Environment Variables:
DEPOT_BUILD_ID: Unique build session ID from DepotDEPOT_TOKEN: Build-specific authentication tokenDEPOT_PROJECT_ID: Depot project identifierDEPOT_NO_SUMMARY_LINK: Disable summary outputDEPOT_NO_UPDATE_NOTIFIER: Disable update checksSources: packages/cli-v3/src/deploy/buildImage.ts196-323
After the image is built, the deployment transitions to DEPLOYING and tasks are indexed.
The indexing process runs the worker container with a special --index flag that causes it to register tasks and then exit:
Sources: apps/webapp/app/routes/api.v1.deployments.$deploymentId.deploy.ts apps/webapp/app/v3/services/startDeploymentIndexing.server.ts
The FinalizeDeploymentService completes the deployment and optionally promotes it.
Finalization Steps:
DEPLOYING statusBackgroundWorker with deploymentstatus: "DEPLOYED", deployedAt: new Date()WorkerDeploymentPromotion with label "current"Sources: apps/webapp/app/v3/services/finalizeDeployment.server.ts16-118
For deployments using remote builds, FinalizeDeploymentV2Service handles pushing the image to the registry:
This two-step process (depot pull + depot push) ensures the remotely-built image is pushed to the project's container registry (ECR or other).
Sources: apps/webapp/app/v3/services/finalizeDeploymentV2.server.ts19-224
The native build server provides an alternative deployment path that runs entirely server-side.
Key Differences:
| Aspect | CLI Path | Native Build Server |
|---|---|---|
| Initial Status | BUILDING | PENDING |
| Artifact | Not stored | Uploaded to S3/R2 |
| Build Location | CLI machine or Depot | Build server |
| Dependency Install | CLI machine | Build server |
| Log Streaming | Via --plain flag | Via S2 stream |
--detach | Not applicable | Supported |
The native build server is useful for:
Sources: packages/cli-v3/src/commands/deploy.ts974-1182 apps/webapp/app/v3/services/initializeDeployment.server.ts240-272
Build context is packaged as a compressed tarball and uploaded to object storage:
Sources: packages/cli-v3/src/commands/deploy.ts989-1055 apps/webapp/app/v3/services/artifacts.server.ts
The DeploymentService.progressDeployment() method manages state transitions during native builds.
Progress Flow:
PENDING → INSTALLING: First call from build server
startedAt timestampINSTALLINGDEPLOY_TIMEOUT_MSINSTALLING → BUILDING: Second call after dependency installation
createRemoteImageBuild())externalBuildData (buildId, buildToken, projectId)installedAt timestampBUILDINGDEPLOY_TIMEOUT_MSOnly transitions if current status matches expected status (uses updateMany with status condition to prevent race conditions).
Sources: apps/webapp/app/v3/services/deployment.server.ts38-136 apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts1-60
Promotion makes a deployment the "current" deployment for an environment, making it the active version that receives new task runs.
Promotion Record:
The WorkerDeploymentPromotion table tracks which deployments are "current":
Only one deployment per environment can have label: "current". Promoting a new deployment automatically unpromotes the previous one.
Sources: apps/webapp/app/v3/services/changeCurrentDeployment.server.ts apps/webapp/app/v3/services/finalizeDeployment.server.ts69-78
Deployments can be canceled before they reach a final state.
Cancellation Triggers:
POST /api/v1/deployments/{id}/cancelFinal States (cannot be canceled):
DEPLOYEDFAILEDCANCELEDTIMED_OUTSources: apps/webapp/app/v3/services/deployment.server.ts147-224 apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts1-60
Each deployment has a timeout enforced by TimeoutDeploymentService.
Timeout Configuration:
| Stage | Timeout | Environment Variable |
|---|---|---|
| Queued (PENDING) | 1 hour | DEPLOY_QUEUE_TIMEOUT_MS |
| Installing/Building/Deploying | 30 minutes | DEPLOY_TIMEOUT_MS |
Timeouts are managed via Graphile Worker background jobs and are extended each time the deployment progresses to a new stage.
Sources: apps/webapp/app/v3/services/initializeDeployment.server.ts230-238 apps/webapp/app/v3/services/deployment.server.ts110-124 apps/webapp/app/v3/services/timeoutDeployment.server.ts
Deployment failures are handled by FailDeploymentService.
Error Data Schema:
Error data is stored in WorkerDeployment.errorData as JSON and displayed in the dashboard.
Sources: apps/webapp/app/v3/services/failDeployment.server.ts1-82 packages/cli-v3/src/commands/deploy.ts767-884
Recent deployments (native build server or GitHub App) stream logs via S2.
Event Types:
Events are written as NDJSON to the S2 stream and consumed by the dashboard for real-time log display.
Sources: apps/webapp/app/v3/services/deployment.server.ts333-397 apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts170-188 apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx90-184
| Class | Responsibility | File |
|---|---|---|
InitializeDeploymentService | Create deployment record, generate image reference, optionally enqueue build | apps/webapp/app/v3/services/initializeDeployment.server.ts19-282 |
DeploymentService | Progress deployment through states, cancel deployments, manage credentials | apps/webapp/app/v3/services/deployment.server.ts25-397 |
FinalizeDeploymentService | Complete deployment, link worker, trigger promotion | apps/webapp/app/v3/services/finalizeDeployment.server.ts16-118 |
FinalizeDeploymentV2Service | Handle remote build finalization with registry push | apps/webapp/app/v3/services/finalizeDeploymentV2.server.ts19-224 |
FailDeploymentService | Handle deployment failures, store error data | apps/webapp/app/v3/services/failDeployment.server.ts16-82 |
ChangeCurrentDeploymentService | Promote deployments to "current" | apps/webapp/app/v3/services/changeCurrentDeployment.server.ts |
TimeoutDeploymentService | Manage deployment timeout jobs | apps/webapp/app/v3/services/timeoutDeployment.server.ts |
StartDeploymentIndexingService | Start worker, index tasks | apps/webapp/app/v3/services/startDeploymentIndexing.server.ts |
ArtifactsService | Generate presigned URLs for artifact uploads | apps/webapp/app/v3/services/artifacts.server.ts |
Sources: All listed in table above
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/deployments/initialize | POST | Create deployment record |
/api/v1/deployments/{id}/progress | POST | Transition PENDING→INSTALLING→BUILDING |
/api/v1/deployments/{id}/cancel | POST | Cancel non-final deployment |
/api/v1/deployments/{id}/deploy | POST | Start task indexing (BUILDING→DEPLOYING) |
/api/v2/deployments/{id}/finalize | POST | Complete deployment (DEPLOYING→DEPLOYED) |
/api/v1/deployments/{id}/fail | POST | Mark deployment as failed |
/api/v1/artifacts | POST | Create artifact upload URL |
/api/v1/deployments/{id}/credentials | GET | Generate ECR/registry credentials |
Sources: apps/webapp/app/routes/api.v1.deployments.initialize.ts apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts apps/webapp/app/routes/api.v2.deployments.$deploymentId.finalize.ts apps/webapp/app/routes/api.v1.artifacts.ts
Refresh this wiki
This wiki was recently refreshed. Please wait 6 days to refresh again.