---
url: /zh/build/build-env.md
---
## 概述

构建环境定义了流水线任务（Job）的运行环境，其中包含执行构建所需的全部软件和工具，例如特定版本的 JDK、Node.js、Python 等。

`云原生构建` 采用 Docker 容器作为构建环境的运行时。相比于传统虚拟机，Docker 容器具有启动速度快、资源开销低、环境一致性高等巨大优势，已成为现代 CI/CD 领域的行业标准。

::: tip 提示
拥有基础的 Docker 知识将有助于您更深入地理解和使用 `云原生构建`。
:::

## 配置方式

您可以通过以下两种方式为流水线配置构建环境：

| 配置方式 | 说明 | 适用场景 | 权限要求 |
|---------|------|---------|---------|
| [使用现有镜像 (`image`)](#示例-1使用现成镜像-image) | 直接使用已构建并推送至镜像仓库的现成镜像 | 使用官方镜像或团队内部预置的公共工具镜像 | 私有镜像需配置镜像仓库认证信息 |
| [动态构建镜像 (`build`)](#示例-2使用-dockerfile-构建镜像-build) | 指定项目中的 Dockerfile 文件，动态构建镜像 | 需要高度自定义环境、安装特定依赖或工具的复杂项目 | 无特殊要求 |

### 使用现有镜像 (image)

直接使用一个已构建并推送至镜像仓库（如 Docker Hub、私有仓库）的现成镜像。这是最快速的方式。

**语法参考**: [`pipeline.docker.image`](./grammar.md#pipeline-image)

### 动态构建镜像 (build)

指定一个项目中的 `Dockerfile` 文件。在构建开始时，系统会依据该文件动态构建一个镜像并用于后续流程。

**工作机制**:

1. 系统先计算镜像的版本号哈希值
2. 若本地缓存或远端仓库中已存在该镜像，则直接使用，极大加速构建过程
3. 否则，会执行 `docker build` 构建镜像，并自动推送至流水线项目所属的制品库，供后续构建复用

**语法参考**: [`pipeline.docker.build`](./grammar.md#pipeline-build)

### 环境作用范围

流水线级别声明的构建环境将作为其下所有**脚本任务**的默认运行环境。

此外，每个**脚本任务**可以单独覆盖并指定其专属的 `image` 环境。

::: warning 注意
任务级仅支持 `image` 配置，不支持 `dockerfile`。
:::

**语法参考**: [脚本任务](./grammar.md#job-script-task)

## 示例说明

### 示例 1：使用现成镜像 (image)

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        # 声明流水线默认使用 Node.js 22 的官方镜像作为构建环境
        image: node:22
      stages:
        # 下面的脚本任务将在 node:22 环境中运行
        - node -v # 输出：v22.x.x
```

### 示例 2：使用 Dockerfile 构建镜像 (build)

**步骤 1**: 创建 Dockerfile 文件

```dockerfile title="image/Dockerfile"
# 基于 Node.js 20 构建自定义环境
FROM node:20
# 可以在此安装更多项目特定的全局依赖
# RUN npm install -g yarn
```

**步骤 2**: 配置流水线使用该 Dockerfile

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        # 声明使用项目中的 Dockerfile 来构建环境镜像
        build: image/Dockerfile
      stages:
        # 下面的脚本任务将在自定义构建的环境中运行
        - node -v # 输出：v20.x.x
```

### 示例 3：任务级别覆盖构建环境

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        # 流水线默认环境
        image: node:22
      stages:
        - node -v # 输出：v22.x.x (使用默认环境)
        - name: 使用特定镜像版本的任务
          image: node:20 # 此任务覆盖并使用 Node.js 20
          script:
            - node -v # 输出：v20.x.x
```

### 示例 4：使用缺省镜像

当流水线未显式指定任何 `image` 或 `build` 配置时，系统会自动使用一个缺省镜像，确保基础环境可用。

**缺省镜像配置**:

| 构建类型 | 缺省镜像变量 |
|---------|-------------|
| 云原生构建 | `cnbcool/default-build-env` |
| 云原生开发 | `cnbcool/default-dev-env` |

**云原生构建示例**:

```yaml title=".cnb.yml"
main:
  push:
    - stages:
        - stage1
        - stage2
# 上述配置等价于：
# docker:
#   image: cnbcool/default-build-env
```

**云原生开发示例**:

```yaml title=".cnb.yml"
main:
  vscode:
    - services:
        - vscode
      stages:
        - stage1
        - stage2
# 云原生开发未指定环境时，等价于：
# docker:
#   image: cnbcool/default-dev-env
```

## Volume 共享

如果您的自定义镜像通过 `VOLUME` 指令声明了数据卷（例如 `VOLUME /cache`），这些卷会被自动共享给后续由**插件任务**启动的容器。

### 应用场景示例

**步骤 1**: 在 Dockerfile 中准备共享数据

```dockerfile
FROM alpine
RUN mkdir /cache && echo 'Initial data' > /cache/data.txt
VOLUME /cache # 声明 /cache 为数据卷
```

**步骤 2**: 在后续任务中访问共享数据

```yaml
- name: 读取共享卷中的数据
  image: alpine # 使用其他镜像的任务
  script:
    - cat /cache/data.txt # 成功输出: Initial data
```

::: tip 提示
Volume 共享机制允许不同镜像的任务之间共享数据，非常适合缓存依赖、共享构建产物等场景。
:::
