> ## 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.

# Base image

> Start templates from standard images, existing templates, custom images, or Dockerfiles.

## Predefined image helpers

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  Template().from_ubuntu_image("22.04")
  Template().from_debian_image()
  Template().from_python_image("3.12")
  Template().from_node_image("20")
  Template().from_bun_image("1.2")
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  // Note: the TypeScript builder does not expose fromBunImage yet.
  client.templates.builder().fromUbuntuImage("22.04");
  client.templates.builder().fromDebianImage();
  client.templates.builder().fromPythonImage("3.12");
  client.templates.builder().fromNodeImage("20");
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build --from-ubuntu-image 22.04 --name demo
  nullspace template build --from-debian-image --name demo
  nullspace template build --from-python-image 3.12 --name demo
  nullspace template build --from-node-image 20 --name demo
  nullspace template build --from-bun-image 1.2 --name demo
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # Predefined helpers resolve to a base_image OCI ref server-side. Builds stream
  # over SSE — see the API reference for the full request schema.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"name": "demo", "base_image": "python:3.12"}'
  ```
</CodeGroup>

`from_bun_image()` requires an explicit Bun version and maps to
`oven/bun:<version>`.

## Existing templates and custom images

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  Template().from_template("base")
  Template().from_image("registry.example.com/team/app:1.0")
  Template().from_base_image("ubuntu:22.04")
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  client.templates.builder().fromTemplateRef("base");
  client.templates.builder().fromImage("registry.example.com/team/app:1.0");
  client.templates.builder().fromImage("ubuntu:22.04");
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build --from-template base --name demo
  nullspace template build --from-image registry.example.com/team/app:1.0 --name demo
  nullspace template build --from-base-image ubuntu:22.04 --name demo
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # Custom and base images both populate base_image. Builds stream over SSE —
  # see the API reference for the full request schema.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"name": "demo", "base_image": "registry.example.com/team/app:1.0"}'
  ```
</CodeGroup>

## Dockerfile

Build from a Dockerfile on disk:

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  builder = Template().from_dockerfile("./Dockerfile")
  build = Template.build(builder, name="demo-from-dockerfile")
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build --from-dockerfile ./Dockerfile --name demo-from-dockerfile
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # The HTTP API takes inline Dockerfile content via the "dockerfile" field
  # (the SDK/CLI read the file for you). Builds stream over SSE — see the
  # API reference for the full request schema.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"name": "demo-from-dockerfile", "dockerfile": "FROM ubuntu:22.04\nRUN apt-get update && apt-get install -y jq"}'
  ```
</CodeGroup>

<Note>
  The TypeScript SDK builds Dockerfiles from inline content with
  `fromDockerfileContent(...)`; it does not read a Dockerfile path for you.
</Note>

Build from inline Dockerfile content:

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  dockerfile = """
  FROM ubuntu:22.04
  RUN apt-get update && apt-get install -y jq
  """

  builder = Template().from_dockerfile_content(dockerfile)
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  const dockerfile = `FROM ubuntu:22.04
  RUN apt-get update && apt-get install -y jq`;

  const builder = client.templates.builder().fromDockerfileContent(dockerfile);
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # Inline Dockerfile content goes in the "dockerfile" field. Builds stream over
  # SSE — see the API reference for the full request schema.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"name": "demo", "dockerfile": "FROM ubuntu:22.04\nRUN apt-get update && apt-get install -y jq"}'
  ```
</CodeGroup>

Dockerfile builds use BuildKit. BuildKit-backed builds evaluate the Dockerfile,
then import the resulting OCI image into a Nullspace rootfs and snapshot.
`build_backend="native"` remains valid for non-Dockerfile declarative/OCI
requests and historical build filters, but Dockerfile input with the native
backend is rejected.

## Compatibility

BuildKit-backed Dockerfile builds use BuildKit for upstream Dockerfile
evaluation and then retain the resulting OCI runtime metadata during import.

| Feature                              | BuildKit behavior                                                                                                         |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| Multi-stage builds and `COPY --from` | Handled by BuildKit.                                                                                                      |
| Heredocs                             | Supported when the configured BuildKit Dockerfile frontend supports them.                                                 |
| `RUN --mount`                        | BuildKit cache, bind, tmpfs, secret, and SSH mounts require matching Nullspace request support and policy.                |
| Named contexts                       | Require BuildKit build-context support.                                                                                   |
| `.dockerignore` parity               | Uses the uploaded BuildKit context path.                                                                                  |
| `LABEL`                              | Retained as template/build OCI metadata.                                                                                  |
| `EXPOSE`                             | Retained as metadata and UI/API hints; it does not automatically publish a port.                                          |
| `VOLUME`                             | Retained as metadata only; it does not create persistent Nullspace volumes.                                               |
| `HEALTHCHECK`                        | Retained as metadata. Shell/exec healthchecks map to command readiness when safe; unsupported forms remain metadata only. |

Docker's BuildKit and Dockerfile references define the upstream behavior:
[BuildKit](https://docs.docker.com/build/buildkit/),
[Dockerfile reference](https://docs.docker.com/reference/builder), and
[build contexts](https://docs.docker.com/build/building/context/).

### OCI import

When a custom image or external Dockerfile `FROM` imports an OCI image,
Nullspace imports these runtime defaults:

| OCI data               | Import behavior                                                                                                                                                                                |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Env`                  | `KEY=VALUE` entries become runtime env defaults; malformed entries are skipped.                                                                                                                |
| `User`                 | Trimmed non-empty values become the default user. Supported Linux forms include names, numeric ids, and user/group combinations.                                                               |
| `WorkingDir`           | Trimmed non-empty values become the default workdir.                                                                                                                                           |
| `Entrypoint` and `Cmd` | Arrays are concatenated and shell-escaped into one start command.                                                                                                                              |
| Labels                 | Retained as template/build OCI metadata.                                                                                                                                                       |
| Exposed ports          | Retained as metadata and hints; they do not publish traffic by themselves.                                                                                                                     |
| Volumes                | Retained as metadata only; no persistent Nullspace volume is created automatically.                                                                                                            |
| Healthcheck            | Retained as metadata and mapped to command readiness when semantics are safe.                                                                                                                  |
| Layers                 | Raw tar, gzip, Docker tar/gzip, nondistributable variants, and zstd OCI layers are supported.                                                                                                  |
| Filesystem entries     | Regular files, directories, symlinks, hard links, and OCI whiteouts are applied when paths stay inside the rootfs. Mode bits and uid/gid ownership are preserved in the generated ext4 rootfs. |
| Platform               | Linux manifests are selected for the microVM host architecture. Manifests with `os.version` or `os.features` are rejected.                                                                     |

Nullspace does not import stop signal, shell metadata, or arbitrary annotations
into runtime config today. Special files such as sockets, FIFOs, block devices,
character devices, sparse tar entries, and unknown tar entries are rejected.

## Private registries

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  builder = (
      Template()
      .from_image("registry.example.com/team/app:1.0")
      .set_base_image_auth(username="robot", password="token")
  )
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace template build \
    --from-image registry.example.com/team/app:1.0 \
    --registry-username robot \
    --registry-password token \
    --name demo
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  # base_image_auth carries request-time credentials (kind=basic for
  # username/password). Builds stream over SSE — see the API reference.
  curl -N -X POST "${NULLSPACE_API_URL}/v1/templates/build" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "demo",
      "base_image": "registry.example.com/team/app:1.0",
      "base_image_auth": {"kind": "basic", "username": "robot", "password": "token"}
    }'
  ```
</CodeGroup>

<Note>
  The TypeScript SDK does not expose private registry auth yet; use the Python
  SDK, CLI, or HTTP API for authenticated base-image pulls.
</Note>

Helpers also exist for GCP Artifact Registry and AWS ECR.

## Related

* [Build logs](./build-logs)
* [Template kernel selection](../guides/template-kernel-selection)
* [Template build example](../examples/template-build)
