Docs Build and deploy
Deploying
A deployment builds a service from its source, starts the new version, waits until it is healthy and then moves traffic to it. This page covers where code comes from, how it is built and how it is rolled out.
Sources
GitHub repositories
A service can deploy a repository given as owner/name, an https:// URL or a git@ URL. Settings for the source are under Settings → Source:
- Branch: the branch to deploy. Empty means the repository’s default branch.
- Root directory: the folder to build, for monorepos. Dawnrose builds from this folder and reads
dawnrose.jsonfrom it. - Auto-deploy: deploy on every push to the branch. On by default.
To deploy private repositories, connect GitHub under Account, under Connected accounts. Dawnrose clones with the GitHub token of the person who started the deploy, or of another workspace member who connected GitHub. When you create a service from a GitHub repository with GitHub connected, Dawnrose tries to add a webhook to the repository for push and pull request events, using your GitHub access. Auto-deploys and pull request environments depend on it.
Docker images
Choose Create → Docker image and enter an image such as nginx:alpine or ghcr.io/owner/app:latest. Deploying pulls the image again, so a moving tag such as latest picks up the newest push.
For a private registry, set registryUsername and registryPassword on the service source through the REST API:
curl -X PATCH https://app.dawnrose.ai/api/services/SERVICE_ID \
-H "Authorization: Bearer drt_…" -H "Content-Type: application/json" \
-d '{"source": {"registryUsername": "bot", "registryPassword": "…"}}'
The dashboard shows the Registry username field under Settings → Source. Images named dawnrose/… are reserved for platform builds.
Uploaded files
Run dawn up to upload the current folder (see dawn CLI), or let your agent send files with the deploy_files tool (up to 20 MB in total). A service deployed from uploads keeps its latest upload: deploying it again with dawn deploy or your agent redeploys the latest build. One-file functions are a special case of uploads; see Functions, buckets and sandboxes.
Builds
Pick the builder under Settings → Build or in dawnrose.json. With Auto-detect (the default), Dawnrose uses your Dockerfile if the source has one. Otherwise it detects the language and writes a Dockerfile for you, which it prints in the build log.
Zero-config detection
Detection checks the root directory in this order and uses the first match:
| Found | Detected as | Base image |
|---|---|---|
package.json | Node.js | node:<major>-slim, the major version from engines.node, else 22 |
requirements.txt, pyproject.toml or Pipfile | Python | python:3.12-slim |
go.mod | Go | golang:<version from go.mod> (else 1.23) to build, debian:bookworm-slim to run |
index.html at the root, or in public/, dist/, build/ or site/ | Static site | nginx:alpine, port 80 |
If nothing matches, the build fails and the log lists the files it found.
Node.js. The package manager is pnpm if there is a pnpm-lock.yaml or packageManager names pnpm, Yarn for yarn.lock or a Yarn packageManager, and npm otherwise. npm runs npm ci when there is a package-lock.json and npm install when there is not. If scripts.build exists, it runs. The start command is the first of: your start command, the web: line of a Procfile, scripts.start, or node with the first file that exists of main, server.js, index.js, app.js and main.js. A project with none of these, a build script and a dependency on Vite, Create React App, Angular CLI or Astro is built and served as a static site by nginx on port 80.
Python. Dependencies install with pip install -r requirements.txt, or pip install . without one. The start command is the first of: your start command, the web: line of a Procfile, gunicorn <project>.wsgi for Django, uvicorn <module>:app for FastAPI with uvicorn, gunicorn <module>:app for Flask with gunicorn, or python with the first of main.py, app.py, server.py and wsgi.py. The generated Django, FastAPI and Flask commands listen on 0.0.0.0:$PORT.
Go. The build runs CGO_ENABLED=0 go build -o /out/app . unless you set a build command, and the binary runs as /app/app.
Builders and build settings
- Dockerfile builds
Dockerfilein the root directory, or the path in Dockerfile path. The path must stay inside the source. - Nixpacks isn’t available: a build with it fails with a message saying to switch to Auto-detect or add a Dockerfile.
- Install command and Build command replace the detected ones. They apply to Auto-detect.
- Disable build cache builds without cached layers.
If the source has no .dockerignore, Dawnrose adds one that excludes .git and node_modules. The service’s resolved variables are passed to Docker builds as build arguments; a Dockerfile can read one by declaring it with ARG. Each workspace builds in its own builder with its own cache.
Ports and $PORT
Dawnrose routes traffic to one port per service. It uses the first of these that is set:
- Target port under Settings → Networking, or
portindawnrose.json. - A
PORTvariable you set on the service. - Port 80 for static sites built by zero-config detection.
- The lowest port the image declares with
EXPOSE. - 8080.
Unless you set PORT yourself, Dawnrose sets it to that port. Your app should listen on 0.0.0.0 and the port in $PORT.
Healthchecks
Set Healthcheck path (it must start with /) to have Dawnrose send GET requests to each new replica on its port until it returns a 2xx status. The deployment fails if that does not happen within Healthcheck timeout (default 300 seconds, and at most 2 minutes on Trial, 10 on Hobby and 30 on Pro). Healthcheck requests come from the private network with the user agent Dawnrose-Healthcheck, addressed to the replica’s IP address. If your app only accepts requests for known hostnames, let the healthcheck path through for any host.
Without a healthcheck, each replica must keep running for 3 seconds. Then, if the service gets traffic (it has a domain or a TCP proxy, or its previous deployment accepted connections), Dawnrose waits for the app to accept connections on its port. If it doesn’t within Healthcheck timeout, the deployment fails and traffic stays on the previous version. A worker that nothing sends traffic to doesn’t need to listen: Dawnrose waits up to 30 seconds for the port and only logs a warning.
A replica that exits or restarts during the rollout fails the deployment, and the last log lines appear in the deploy log.
Rollouts without downtime
New replicas start next to the running ones. Traffic moves to the new version only once every new replica is healthy. If the deployment fails, the previous version keeps serving.
- Overlap (s) keeps the old version running this long after the new one is live, up to 1 minute on Trial, 2 on Hobby and 10 on Pro. Default 0.
- Draining (s) is the time between SIGTERM and SIGKILL when old replicas stop. Default 10.
- Pre-deploy command runs once in a separate container from the new image, with the service’s variables but without its volume, before the new version takes traffic. Use it for migrations. A non-zero exit or a run longer than one hour fails the deployment.
A service with a volume is the exception: the old deployment stops before the new one starts, so there is a short gap. If the new deployment fails, the old one is started again.
Only one deployment per service runs at a time. Queuing a new deployment marks older queued ones as skipped.
Replicas and resources
Replicas sets how many copies run. Requests are spread across them in turn, and each replica gets its own DAWNROSE_REPLICA_ID. Services with a volume run one replica. CPU limit (vCPU) and Memory limit (MB) apply per replica. The plan limits are listed in Scaling and plan limits.
Start command
Start command replaces the image’s entrypoint and runs through sh -c, so $VARIABLES expand.
Automatic rollback
A deployment can pass every check and still crash a few minutes later. If a new deployment keeps crashing in its first 10 minutes, Dawnrose rolls back to the deployment it replaced. That happens when every replica exits with an error, or when replicas crash and are restarted 3 times. The rollback restores that deployment’s image, settings and variables and deploys it, the same as Rollback to this.
- The crashed deployment shows why it was rolled back, the activity log records it, and a
deploy.failednotification goes out. - Rollbacks are never rolled back themselves, so a bad previous version can’t cause a loop.
- Cron services and a service’s first deployment have nothing to roll back to.
- Turn it off per service with Automatic rollback under Settings → Deploy,
auto_rollback: falsein the agent’supdate_service, or"autoRollback": falseunderdeployindawnrose.json.
Rolling back doesn’t undo database migrations. If the new version changed the schema in a way the old version can’t read, turn automatic rollback off for that service or keep migrations backward compatible.
Restart policies and crashes
Restart policy decides what happens when a replica exits:
- On failure (default): restart after a non-zero exit, up to the max retries (default 10).
- Always: always restart.
- Never: leave it stopped.
When a replica is restarted, the workspace gets a service.restarted notification, at most once every 10 minutes per service. When every replica has exited and the policy stops restarting them, the deployment becomes Crashed, traffic stops and a service.crashed notification goes out, unless an automatic rollback takes over.
Sleeping idle services
Sleep after idle (s) stops a service after that many seconds without traffic. The next request wakes it: the edge holds the request while the replicas start and pass the healthcheck. A sleeping service has no running containers, so it uses no CPU or memory.
Cron services
Set Cron schedule to a 5-field crontab expression in UTC, such as */15 * * * *, to run the service on a schedule instead of continuously. The deployment builds the image but starts no long-running replicas. Each run starts a fresh container from the deployed image with the service’s variables.
- The Cron tab shows the next run, past runs with their exit codes, and a Run now button.
- A run that is still going when the next one is due makes the next one skip.
- Runs time out after 15 minutes on Trial, 1 hour on Hobby and 6 hours on Pro. A failed or timed-out run sends a
service.crashednotification.
What starts a deploy
- The Deploy button in the service panel (or
D), the agent’sdeploytool, ordawn deploy. - A push to the deployed branch, when Auto-deploy is on.
- The pending changes banner on the canvas, which deploys every service whose settings or variables changed. See Environments.
- The service’s deploy hook: a URL under Settings → Deploy hook. A
POSTto it starts a deployment, for example from CI. Viewers cannot see this URL.
curl -X POST "$DEPLOY_HOOK_URL"
Watch paths under Settings → Build take glob patterns, one per line, such as /apps/api/**. A push deploys only if it changes a matching file. Without watch paths but with a root directory, a push deploys only if it changes a file under that directory.
Redeploy, roll back, cancel and stop
The Deployments tab lists a service’s deployments. Each service keeps its newest 100 deployments, and a workspace has room for 32 MB of deployment records, variables and activity on Trial, 256 MB on Hobby and 1 GB on Pro. Past either, the oldest finished deployments are removed, which can take old rollback targets with them. Build and deploy logs are kept for 7 days on Trial, 14 on Hobby and 30 on Pro, up to 0.5 GB, 5 GB and 20 GB in total. Images beyond what’s running may take 6 GB, 30 GB and 100 GB on each server, and old rollback targets give way first. The activity log keeps 14 days on Trial, 30 on Hobby and 90 on Pro, up to 4 MB, 16 MB and 64 MB. A running deployment always stays. Each deployment’s menu has:
- Redeploy: run that deployment’s image again with the current variables and settings, without rebuilding. A deployment that never built an image is rebuilt from the same commit.
- Rollback to this: restore the image, settings and variables of that deployment, then deploy it. Available for earlier deployments that built an image.
- Cancel: stop a deployment that is queued, building or rolling out.
- Stop: remove a running deployment’s containers. The service goes offline until you deploy or redeploy it.
Restart in the service panel menu restarts the running replicas without a new deployment. The same actions exist as agent tools and as dawn redeploy, dawn rollback, dawn restart and dawn down.