Deployments
Every change to an app — a new image, an environment update, a configuration edit, an attachment change — triggers a blue/green redeploy. Each successful redeploy is recorded as an immutable revision in the deployment history. You can list those revisions, inspect their deploy logs, and roll back to any of them.
How blue/green deploys work
When you update an app, the platform:
- Pulls the new image on the existing VM.
- Starts the new container (the "green" color) alongside the currently-serving container (the "blue" color).
- Probes the new container on its
health_check_pathathealth_check_interval_secondsintervals. - Once the container returns
health_check_healthy_thresholdconsecutive2xxresponses withinhealth_check_timeout_seconds, it cuts the Caddy ingress over to the green container. - Stops and removes the previous blue container.
If the new container never becomes healthy within the timeout, the deploy fails at the health-probe step and the blue container keeps serving. The app returns to Running with the previous revision active.
Deployment history
Each revision records the configuration that was deployed: image reference, container port, environment variables, custom domains, and registry username. The registry password is never stored in or returned from a revision.
List revisions newest-first:
curl -u "$USER:$PASS" https://api.foundrydb.com/app-services/{id}/deployments
Example response (truncated):
{
"deployments": [
{
"id": "d1a2b3c4-...",
"image_ref": "ghcr.io/acme/api:1.1.0",
"container_port": 8080,
"env": { "LOG_LEVEL": "debug" },
"reason": "configuration update",
"deploy_logs": [...],
"created_at": "2026-06-20T10:45:00Z"
},
{
"id": "e5f6a7b8-...",
"image_ref": "ghcr.io/acme/api:1.0.0",
"container_port": 8080,
"env": { "LOG_LEVEL": "info" },
"reason": "initial deployment",
"deploy_logs": [...],
"created_at": "2026-06-19T09:00:00Z"
}
]
}
The reason field describes why the revision was created:
| Reason | Trigger |
|---|---|
initial deployment | The app was first provisioned. |
configuration update | PATCH /app-services/{id} changed the image, env, or domains. |
database attachment change | A database or app was attached or detached. |
Deploy logs
Each revision also carries a deploy_logs array: the ordered steps the agent ran to roll out that revision, with each step's status and duration. These are distinct from runtime container logs (the serving container's stdout and stderr). Deploy logs describe what the deploy itself did.
Example:
"deploy_logs": [
{
"step": "start-container-green",
"status": "ok",
"duration_ms": 1840,
"started_at": "2026-06-20T10:45:01Z"
},
{
"step": "health-probe-green",
"status": "ok",
"duration_ms": 920,
"started_at": "2026-06-20T10:45:02Z"
},
{
"step": "point-ingress-green",
"status": "ok",
"duration_ms": 60,
"started_at": "2026-06-20T10:45:03Z"
},
{
"step": "stop-previous-blue",
"status": "ok",
"duration_ms": 410,
"started_at": "2026-06-20T10:45:04Z"
}
]
Each step's status is ok, failed, or info. A failed step carries the error in message and, where available, the container's journal tail in detail.
| Step | What it does |
|---|---|
start-container-green | Pulls the image and starts the new container. |
health-probe-green | Probes the new container on health_check_path until healthy or timed out. |
point-ingress-green | Cuts the Caddy ingress over to the new container. |
stop-previous-blue | Stops and removes the previous container. |
Revisions created before deploy logs were introduced have an empty deploy_logs array.
In the dashboard, the Deployments tab lists revisions with expandable deploy logs for each one.
Rollback
Roll back to any previous revision by its id. The platform re-applies that revision's stored configuration and runs a normal health-gated blue/green redeploy:
curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/{id}/rollback \
-H "Content-Type: application/json" \
-d '{ "deployment_id": "e5f6a7b8-..." }'
A rollback is zero-downtime: the health gate still applies, so a rollback to a broken revision also fails safely and leaves the current container serving.
Because the registry password is never stored in a revision, a rollback reuses the password currently held for the app when the registry_username is unchanged. If the target revision's username differs from the current one, you need to supply the new credentials through a PATCH before rolling back.
In the dashboard, each revision in the Deployments tab has a Restore button.