---
url: /en/workspaces/custom-dev-env.md
description: >
  Describes how to customize the Workspaces development environment by
  specifying a Docker image in `.cnb.yml` or writing a custom `.ide/Dockerfile`.
---
## Specifying Development Environment via Docker Image

You can specify the development environment by writing a Workspaces event
pipeline in `.cnb.yml` and setting `docker.image`.

If the specified image has code-server installed, it will start in **single-container mode**;
otherwise, it will start in **dual-container mode**.

Two options are available for specifying the development environment image;
choose the one that fits your needs in the example below:

### Use a pre-built image (image)

```yaml title=".cnb.yml"
$: # Fallback matching all branches not matched by glob
  vscode:
    - docker:
        image: cnbcool/default-dev-env:latest
      services:
        - vscode
        - docker
      stages:
        - name: ls
          script: ls -al
```

### Build via Dockerfile (build)

```yaml title=".cnb.yml"
$: # Fallback matching all branches not matched by glob
  vscode:
    - docker:
        # Build image using .ide/Dockerfile in the repository root
        build: .ide/Dockerfile
        # image is used as a fallback when the build fails (optional)
        image: cnbcool/default-dev-env:latest
      services:
        - vscode
        - docker
      stages:
        - name: ls
          script: ls -al
```

* `image`: Use a pre-built image directly (for pre-configured image scenarios)
* `build`: Custom build via Dockerfile (choose one with `image`; you can also specify `image` as a fallback)

## Customizing Development Environment via Dockerfile

If specifying an image doesn't meet your needs, you can create a `.ide/Dockerfile`
in the repository root to customize the development environment.

When no custom startup pipeline is defined, the system prioritizes using `.ide/Dockerfile`
to build the base image. If `.ide/Dockerfile` doesn't exist or the build fails, it falls back to the default image.

```dockerfile
# .ide/Dockerfile

# You can replace node with your required base image
FROM node:20

# Install code-server and common VSCode extensions
RUN curl -fsSL https://code-server.dev/install.sh | sh \
  && code-server --install-extension cnbcool.cnb-welcome \
  && code-server --install-extension redhat.vscode-yaml \
  && code-server --install-extension dbaeumer.vscode-eslint \
  && code-server --install-extension mhutchie.git-graph \
  && echo done

# Install CodeBuddy Code (provides the codebuddy command) to use CodeBuddy Web in the browser
# Make sure the version is >= 2.137.0 (see the "CodeBuddy Web" doc)
RUN npm install -g @tencent-ai/codebuddy-code

# Install SSH service to support accessing the development environment via VSCode Remote-SSH (and other software as needed)
RUN apt-get update && apt-get install -y git wget unzip openssh-server

# Specify character set to support Chinese input in command line (choose character set as needed)
ENV LANG C.UTF-8
ENV LANGUAGE C.UTF-8
```

## Customizing Both Development Environment and Startup Process

To customize both the development environment and startup process,
write `.ide/Dockerfile` and `.cnb.yml`. The Dockerfile content is the same as above.

In `.cnb.yml`, enable `build: .ide/Dockerfile` (see the "Build via Dockerfile (build)" example above),
and optionally specify `image` as a fallback. Full example:

```yaml title=".cnb.yml"
$: # Fallback matching all branches not matched by glob
  vscode:
    - docker:
        build: .ide/Dockerfile
        image: cnbcool/default-dev-env:latest
      services:
        - vscode
        - docker
      stages:
        - name: install deps
          script: npm install
        - name: dev
          script: npm run dev
```
