Every deployment in Deploy Your App moves through a well-defined, event-driven pipeline. When you trigger a deploy — either manually from the dashboard or automatically via a GitHub webhook — the platform creates aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/deploy-your-app/llms.txt
Use this file to discover all available pages before exploring further.
Deployment record in PostgreSQL, enqueues a job, and hands off execution to a chain of independent services. Each stage updates the deployment status in the database and publishes log chunks to Redis so the dashboard can reflect progress in real time without polling.
Deployment Status Lifecycle
TheDeploymentStatus enum is defined in packages/database/prisma/schema.prisma and contains the following values:
PENDING
The
Deployment record is created with status PENDING and an initial job is added to the deployment-queue BullMQ queue. The deployment URL and port are both null at this stage.CLONING
The worker picks up the job from
deployment-queue and forwards it to execution-queue. The builder then consumes the job, sets status to CLONING, and runs a shallow git clone --depth 1 of the target branch into a temporary directory under os.tmpdir().BUILDING
Status advances to
BUILDING. The builder allocates a port from the Redis pool, detects the framework and package manager, copies the matching Dockerfile template into the project directory, writes a .env file containing any configured environment variables, and executes docker build. All stdout and stderr output from Docker is published to the live log stream. The overall build timeout is 600 seconds (10 minutes).SUCCESS
After a successful health check (or a completed R2 upload for static sites), the deployment is marked
SUCCESS. The port, url, and completedAt fields are written to the Deployment record. The parent Project row is updated with deploymentUrl and a metadata JSON object containing containerId, imageName, isStatic, and r2Path.DETECTING, ALLOCATING, and DEPLOYING — that are reserved for future use and displayed by the frontend when present. The builder itself transitions directly from CLONING to BUILDING and then to SUCCESS or FAILED.
Two-Stage Queue Architecture
The platform routes deployment jobs through two separate BullMQ queues rather than a single one.apps/api) adds a job to deployment-queue. The worker in apps/worker is the sole consumer of that queue; its only job is to validate the payload and immediately re-enqueue the job on execution-queue. The builder in apps/builder consumes execution-queue and performs all the heavy lifting.
This two-stage design gives you a clean place to add throttling, priority routing, or pre-flight checks without coupling that logic to the build runtime. The worker’s concurrency is fixed at 1 — it dispatches one job at a time — while the builder’s concurrency is configurable via the WORKER_CONCURRENCY environment variable.
All three queue instances (deployment-queue, execution-queue, notification-queue) are exported from @workspace/queue and share the following default job options:
Real-Time Log Streaming
As the builder processes each stage it publishes log chunks to a Redis pub/sub channel namedlogs:{deploymentId}:
docker build, the git clone process, or system status messages (prefixed with [SYSTEM]) is forwarded to the subscriber in real time. Secret values are redacted before publication, so environment variable contents never appear in the streamed output.
Container Health Check
After starting a dynamic container the builder waits 5 seconds (CONTAINER_BOOT_WAIT_MS = 5000) for the process to initialize, then polls http://127.0.0.1:{port} in a loop:
- Maximum attempts: 15
- Interval between attempts: 1 second
- Success condition: any HTTP response with a status code greater than 0
docker logs output and docker inspect state for debugging, removes the container, and returns a failure result that triggers the FAILED status path.
Cleanup Behavior
The builder always performs cleanup in afinally block, ensuring the temporary repository directory is deleted from disk regardless of outcome. On a successful deployment the previous container and image for the same project are also removed:
performFullCleanup is called explicitly in the catch block before the finally cleanup, passing forceRemoveImage: true to ensure the failed image does not consume disk space.
The number of concurrent builds the builder can run in parallel is controlled by the
WORKER_CONCURRENCY environment variable on the apps/builder service. It defaults to 1 if the variable is not set. Increase this value to allow multiple deployments to build simultaneously, keeping in mind that each concurrent build requires its own Docker daemon capacity and an available port in the 5000–5100 range.