Skip to main content

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:

  1. Pulls the new image on the existing VM.
  2. Starts the new container (the "green" color) alongside the currently-serving container (the "blue" color).
  3. Probes the new container on its health_check_path at health_check_interval_seconds intervals.
  4. Once the container returns health_check_healthy_threshold consecutive 2xx responses within health_check_timeout_seconds, it cuts the Caddy ingress over to the green container.
  5. 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:

ReasonTrigger
initial deploymentThe app was first provisioned.
configuration updatePATCH /app-services/{id} changed the image, env, or domains.
database attachment changeA 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.

StepWhat it does
start-container-greenPulls the image and starts the new container.
health-probe-greenProbes the new container on health_check_path until healthy or timed out.
point-ingress-greenCuts the Caddy ingress over to the new container.
stop-previous-blueStops 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.