DocsApplications
Deploy & rollback
What happens when you press Deploy, how to read the logs, health checks and blue/green, and rolling back to a previous version.
- Triggers
- Deploy button, push webhook, auto-update, Rollback
- Runs on
- The host's Docker daemon (or a remote server)
- Guarantee
- A failed build never touches the running container
Life of a deployment
- 01queueddeployment created
- 02buildingclone + build image
- 03pushingpush to registry
- 04startingnew container, wait for healthy
- 05successold container replaced
Any stage can end in failed; a deployment always ends up as success or failed, never stuck in between. Logs for every stage stream to the Deploy tab in realtime.
- A deploy is rejected (409) while another deployment for the same application is still active. A webhook arriving in the meantime gets
busyback and is not queued. - Changing application settings (name, env, domains, resource limits, health check, previews, and so on) while a deploy runs is not lost: the change is saved and takes effect on the next deploy, because the container being created uses the values from when the deploy started. Only the host port and the secret source are rejected (409) while a deploy is active.
- Failing during
buildingorpushingnever touches the currently running container, and doesn't change the application's status. - On a remote server the
pushingstage is skipped — the image stays on that server's daemon.
Deploy mode: container or service
| container (default) | service (Swarm) | |
|---|---|---|
| What gets created | A single container on the app's host/server | A service with N replicas, tasks spread by the scheduler |
| Version changes | Blue/green or replace | Rolling update by the daemon (parallelism, delay, order) |
| Failure | The old container keeps serving | Automatic rollback to the previous spec after a timeout |
| Stop / Start | Container is stopped/started | Scaled to 0 and back to the replica count |
| Metrics | That container | Sum of local tasks only |
Service mode needs Docker Swarm active. Changing mode, replica count, placement, or resource limits runs as a config deployment — no build, and the same deployment queue still applies.
Auto-update (image-based applications)
Applications whose source is an image (not a Git repo) can update themselves: a watcher compares the used tag's manifest digest via the registry API every 60 minutes (configurable per application), and creates an auto-update deployment as soon as the digest changes.
- The baseline comes from the digest recorded at the last pull — not from the tag, so even
latestis detected. - Supports Docker Hub/GHCR (token flow) and your own registry (basic auth via external registry credentials).
- The check now button on the application page forces a check without waiting for the interval.
Realtime logs
| Log | Contents | Source |
|---|---|---|
| Deployment log | Clone, build, push, and start output for one deployment. Kept permanently in history. | Runner → Socket.IO /logs |
| Container log | stdout/stderr of the running application (follow). | docker logs --follow |
Resolved Git tokens and database passwords are automatically redacted from both logs and from error messages. Every container aoox creates uses log rotation (json-file with a size and file-count limit), so container logs never fill up the disk.
Health check
Set a Health check path (e.g. /health) in Settings. The container is created with a Docker HEALTHCHECK that calls 127.0.0.1:<container port><path> every 3 seconds, up to 30 times (± 90 seconds).
GET /health → 200 OK
# no body needed; a fast 2xx status is all that matterswget → curl → node -e fetch → python3. An image with none of these (e.g. scratch, distroless) makes the deployment fail with a message naming it. A container that later becomes unhealthy is automatically dropped by Traefik (404).Blue/green
Kicks in automatically when an application has a domain, no host port, and isn't a preview. The goal: no request ever fails during a version switch.
| Time | Old container | -next container | Notes |
|---|---|---|---|
| 0 s | serving | — | Deploy starts; the new image is already in the registry. |
| +1 s | serving | starting | The <app>-next container is created with the same Traefik labels. |
| +3–90 s | serving | healthy | Traefik starts routing to both once -next is healthy. |
| +3 s | removed | serving | Wait for the proxy to settle, then remove the old one. |
| done | — | → <app> | -next is renamed to the original name. Deployment succeeds. |
| Condition | Behavior |
|---|---|
| Domain, no host port, has a health check | Blue/green as above. |
| Has a host port | Plain replace — two containers can't bind the same port. The health check still decides success/failure. |
| No health check path | Plain replace; the deployment succeeds as soon as the container starts. |
| Failure/timeout during blue/green | -next is removed, the old container keeps serving, the deployment is failed. |
Rollback
Pick a deployment with status success
In the deployment list (Deploy tab), click Rollback on the target version.
A new rollback-type deployment is created
No build/push — the old image is pulled from the registry (or whatever's still on the remote server) and the container is replaced through the same path: health check, blue/green.
- Rollback uses the old image but the current env — handy for fixing a bad env without rebuilding.
- An image tag already deleted from the Registry can't be a rollback target.
Stop & start
The Stop/Start buttons on the Deploy tab stop/run the container without rebuilding. Container-down notifications aren't sent for an intentional stop.
What change triggers what
| What changed | Effect | Needs |
|---|---|---|
| Code in the repo | New image | Deploy (or push + webhook) |
| Image tag changes (image source) | Pull a new image | Automatic if auto-update is on |
| Build args, Dockerfile path, build method | New image | Deploy |
| Environment variables | Applied when the container is created | Deploy or Rollback |
| Domain, mount, resource limit (removed) | Container recreated from the current image | Automatic, no build |
| Deploy mode, replicas, placement | Service updated (rolling) | Config deployment, automatic |
| Resource limit (changed value) | Applied immediately | Nothing |
Next steps
Found a mistake? Edit this page on GitHub ↗