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

# Creación

## Imagen base

Cada plantilla parte de un entorno de origen. El SDK admite varios puntos de entrada según el nivel de control que necesites.

* `fromPythonImage(...)` / `from_python_image(...)` para un runtime estándar de Python
* `fromUbuntuImage(...)` / `from_ubuntu_image(...)` o `fromDebianImage(...)` / `from_debian_image(...)` para una base estándar de Linux
* `fromNodeImage(...)` / `from_node_image(...)` y `fromBunImage(...)` / `from_bun_image(...)` para bases específicas de lenguaje
* `fromImage(...)` / `from_image(...)` para una imagen de contenedor arbitraria
* `fromDockerfile(...)` / `from_dockerfile(...)` cuando tu Dockerfile ya es la fuente de referencia
* `fromBaseImage()` / `from_base_image()` para empezar desde la base predeterminada de la plataforma
* `fromTemplate(...)` / `from_template(...)` para crear una capa sobre otra plantilla

`fromPythonImage("3.12")` y `from_python_image("3.12")` equivalen a empezar desde:

```dockerfile Dockerfile icon="docker" theme={"system"}
FROM python:3.12
```

## Registros privados

Si tu imagen base reside en un registro privado, pasa las credenciales al definir el origen de la plantilla.

Los SDK de JS y Python admiten:

* credenciales genéricas de registro con nombre de usuario y contraseña
* credenciales de registro de AWS
* credenciales de registro de GCP
* credenciales de registro de Huawei Cloud

Ejemplo de registro privado genérico:

<CodeGroup>
  ```ts JavaScript & TypeScript icon="js" theme={"system"}
  import { Template } from "novita-sandbox"

  const template = Template().fromRegistry(
    "registry.example.com/team/myimage:latest",
    {
      username: process.env.REGISTRY_USERNAME,
      password: process.env.REGISTRY_PASSWORD,
    }
  )

  const build = await Template.build(template, "my-private-image-template")
  console.log(build.templateId)
  ```

  ```python Python icon="python" theme={"system"}
  import os

  from novita_sandbox.core import Template

  template = Template().from_registry(
      "registry.example.com/team/myimage:latest",
      username=os.environ.get("REGISTRY_USERNAME"),
      password=os.environ.get("REGISTRY_PASSWORD"),
  )

  build = Template.build(template, "my-private-image-template")
  print(build.template_id)
  ```
</CodeGroup>

## Definición de la plantilla

La API del builder te permite componer el entorno final directamente en código. Los pasos habituales de definición incluyen:

* `runCmd(...)` / `run_cmd(...)` para instalar paquetes o ejecutar comandos de aprovisionamiento
* `copy(...)` para incluir archivos locales
* `makeDir(...)`, `remove(...)`, `rename(...)` y `makeSymlink(...)` para dar forma al sistema de archivos
* `setEnvs(...)` / `set_envs(...)` para variables de entorno
* `pipInstall(...)`, `npmInstall(...)`, `bunInstall(...)` y `aptInstall(...)` para la configuración de paquetes
* `gitClone(...)` / `git_clone(...)` para incorporar código en la imagen

Ejemplo:

<CodeGroup>
  ```ts JavaScript & TypeScript icon="js" theme={"system"}
  import { Template } from "novita-sandbox"

  const template = Template()
    .fromPythonImage("3.12")
    .setWorkdir("/app")
    .setEnvs({
      APP_ENV: "production",
      PORT: "8000",
    })
    .runCmd("pip install fastapi uvicorn")
    .copy("app.py", "/app/app.py")
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.core import Template

  template = (
      Template()
      .from_python_image("3.12")
      .set_workdir("/app")
      .set_envs(
          {
              "APP_ENV": "production",
              "PORT": "8000",
          }
      )
      .run_cmd("pip install fastapi uvicorn")
      .copy("app.py", "/app/app.py")
  )
  ```
</CodeGroup>

## Comandos de inicio y de preparación

Usa un comando de inicio cuando la plantilla deba arrancar un servicio de larga duración durante el resultado de la compilación, y usa un comando de preparación para definir cuándo se considera que ese servicio está en buen estado.

Esto resulta útil para apps web, servidores de API, workers en segundo plano y cualquier plantilla que deba estar ya inicializada cuando se inicia un sandbox.

<CodeGroup>
  ```ts JavaScript & TypeScript icon="js" theme={"system"}
  import { Template } from "novita-sandbox"

  const template = Template()
    .fromPythonImage("3.12")
    .runCmd("pip install fastapi uvicorn")
    .copy("app.py", "/home/user/app.py")
    .setStartCmd(
      "uvicorn app:app --host 0.0.0.0 --port 8000",
      "python - <<'PY'\nimport urllib.request\nurllib.request.urlopen('http://127.0.0.1:8000', timeout=2)\nPY"
    )
  ```

  ```python Python icon="python" theme={"system"}
  from novita_sandbox.core import Template

  template = (
      Template()
      .from_python_image("3.12")
      .run_cmd("pip install fastapi uvicorn")
      .copy("app.py", "/home/user/app.py")
      .set_start_cmd(
          "uvicorn app:app --host 0.0.0.0 --port 8000",
          "python - <<'PY'\nimport urllib.request\nurllib.request.urlopen('http://127.0.0.1:8000', timeout=2)\nPY",
      )
  )
  ```
</CodeGroup>

También puedes configurar la preparación por separado con `setReadyCmd(...)` / `set_ready_cmd(...)`.
