Deployments

A deployment runs one image of a service on the environment’s deploy node. up replaces a running container with a new one without dropping traffic: the new container starts, answers its health check, receives the proxy routes, and only then is the container it replaces stopped. If the health check never passes, the new container is removed and the container that was already serving keeps traffic. If a post-deploy command fails after traffic has moved, traffic returns to the previous container.

Local images

A deploy node keeps the images it pulls. A build produces a new image on every deploy, so without cleanup a node accumulates one image per rollout. up retains only the image the active deployment runs:

  • When a rollout succeeds, the image of the deployment it replaced is removed from the node. The replaced image is not needed as a rollback target any more, because rollback always returns traffic to the running active deployment and never starts a container of its own.
  • When a deployment fails, its image is removed together with its container.
  • When a service is removed, every build image it produced is removed from its deploy node. Removing an environment or a project does the same for each of its services.

Image-source services, those declared with source.image, are not affected. Their reference can be shared with other services, so up never removes it. Images that a container is still using are always left in place, so a removal is skipped rather than forced.

Images built before up performed this cleanup, and images whose service was already removed, are not tracked any more. Run up node prune to remove them from a node, or from every node when --node is omitted. It only considers images that belong to a configured registry, it keeps images a container uses and images that an active or in-flight deployment may still need, and it lists what it would remove unless --force is passed.

The control node also runs its own image collection on a fixed 30 minute schedule. For each online node that has the deploy role it removes the same images that up node prune would remove. It skips a node with a deployment in flight and keeps the images an active or in-flight deployment may need, so a rollout in progress is protected. This pass is the backstop for images that the events above miss, such as an image left behind by a deploy that was cancelled or by a control node that restarted in the middle of a cleanup.

Rollback never restores an image that up has removed. A rollback re-pulls the older image when it is not present on the node. The progress of the scheduled pass is reported on GET /api/v1/health under image_gc.

Leftover containers

up keeps only the containers that are still in use: the active deployment, any in-flight rollout, and a deployment whose rollback failed. Every other container of a known deployment is removed, both right after a successful deploy and by the control node’s reconcile pass, which runs at startup and on an interval. Named volumes are never removed, so data survives.

The sweep only removes containers that belong to a deployment the control node recorded. Containers that are not deployments, such as the node proxy, a deploy-hook container, or a one-shot health-check container, are never removed. The node also leaves its ephemeral health-check containers out of the container list it reports, so the sweep cannot mistake one for a deployment.

up service deployments lists a service’s deployments and each deployment’s live container state. A non-active row whose container still runs is a leftover; the next reconcile pass removes it. The state reads unknown when the deploy node cannot be reached.

Cancelled deployments

A deployment runs on the control node, not in the CLI. When you stop up apply or up service deploy with Ctrl+C, or the connection drops, the deployments that already started continue to their end. The CLI says so before it exits. An interrupted up apply does not start its remaining steps, so run it again to finish the rest.

A deployment is cancelled in these cases:

  • A service, environment, or project is removed with --force, or a service is stopped while it deploys.
  • A pull request closes while its preview deploys.
  • A new commit arrives on a pull request while its preview deploys.

A cancel stops the work on the node. A build stops on the build node. A rollout is rolled back, so the previous deployment keeps its traffic. The deployment then ends with the status canceled. A removal waits until the cancel is complete, up to one minute, so no container of a removed service starts after the removal. A cancel that arrives after the rollout succeeded leaves it succeeded.

If the control node loses track of a deployment, for example after a crash during a rollout, its reconcile pass finds the deployment within a few minutes. The pass rolls it back on the node and marks it failed.