---
title: Run microsandbox in Docker
sidebarTitle: Sandbox in Docker
description: Run the microsandbox CLI from a Linux container with KVM access
icon: "box"
---

<Tooltip tip="The container runs the local microsandbox backend and needs hardware virtualization from the environment running Docker. It is not a microsandbox cloud workflow."><span className="msb-badge-local">Local-only <Icon icon="circle-info" size={11} /></span></Tooltip>

This example runs the `msb` CLI inside Docker and starts an Alpine microVM from the container. It works in any Docker environment that can pass a usable `/dev/kvm` device into the container.

## Run microsandbox in Docker

<Steps>

<Step title="Check Docker support">

Pull the image, then run `msb doctor` inside it before starting a sandbox:

```bash
docker pull ghcr.io/superradcompany/microsandbox:latest
```

Run the preflight inside the container:

<CodeGroup>
```bash macOS & Linux
docker run --rm --device /dev/kvm \
  ghcr.io/superradcompany/microsandbox:latest \
  doctor
```

```powershell Windows
docker run --rm --device /dev/kvm `
  ghcr.io/superradcompany/microsandbox:latest `
  doctor
```
</CodeGroup>

A compatible Docker environment reports both checks as successful:

```text
✓ KVM device   /dev/kvm
✓ KVM access   read/write
```

If both checks pass, continue with the example. If either fails, the Docker environment does not currently expose the virtualization support microsandbox needs. `/dev/kvm` is the authoritative compatibility check: Docker Engine can pass it through directly, while Docker Desktop depends on whether its Linux VM makes nested virtualization available.

If Docker rejects the device mapping or `msb doctor` reports that `/dev/kvm` is missing, consult the relevant setup guide:

- **Linux Docker Engine:** Follow the [`/dev/kvm` setup and permission checks](/troubleshooting/linux#missing-devkvm).
- **Docker Desktop:** Review the [Mac virtual machine manager](https://docs.docker.com/desktop/features/vmm/) or [Windows backend](https://docs.docker.com/desktop/setup/install/windows-install/) documentation. Hardware virtualization on the physical machine does not by itself make `/dev/kvm` available to containers.
- **Docker Desktop inside another VM or VDI:** Follow Docker's [nested-virtualization guide](https://docs.docker.com/desktop/setup/vm-vdi/).

After changing the Docker or hypervisor configuration, rerun the preflight. Adding `--privileged` cannot create a KVM device that the Docker environment does not have.

</Step>

<Step title="Open an interactive sandbox">

Run Alpine and attach your terminal to its shell:

<CodeGroup>
```bash macOS & Linux
docker run --rm -it \
  --device /dev/kvm \
  ghcr.io/superradcompany/microsandbox:latest \
  run alpine --name my-sandbox --replace
```

```powershell Windows
docker run --rm -it `
  --device /dev/kvm `
  ghcr.io/superradcompany/microsandbox:latest `
  run alpine --name my-sandbox --replace
```
</CodeGroup>

- `--rm` removes the outer container when it exits.
- `-it` carries your terminal through Docker and `msb` to the sandbox. Without it, the sandbox can be running with no usable prompt.
- `--device /dev/kvm` grants the specific hardware interface microsandbox needs. The container does not require Docker's blanket `--privileged` mode.

At the Alpine prompt, verify the guest and exit:

```sh
uname -a
exit
```

</Step>

<Step title="Run one command">

For automation, pass a command instead of allocating a terminal:

<CodeGroup>
```bash macOS & Linux
docker run --rm --device /dev/kvm \
  ghcr.io/superradcompany/microsandbox:latest \
  run alpine --name my-sandbox --replace -- \
  echo "hello from a microVM"
```

```powershell Windows
docker run --rm --device /dev/kvm `
  ghcr.io/superradcompany/microsandbox:latest `
  run alpine --name my-sandbox --replace -- `
  echo "hello from a microVM"
```
</CodeGroup>

The command's output and exit code pass through both layers to the host.

</Step>

<Step title="Persist images and sandboxes">

Without a volume, the outer container owns the microsandbox image cache and database. `--rm` deletes them with the container, so the next run downloads Alpine again. Mount a Docker volume when repeated runs should reuse that state:

```bash
docker volume create microsandbox-data
```

Mount it at microsandbox's data directory:

<CodeGroup>
```bash macOS & Linux
docker run --rm -it \
  --device /dev/kvm \
  --volume microsandbox-data:/root/.microsandbox \
  ghcr.io/superradcompany/microsandbox:latest \
  run alpine --name my-sandbox --replace
```

```powershell Windows
docker run --rm -it `
  --device /dev/kvm `
  --volume microsandbox-data:/root/.microsandbox `
  ghcr.io/superradcompany/microsandbox:latest `
  run alpine --name my-sandbox --replace
```
</CodeGroup>

The Docker volume preserves pulled images, stopped sandboxes, snapshots, and the microsandbox database. Remove it only when that state is no longer needed:

```bash
docker volume rm microsandbox-data
```

</Step>

</Steps>

## Troubleshooting

<div className="msb-accordion-group">
  <AccordionGroup>
    <Accordion title="The process exits with SIGABRT before the agent starts">
      Run the `msb doctor` preflight above. An early abort while entering the VM commonly means the outer Linux environment did not provide usable KVM access.
    </Accordion>
    <Accordion title="The command keeps running but shows no prompt">
      Check that the Docker command includes `-it`. From another terminal, `docker ps` may show that the outer container is running even though its standard input and terminal were not attached.
    </Accordion>
    <Accordion title="The guest image downloads on every run">
      Mount `microsandbox-data` at `/root/.microsandbox`. An ephemeral outer container otherwise starts with an empty microsandbox cache.
    </Accordion>
  </AccordionGroup>
</div>

## Image tags

| Tag | Description |
| --- | --- |
| `latest` | Latest microsandbox release. |
| `x.y.z` | Exact release version. |
| `x.y` | Latest patch release in a minor series. |
