> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# Start & ready commands

> Start template services during build and snapshot them after readiness.

`set_start_cmd()` is a microVM template-build setting. The command runs
during template build before snapshotting. Machines created from the template
restore that snapshotted running state instead of rerunning the command at
machine create time.

Create-time environment variables passed to `Machine.create(envs=...)` are not
visible to the template start command. Use `set_runtime_envs()` for defaults
that should be present in machines launched from the template.

## Start command

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  from nullspace import Template, wait_for_port

  builder = (
      Template()
      .from_python_image("3.12")
      .pip_install(["fastapi", "uvicorn"])
      .copy("./app.py", "/workspace/app.py")
      .set_workdir("/workspace")
      .set_start_cmd(
          "uvicorn app:app --host 0.0.0.0 --port 8080",
          readiness=wait_for_port(8080),
      )
  )
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  // Note: the TypeScript setStartCmd takes only the command. Configure the
  // readiness probe via the Python SDK, CLI, or HTTP API.
  const builder = client.templates
    .builder()
    .fromPythonImage("3.12")
    .pipInstall(["fastapi", "uvicorn"])
    .copy("./app.py", "/workspace/app.py")
    .setWorkdir("/workspace")
    .setStartCmd("uvicorn app:app --host 0.0.0.0 --port 8080");
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build \
    --from-python-image 3.12 \
    --pip-install fastapi,uvicorn \
    --copy-src ./app.py --copy-dst /workspace/app.py \
    --set-workdir /workspace \
    --start-cmd "uvicorn app:app --host 0.0.0.0 --port 8080" \
    --ready-port 8080 \
    --name api-template
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # start_cmd is top-level; the readiness probe lives under runtime_config.
  # COPY needs an uploaded build_context, so the full body is large — see the
  # API reference for the complete CreateTemplateRequest schema.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "api-template",
      "base_image": "python:3.12",
      "steps": [
        {"action": "pip_install", "packages": ["fastapi", "uvicorn"]},
        {"action": "workdir", "path": "/workspace"}
      ],
      "start_cmd": "uvicorn app:app --host 0.0.0.0 --port 8080",
      "runtime_config": {"readiness": {"kind": "tcp", "port": 8080}}
    }'
  ```
</CodeGroup>

See the [API reference](../api-reference) for the full template build request
schema, including `build_context` uploads for COPY steps.

## Readiness helpers

```python theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
from nullspace import (
    wait_for_file,
    wait_for_port,
    wait_for_process,
    wait_for_timeout,
    wait_for_url,
)

wait_for_port(8080)
wait_for_url("http://127.0.0.1:8080/health")
wait_for_file("/tmp/ready")
wait_for_process("server")
wait_for_timeout(5_000)
```

`wait_for_url()` is an in-guest local HTTP probe. It only accepts `http://`
URLs on `localhost`, `127.0.0.1`, or `0.0.0.0`; the URL must include an
explicit port and cannot include query strings, fragments, or embedded
credentials.

## Warm Pools

Template warm pools use this same start-ready snapshot as their startup
contract. Put service boot inputs that must exist before pooling in template
runtime defaults with `set_runtime_envs()`.

Create-time envs, volume mounts, cwd overrides, desktop settings, custom
networking, non-destroy timeout policy, and auto-resume are not visible to the
prewarmed service boot path. Use [Template Warm Pools](./warm-pools) for the
checkout modes and fallback behavior.

## Ready command

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  builder = builder.set_ready_cmd("curl -fsS http://127.0.0.1:8080/health")
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build \
    --from-python-image 3.12 \
    --ready-cmd "curl -fsS http://127.0.0.1:8080/health" \
    --name api-template
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # A command readiness probe is a runtime_config.readiness entry of kind=command.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "api-template",
      "base_image": "python:3.12",
      "runtime_config": {
        "readiness": {"kind": "command", "command": "curl -fsS http://127.0.0.1:8080/health"}
      }
    }'
  ```
</CodeGroup>

## Related

* [Preview URLs](../networking/preview-urls)
* [Template warm pools](./warm-pools)
* [Template build example](../examples/template-build)
