cubeship

Health checks

A path the proxy asks each copy for, to stop sending traffic to a copy that is up and broken. Off by default, on purpose.

Two things stand between a visitor and a broken copy of an app, and they see different failures.

A copy that has gone costs one retry, and needs nothing configured. A container that is not there refuses the connection, so the proxy retries the request on the next copy and the visitor sees nothing. This is attached whenever an app has more than one copy.

A copy that is up and broken needs a health check. It accepts the connection, so no retry fires — only an actual request tells the difference. The health path is that request.

The path

Set it on the app's Network tab, as a path the app answers 2xx on:

/healthz

The proxy asks every copy for it every 10 seconds, with a 5-second timeout, and stops sending traffic to a copy that fails until it answers again.

The timeout is deliberately not tight: a copy taking five seconds to answer is in trouble, one taking a second under load is not, and marking a working container down is the failure that takes a name off the internet rather than the one that degrades it.

Off is the default

A path is something only the app's author knows, and a wrong one does not degrade a name by halves: the proxy marks every copy down at once and the name answers 503. A default of / would be the instance turning working apps off — most answer 404 there. So no check is the default, and turning one on is a deliberate act.

Rules

A leading /, no ? and no #, ordinary URL characters, at most 255 of them. The value is written into the proxy's configuration and a container label, so the grammar is strict.

Before a deployment serves traffic

On the control plane, a deploy uses the configured health path too: it sends an HTTP GET to the new container's application network address and requires a 2xx response. Redirects are failures. The first domain's port is used, then the first published TCP container port if present, otherwise port 8080. With no health path, an app with a published TCP port must accept a TCP connection at the selected port. Otherwise, readiness checks only that the container remains running.

Each HTTP or TCP attempt has a 5-second network timeout. The deploy retries up to 150 times, waiting 2 seconds between attempts, and requires three consecutive successes before switching traffic. Container startup overhead can add to this five-minute window. The last probe error is included when readiness fails.

The daemon stays on its private management network. A temporary restricted helper, using the running daemon's own image, probes from the new app's network namespace and is removed after the attempt. The app image needs no shell, curl or wget. The helper has no Docker socket or host mounts.

A failed rolling deployment removes the candidate and keeps the previous version serving. Apps with volumes or published ports stop the old container first and restart it if the replacement fails, so those deployments have downtime. Workers currently check that their containers remain running; the HTTP/TCP deployment gate described above applies to the control plane.

Proxy health checks continue after deployment. They do not intercept access through the internal address, where there is no proxy in the path.

On this page