---
url: /en/build/build-env.md
description: >
  Explains how to configure the Docker-based build environment for Cloud Native
  Build pipelines, covering how to use existing images or build images
  dynamically from a Dockerfile.
---
## Overview

The build environment defines the runtime environment for pipeline jobs,
containing all the software and tools required for execution, such as JDK, Node.js, Python, and other specific versions.

`Cloud Native Build` uses Docker containers as the build runtime. Compared to traditional virtual machines,
Docker containers offer faster startup, lower resource overhead, and better environment consistency,
making them the standard choice in the CI/CD industry.

::: tip
Having a basic understanding of Docker will help you better comprehend and utilize `Cloud Native Build`.
:::

## Configuration Methods

You can configure the build environment in the following two ways:

* **[Use Existing Image (`image`)](#example-1-using-existing-image-image)**: Directly use a pre-built image
  that has been pushed to a container registry. Suitable for using official images or
  team-internal pre-configured public tool images. Private images require registry authentication configuration.
* **[Build Image Dynamically (`build`)](#example-2-building-image-with-dockerfile-build)**: Specify a Dockerfile
  in the project to dynamically build an image. Suitable for complex projects requiring highly customized
  environments, specific dependencies, or tools. No special permission requirements.

### Use Existing Image (image)

Directly use a pre-built image pushed to a container registry, which is the quickest method.

**Syntax Reference**: [`pipeline.docker.image`](./grammar.md#pipeline-image)

### Build Image Dynamically (build)

Specify a `Dockerfile` in the project to dynamically build an image at the start of the build,
and use it for subsequent pipeline stages.

**Mechanism**:

1. The system calculates a hash for the image version
2. If the image exists in the local cache or remote registry, it is used directly to speed up the build
3. Otherwise, `docker build` is executed to create the image,
   which is automatically pushed to the project's artifact registry for reuse by subsequent builds

**Syntax Reference**: [`pipeline.docker.build`](./grammar.md#pipeline-build)

### Environment Scope

The build environment declared at the pipeline level serves as the default runtime environment for all **script
tasks**. Each **script task** can also specify its own `image` environment.

::: warning
Task-level configuration only supports `image`, not `dockerfile`.
:::

**Syntax Reference**: [Script Task](./grammar.md#job-script-task) |
[Script Tasks vs Plugin Tasks](./script-vs-plugin.md)

## Examples

### Example 1: Using Existing Image (image)

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: node:22
      stages:
        - node -v
```

### Example 2: Building Image with Dockerfile (build)

**Step 1**: Create a Dockerfile

```dockerfile title="image/Dockerfile"
FROM node:20
```

**Step 2**: Configure the pipeline to use this Dockerfile

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        build: image/Dockerfile
      stages:
        - node -v
```

### Example 3: Job-Level Override + Default Image

```yaml title=".cnb.yml"
main:
  push:
    - docker:
        image: node:22
      stages:
        - node -v
        - name: Using a specific image version
          image: node:20
          script:
            - node -v
```

### Example 4: Using Default Images

When a pipeline does not explicitly specify an `image` or `build` configuration,
the system automatically uses a default image to ensure a basic environment is available.

| Build Type               | Default Image Variable                |
| ------------------------ | ------------------------------------- |
| Cloud Native Build       | `cnbcool/default-build-env`     |
| Cloud Native Development | `cnbcool/default-dev-env` |

```yaml title=".cnb.yml"
main:
  push:
    - stages:
        - stage1
        - stage2
# Without explicit environment, equivalent to using cnbcool/default-build-env
```

Cloud native development works similarly — the default dev image is used when no image is declared:

```yaml title=".cnb.yml"
$:
  vscode:
    - services:
        - vscode
      stages:
        - stage1
# Without explicit environment, equivalent to using cnbcool/default-dev-env
```

## Volume Sharing

If your custom image declares data volumes using the `VOLUME` instruction (e.g., `VOLUME /cache`),
these volumes are automatically shared with containers started by subsequent **plugin tasks**.

### Application Example

**Step 1**: Prepare shared data in the Dockerfile

```dockerfile
FROM alpine
RUN mkdir /cache && echo 'Initial data' > /cache/data.txt
VOLUME /cache
```

**Step 2**: Access the shared data in a subsequent task

```yaml
- name: Read data from the shared volume
  image: alpine
  script:
    - cat /cache/data.txt
```

::: tip
Volume sharing allows different image tasks to share data,
making it ideal for scenarios like caching dependencies and sharing build artifacts.
:::
