<!-- https://zerolog.ch/docs/container-start · Docs / Compute -->
# Container start

A real percentage while a container starts, and "Running" only when it is ready to use. Both come from measured steps, not from a timer.

- **The steps:** planning the start, bringing the workspace back from network storage (only if it was moved there), checking the image, preparing the network, mounting the workspace, creating the machine, booting it, starting the inner sandbox (only for the VM with gVisor class), checking network access, and a readiness check. The bar shows the step you are in and its percentage.
- **Where the number comes from:** every finished step counts with its weight. The step in progress adds a part of its own weight: bytes unpacked while the workspace comes back, probe attempts during the readiness check, or elapsed time against the usual time for that step. The number never goes past the weight of the current step and never reaches 100 before the container runs.
- **Taking longer than usual:** if a step takes three times its usual time, the number stops and the view says so. It does not creep forward to look busy.
- **Running means ready:** a command runs inside the machine, the sandbox network has a gateway (so the terminal can connect), and, for the VM with gVisor class, the inner sandbox answers. The file list is tried with a short deadline. Only after that does the container show **Running** and 100 %. Until then the terminal answers with "still starting" instead of an error, and the Files view opens when the container runs.
- **If a step fails:** the view names the step and the reason, the container goes back to the state it was in, and **Try again** starts it again. A machine that booted but failed the readiness check is stopped, so it never shows Running next to an error.
- **The agent runtime** (used by Tailscale and by agents in your chats) is its own phase after the start. It is not a condition for Running; opening Tailscale or the terminal waits for the same start instead of building a second one.
- **Measured, not guessed:** each step's duration is stored. The weights start from one cold-start measurement and are pulled from the medians as data comes in.
- **For API clients:** send the header `X-ZL-Start: async` with `POST /api/containers/:id/resume` to get `202` and poll `GET /api/containers/:id/wecken`. The `wecken` object carries `phase`, `phase_label`, `prozent`, `schritt`, `fehler` and `fehler_phase`. Without the header, the call waits and answers `200` as before, and `wecken` is included.

Pausing and storage are described under [Containers](https://zerolog.ch/docs/containers). The Tailscale connection is under [Tailscale in a container](https://zerolog.ch/docs/tailnet).

## From Start to Running

Mermaid source of the diagram on this page:

```mermaid
%% Container start: from the click to Running. Facts from server/containerstart.js (phases, weights), server/sandbox.js (starteLaufzeit, bereitschaft), server/containerzustand.js.
flowchart TB
  a["1. You press Start<br/>state: Starting<br/>0 %"]
  b["2. Plan, image,<br/>network, workspace<br/>real steps, measured"]
  c["3. Machine created<br/>and booted<br/>VM boot is the longest step"]
  d["4. Readiness check<br/>command runs, network gateway,<br/>inner sandbox, file list"]:::hot
  e["5. Running<br/>100 % only now<br/>terminal and files open"]
  f["A step fails:<br/>step and reason shown,<br/>Try again"]
  g["Step 3x slower than usual:<br/>number stops,<br/>view says so"]

  a --> b --> c --> d --> e
  b -->|error| f
  c -->|error| f
  d -->|error, machine stopped| f
  c --> g

  classDef hot stroke:#8f7ac9
```
