# Reproducing the devcontainer DX, but securely

> Source: <https://k33g.org/p/20261017-devsbx>
> Published: 2026-10-17 00:00:00+00:00

I have always loved using **[devcontainer](https://containers.dev/)**, because it lets VS Code open a project in a preconfigured container with its tools, dependencies and extensions, so you can start coding right away in a reproducible environment without installing everything on your machine. **devcontainer** connects VS Code to the container, so you keep your usual editor while using the container's tools and dependencies for the terminal, autocompletion, tests and debugging: you develop **in the same environment as the one where the code runs**.

Today, with **`sbx`** and its [SSH access](https://docs.docker.com/ai/sandboxes/integrations/) feature, you can absolutely connect **VS Code** to a running `sbx` sandbox over SSH. Your code is then compiled and executed inside this isolated environment, rather than on your host machine. You get a setup similar to what **devcontainer** offers, but with the security hardening tools of `sbx` such as the microVM, **secrets protection** and network policies.

Let's see how to put this into practice with **[`sbx` kits](https://docs.docker.com/reference/cli/sbx/kit/)**, and make it all smooth and straightforward thanks to the `sbx env create` and `sbx env rm` commands.

Docker `sbx` **kits** are declarative YAML configurations that define sandboxes and enrich them with network policies, environment variables, commands ...

## [Prerequisites](#prerequisites)

First of all, you need VS Code installed. Then, you need to install the **Remote-SSH** extension in VS Code (only once):

```
code --install-extension ms-vscode-remote.remote-ssh
```

Then, you need to add the `*.sbx` block to `~/.ssh/config` (idempotent):

```
sbx setup ssh
```

## [Creating the `vscode-ssh` kit](#creating-the-vscode-ssh-kit)

`vscode-ssh` kit
In a folder, create a tree like this one:

```
.
├── demo
│   └── README.md
├── kits
│   └── vscode-ssh
│       ├── config
│       │   └── machine-settings.json
│       ├── kit.dockerfile
│       └── kit.yaml
└── sbxenv.yaml
```

- The `demo` folder will be the VS Code`workspace` (this is where you can create the`.vscode` folder with the`extensions.json` and`settings.json` files)
- The `kits` folder will contain all the kits needed to build our secure working environment.
- The `sbxenv.yaml` file will let us manage the environment of our`sbx` sandbox (think of it as the compose file of`sbx` )

### [`vscode-ssh`](#vscode-ssh)

`vscode-ssh`
The kit is made of the following 3 files:

**`vscode-ssh/config/machine-settings.json`**:

```
{
    "telemetry.telemetryLevel": "off",
    "update.mode": "none",
    "extensions.autoUpdate": false,
    "terminal.integrated.defaultProfile.linux": "bash"
}
```

**`vscode-ssh/kit.dockerfile`**:

```
# syntax=docker/dockerfile:1
# vscode-ssh: the shell template
FROM docker/sandbox-templates:shell

USER root

# What the VS Code server expects on a Remote-SSH host
RUN <<EOF
set -eux
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
  libstdc++6 tar gzip curl wget ca-certificates procps git
rm -rf /var/lib/apt/lists/*
EOF

USER agent

# Default machine settings for the VS Code server
RUN --mount=type=bind,target=/tmp/kit <<EOF
set -eux
install -D -m 0644 /tmp/kit/config/machine-settings.json \
  /home/agent/.vscode-server/data/Machine/settings.json
EOF

WORKDIR /home/agent/workspace
```

**`vscode-ssh/kit.yaml`**:

```
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: workload
displayName: vscode-ssh
description: >-
    Shell sandbox for VS Code Remote-SSH
sourceUrl: https://rickub.com/k33g/devsbx
licenses: [MIT]
version: "0.1.0"
capabilities:
    - type: com.docker.sandbox/sbx@1
    - type: com.docker.sandbox/network-policy@1
      config:
        runtime:
            allow:
                - update.code.visualstudio.com
                - vscode.download.prss.microsoft.com
                - "*.vscode-cdn.net"
                - marketplace.visualstudio.com
                - "*.gallery.vsassets.io"
                - "*.gallerycdn.vsassets.io"
                - open-vsx.org
```

## [`sbxenv.yaml`](#sbxenvyaml)

`sbxenv.yaml`
`sbxenv.yaml` is a **declarative** configuration file that describes a **Docker Sandboxes** environment (AI agent, mounted folders, variables, secrets and tools) so you can create and manage it with the `sbx env` commands.

```
schemaVersion: "1"

# Sandbox name = SSH host (<name>.sbx): letters, digits and hyphens only.
name: vscode-demo

# The workload kit is the base "agent": its name is the kit directory name.
agent: vscode-ssh

kits:
  - ./kits/vscode-ssh

# Mounted at the same path as on the host, 
# so VS Code opens that same path remotely.
workspace: ./demo
```

So let's see how to launch our new development environment.

## [Starting the secure development environment](#starting-the-secure-development-environment)

First, you need to create and start the `sbx` sandbox with the following command:

```
sbx env create --force
```

`--force` skips the confirmation messages

And once the `sbx` sandbox is created, you can start VS Code with the command below to connect it to the sandbox over SSH:

```
code --new-window --remote ssh-remote+vscode-demo.sbx "$PWD/demo"
```

**Note**: in `ssh-remote+vscode-demo.sbx` we reuse the sandbox name defined in `sbxenv.yaml`: `name: vscode-demo`

And VS Code will start in the `demo` folder and initialize the connection to the `vscode-demo` sandbox:

But now it would be nice to add a few tools, like a **Rust** toolchain for example. So we are going to create a second type of kit, a `mixin` kit, to install **Rust** in our environment.

## [Adding Rust to our working environment](#adding-rust-to-our-working-environment)

First, let's stop and remove the running `sbx` instance with the command:

```
sbx env rm --force
```

And let's create a new `rust-toolchain` kit in the `./kits` folder:

```
.
├── demo
│   └── README.md
├── kits
│   ├── rust-toolchain
│   │   ├── rust-toolchain.dockerfile
│   │   └── rust-toolchain.yaml
│   └── vscode-ssh
│       ├── config
│       │   └── machine-settings.json
│       ├── kit.dockerfile
│       └── kit.yaml
└── sbxenv.yaml
```

Now, let's have a look at the contents of `rust-toolchain.dockerfile` and `rust-toolchain.yaml`.

**`rust-toolchain/rust-toolchain.dockerfile`**:

```
# syntax=docker/dockerfile:1

# --- build stage: the Rust toolchain, through rustup ---
FROM debian:trixie-slim AS rust
ARG RUST_VERSION

RUN <<EOF
set -eu
apt-get update
apt-get install -y --no-install-recommends curl ca-certificates
rm -rf /var/lib/apt/lists/*
EOF

ENV RUSTUP_HOME=/usr/local/rustup \
    CARGO_HOME=/usr/local/cargo
RUN <<EOF
set -eu
curl -fsSL https://sh.rustup.rs | sh -s -- -y --no-modify-path \
  --profile minimal \
  --default-toolchain "${RUST_VERSION}" \
  --component rustfmt,clippy,rust-analyzer,rust-src
EOF

RUN <<EOF
set -eu
toolchain="$(ls -d /usr/local/rustup/toolchains/*)"
mkdir -p /out/usr/local/bin
for bin in cargo rustc rustdoc rustfmt cargo-fmt cargo-clippy clippy-driver rust-analyzer; do
  ln -s "${toolchain}/bin/${bin}" "/out/usr/local/bin/${bin}"
done
# Kept in the overlay at the same path: the links point into it.
mkdir -p /out/usr/local/rustup/toolchains
mv "${toolchain}" /out/usr/local/rustup/toolchains/
EOF

# --- linker stage: what the workload lacks to link, from its own distro ---
FROM docker/sandbox-templates:shell AS linker
USER root
RUN <<EOF
set -eu
apt-get update
apt-get install -y --no-install-recommends --download-only gcc libc6-dev
mkdir -p /out
for deb in /var/cache/apt/archives/*.deb; do
  dpkg-deb -x "${deb}" /out
done
# Set by update-alternatives in a real install, which unpacking skips.
ln -sf gcc /out/usr/bin/cc
rm -rf /out/usr/share/doc /out/usr/share/man /out/usr/share/info /out/usr/share/locale
EOF

FROM scratch
COPY --from=linker /out/ /
COPY --from=rust /out/ /
```

**`rust-toolchain/rust-toolchain.yaml`**:

```
# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: mixin
displayName: Rust toolchain
description: Rust toolchain (cargo, rustc, rustfmt, clippy) and rust-analyzer (language server)

args:
  rust_version:
    # A Rust release (e.g. 1.99.0), or stable / beta / nightly (not reproducible).
    default: "1.99.0"
    pattern: '^([0-9]+\.[0-9]+(\.[0-9]+)?|stable|beta|nightly)$'
    buildArg: RUST_VERSION

provides: ["rust@${{ kit.args.rust_version }}"]

capabilities:
  # Runtime access with the tool: the crates.io index and crate downloads.
  - type: com.docker.sandbox/network-policy@1
    config:
      runtime:
        allow:
          - index.crates.io
          - static.crates.io
          - crates.io
          - github.com
```

Then let's update `sbxenv.yaml` to add `./kits/rust-toolchain`:

**`sbxenv.yaml`**:

```
schemaVersion: "1"

# Sandbox name = SSH host (<name>.sbx): letters, digits and hyphens only.
name: vscode-demo

# The workload kit is the base "agent": its name is the kit directory name.
agent: vscode-ssh

# Relative paths resolve against the directory of this file.
kits:
  - ./kits/vscode-ssh
  - ./kits/rust-toolchain

# Mounted at the same path as on the host, 
# so VS Code opens that same path remotely.
workspace: ./demo
```

And now all you have to do is run again:

```
sbx env create --force
```

Wait a few moments while the new kit builds.

Then, we can start VS Code:

```
code --new-window --remote ssh-remote+vscode-demo.sbx "$PWD/demo"
```

And you can check that **Rust** is properly installed:

And of course, you can absolutely add the AI agent of your choice to your setup.

## [Adding Claude Code](#adding-claude-code)

So I added a `claude-code` kit of type `mixin` to my project. You can grab it here: [sbx-vscode/kits/claude-code](https://rickub.com/k33g/devsbx/tree/main/sbx-vscode/kits/claude-code), and I added this line to the `kits` section in `sbxenv.yaml`:

```
- ./kits/claude-code
```

And once my sandbox is recreated, I can now use Claude Code:

Et voilà! You now have everything you need to build yourself development environments that are secure for real.

Written by

Keep reading

### Improving the Developer Experience with SBX Kits

Improve the developer experience with sbx kits: reusable sandbox customizations for Go, Node.js, and code-server extensions.

May 1, 2026

### Embedding a Web IDE and Docker Agent into `sbx`, a fully secured sandbox

Embed a web IDE and docker-agent into an sbx sandbox with Docker Model Runner for a ready-to-use secure dev environment.

Apr 18, 2026

### Running Mistral's Vibe CLI in an `sbx` sandbox

Run Mistral's Vibe coding agent CLI securely inside an sbx sandbox, with credential handling and network isolation.

Jun 9, 2026
From other blogs
