Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.slipway.sh/llms.txt

Use this file to discover all available pages before exploring further.

Every slipway deployment runs through the same state machine. One goroutine in the master orchestrates it from creation to terminal state.

Phases

queued     → orchestration goroutine picked up the deployment.
building   → at least one service has a `build:` block. slipway submits BuildKit
             Jobs in the `slipway-system` namespace, one per buildable service,
             and streams their stdout into the deployment's log buffer.
deploying  → all images are ready. slipway ensures the tenant namespace,
             applies a Deployment + Service (and Ingress for public ports) per
             service, and waits for readiness.
healthy    → every public service is Ready, the Ingress(es) are live, and
             public URLs are persisted on the deployment.
After healthy, three terminal states are possible:
StatusWhen it happens
supersededA newer healthy deployment for the same branch took over. Also set when an ephemeral deployment’s TTL expires.
cancelledYou hit cancel from the UI, or a new commit arrived for the same branch/PR while this deploy was in flight.
failedSomething went wrong — build error, image pull error, healthcheck failure, missing secret. The reason is in failure_reason.

Build caching

Builds are content-addressed. The image tag is <commit-prefix>-<hash> where the hash is over the build inputs: context, dockerfile, sorted args. If a previous deploy on the same commit produced the same inputs, slipway skips the build and reuses the cached image. You’ll see a build_end event with reused cached image …. This is what makes “open a PR and immediately push a typo fix” cheap — the second deploy doesn’t rebuild if your code changed in a way that doesn’t touch build inputs.

Cutover

For public services, slipway:
  1. Waits for the new pod to reach Ready.
  2. Applies the per-service Ingress with the public hostname.
  3. Emits a cutover event with the full URL.
For PR previews, the public hostname (web-pr-<n>.<apps>) is stable across commits. When supersession swaps tenants, nginx-ingress hands the hostname over to the new tenant namespace, so reviewers’ bookmarks and the GitHub PR comment URLs never need updating.

Garbage collection

Three GC paths:
  • PR closed. slipway receives the GitHub pull_request.closed webhook and cancels every deployment associated with that PR, terminal or in-flight. Each one’s tenant namespace is deleted.
  • Branch superseded. When a newer deploy for the same branch reaches healthy, prior healthy deployments for that branch flip to superseded. (Their namespaces stay alive until the build registry’s Job TTL reaps the build artifacts — the deployment row is preserved for history.)
  • Ephemeral TTL. Manual deploys with a TTL get a scheduleTeardown timer set when status flips to healthy. When the timer fires, the tenant namespace is deleted and status flips to superseded. A gc event records the reason.

Cancellation

You can cancel any non-terminal deployment from the UI. slipway:
  1. Flips the status to cancelled and writes a cancelled event.
  2. Cancels the orchestration goroutine’s context, which unblocks anything waiting on a build Job or readiness check.
  3. Asynchronously deletes the tenant namespace (if it was created) and the build Job (if it was submitted).
Cancellation is best-effort cleanup — there’s no harm in cancelling a deploy that was already failing.

Reaping abandoned deployments

If the slipway master is restarted while a deployment is in flight, the orchestration goroutine dies with it. On startup, slipway scans for deployments in non-terminal states (queued, building, deploying) that no longer have an in-process orchestrator and marks them failed with reason abandoned: master restarted while this deployment was in flight. Ephemeral deployments that had reached healthy before the restart have their teardown timers resumed.