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

# 定义 Template

Template 构建器提供了一套可链式调用的 API,用于定义镜像的构建方式:选择基础镜像、运行命令、复制文件、设置环境变量、安装软件包以及克隆代码仓库。在当前 SDK 形态下,以 `Template` 资源作为主入口。JavaScript 和 TypeScript 中从 `ppio.template.new().fromImage(...)` 等静态方法开始;Python 中同样通过 `ppio.template.new().from_image(...)` 使用同一构建器。

## 私有镜像仓库

若要基于托管在私有或云端镜像仓库中的镜像构建,请在选择基础镜像时传入凭据。通用仓库使用 `fromImage` / `from_image` 并提供用户名和密码;针对 AWS ECR、Google Container Registry、Oracle Cloud(OCI)和华为云 SWR 提供了专用辅助方法。

| 镜像仓库             | 方法(JS / Python)                                          | 凭据                                                           |
| ---------------- | -------------------------------------------------------- | ------------------------------------------------------------ |
| 通用(basic auth)   | `fromImage` / `from_image`                               | `username`、`password`                                        |
| AWS ECR          | `fromAWSRegistry` / `from_aws_registry`                  | `accessKeyId`、`secretAccessKey`、`region`                     |
| Google GCR / GAR | `fromGCPRegistry` / `from_gcp_registry`                  | `serviceAccountJSON`(路径、JSON 字符串或对象)                         |
| Oracle OCI       | `fromOCIRegistry` / `from_oci_registry`                  | `tenancyOcid`、`userOcid`、`fingerprint`、`privateKey`、`region` |
| 华为云 SWR          | `fromHuaweiCloudRegistry` / `from_huawei_cloud_registry` | `accessKeyId`、`secretAccessKey`、`region`                     |

<CodeGroup>
  ```python Python theme={null}
  import os
  from ppio_sandbox import PPIO

  ppio = PPIO()

  # 通用私有镜像仓库（basic auth）
  template = ppio.template.new().from_image(
      "myregistry.com/team/app:latest",
      username=os.environ.get("REGISTRY_USERNAME"),
      password=os.environ.get("REGISTRY_PASSWORD"),
  )

  # AWS ECR
  ppio.template.new().from_aws_registry(
      "123456789.dkr.ecr.us-west-2.amazonaws.com/app:latest",
      access_key_id="AKIA...",
      secret_access_key="...",
      region="us-west-2",
  )
  ```

  ```javascript JavaScript & TypeScript theme={null}
  import { PPIO } from 'ppio-sandbox'

  const ppio = new PPIO()

  // 通用私有镜像仓库（basic auth）
  const template = ppio.template.new().fromImage('myregistry.com/team/app:latest', {
    username: process.env.REGISTRY_USERNAME,
    password: process.env.REGISTRY_PASSWORD,
  })

  // AWS ECR
  ppio.template.new().fromAWSRegistry('123456789.dkr.ecr.us-west-2.amazonaws.com/app:latest', {
    accessKeyId: 'AKIA...',
    secretAccessKey: '...',
    region: 'us-west-2',
  })
  ```
</CodeGroup>

## 运行命令

`runCmd` / `run_cmd` 在构建期间运行 shell 命令。它接受单个命令字符串,或一个命令数组/列表(以 `&&` 连接),还可通过可选的 `user` 指定运行用户。

| 参数                    | 类型                  | 说明                   |
| --------------------- | ------------------- | -------------------- |
| `command`             | string \| string\[] | 单个命令,或以 `&&` 连接的命令列表 |
| `user` / options.user | string(可选)          | 运行命令的用户(如 `root`)    |

<CodeGroup>
  ```python Python theme={null}
  template.run_cmd('apt-get update')
  template.run_cmd(['pip install numpy', 'pip install pandas'])
  template.run_cmd('apt-get install vim', user='root')
  ```

  ```javascript JavaScript & TypeScript theme={null}
  template.runCmd('apt-get update')
  template.runCmd(['pip install numpy', 'pip install pandas'])
  template.runCmd('apt-get install vim', { user: 'root' })
  ```
</CodeGroup>

## 复制文件

`copy` 将本地文件或目录打包进镜像。`src` 可以是单个路径或路径列表;`dest` 是 Template 中的目标路径。可通过选项控制文件归属、权限和上传行为。

| 参数                                     | 类型              | 说明              |
| -------------------------------------- | --------------- | --------------- |
| `src`                                  | path \| path\[] | 源文件或目录路径(可多个)   |
| `dest`                                 | path            | Template 中的目标路径 |
| `forceUpload` / `force_upload`         | boolean(可选)     | 即使文件已缓存也强制上传    |
| `user`                                 | string(可选)      | 被复制文件的所有者       |
| `mode`                                 | number(可选)      | 文件权限,如 `0o755`  |
| `resolveSymlinks` / `resolve_symlinks` | boolean(可选)     | 复制时解析符号链接       |

<CodeGroup>
  ```python Python theme={null}
  template.copy('requirements.txt', '/home/user/')
  template.copy(['app.py', 'config.py'], '/app/', mode=0o755)
  ```

  ```javascript JavaScript & TypeScript theme={null}
  template.copy('requirements.txt', '/home/user/')
  template.copy(['app.ts', 'config.ts'], '/app/', { mode: 0o755 })
  ```
</CodeGroup>

## 设置环境变量

`setEnvs` / `set_envs` 通过键/值映射设置环境变量。

<Warning>
  **重要:** 通过 `setEnvs` / `set_envs` 定义的环境变量**仅在 Template 构建期间可用**,在 Sandbox 运行时不可用。
</Warning>

<CodeGroup>
  ```python Python theme={null}
  template.set_envs({'APP_ENV': 'production', 'PORT': '8000'})
  ```

  ```javascript JavaScript & TypeScript theme={null}
  template.setEnvs({ NODE_ENV: 'production', PORT: '8080' })
  ```
</CodeGroup>

## 软件包安装(pip、npm、bun、apt)

专用辅助方法封装了常见的包管理器。每个方法都接受单个包名或包列表;省略包名时,语言类辅助方法会从当前项目安装(`pip install .` 或 `package.json`)。

| 方法(JS / Python)              | 选项                                                                           | 说明                                                       |
| ---------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
| `pipInstall` / `pip_install` | `g`(默认 **true**)                                                             | 默认全局安装;`g: false` 时使用 `--user` 安装。不传包名 → `pip install .` |
| `npmInstall` / `npm_install` | `g`、`dev`                                                                    | `g` 表示全局安装(`-g`),`dev` 表示开发依赖。不传包名 → 从 package.json 安装   |
| `bunInstall` / `bun_install` | `g`、`dev`                                                                    | 与 npm 相同,但使用 `bun`                                       |
| `aptInstall` / `apt_install` | `noInstallRecommends` / `no_install_recommends`、`fixMissing` / `fix_missing` | 先执行 `apt-get update`,再以 root 身份安装;必须指定软件包                |

<CodeGroup>
  ```python Python theme={null}
  template.pip_install('numpy')
  template.pip_install(['pandas', 'scikit-learn'])
  template.pip_install('numpy', g=False)
  template.pip_install()

  template.npm_install('express')
  template.npm_install('tsx', g=True)
  template.npm_install('typescript', dev=True)

  template.bun_install(['lodash', 'axios'])

  template.apt_install(['git', 'curl', 'wget'])
  template.apt_install(['vim'], no_install_recommends=True)
  ```

  ```javascript JavaScript & TypeScript theme={null}
  template.pipInstall('numpy')
  template.pipInstall(['pandas', 'scikit-learn'])
  template.pipInstall('numpy', { g: false })
  template.pipInstall()

  template.npmInstall('express')
  template.npmInstall('tsx', { g: true })
  template.npmInstall('typescript', { dev: true })

  template.bunInstall(['lodash', 'axios'])

  template.aptInstall(['git', 'curl', 'wget'])
  template.aptInstall(['vim'], { noInstallRecommends: true })
  ```
</CodeGroup>

## Git 克隆

`gitClone` / `git_clone` 将代码仓库克隆到镜像中。仅 URL 为必填;支持可选的目标路径和克隆选项。

| 参数       | 类型         | 说明                            |
| -------- | ---------- | ----------------------------- |
| `url`    | string     | 仓库 URL(必填)                    |
| `path`   | path(可选)   | 克隆的目标路径                       |
| `branch` | string(可选) | 要克隆的分支(会添加 `--single-branch`) |
| `depth`  | number(可选) | 浅克隆深度                         |
| `user`   | string(可选) | 执行克隆的用户                       |

<Note>
  **注意:** `gitClone` / `git_clone` 没有专门的认证参数。对于私有仓库,请在 URL 中嵌入凭据/令牌,或通过前置的 `runCmd` / `setEnvs` 步骤进行配置。
</Note>

<CodeGroup>
  ```python Python theme={null}
  template.git_clone('https://github.com/user/repo.git', '/app/repo')
  template.git_clone(
      'https://github.com/user/repo.git',
      branch='main',
      depth=1,
  )
  template.git_clone('https://github.com/user/repo.git', '/app/repo', user='root')
  ```

  ```javascript JavaScript & TypeScript theme={null}
  template.gitClone('https://github.com/user/repo.git', '/app/repo')
  template.gitClone('https://github.com/user/repo.git', undefined, {
    branch: 'main',
    depth: 1,
  })
  template.gitClone('https://github.com/user/repo.git', '/app/repo', { user: 'root' })
  ```
</CodeGroup>
