Skip to content
Runtime

How to run Docker inside a sandbox

Run sudo enable-docker once in the sandbox. It installs Docker Engine, Buildx and Compose. After that, docker works as the sandbox user.

On Runtime, Docker runs inside a microVM of its own. Every sandbox is a Firecracker microVM with its own Linux kernel. The Docker daemon, your containers and docker build all run inside that machine. Root inside it still cannot change its network, CPU, memory or cost. docker run, docker build and docker compose work as they do on any Linux machine. A 2 vCPU, 4 GiB sandbox costs $0.03125 an hour while its containers wait. With both CPUs busy, it costs $0.08 an hour (pricing).

Run a container

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 1800 });const slow = { check: true, timeoutMs: 600_000 } as const;await sbx.exec("sudo enable-docker", slow);const hello = await sbx.exec("docker run --rm hello-world", slow);console.log(hello.stdout);
Pythonfrom withruntime import Sandboxwith Sandbox.create(disk_mib=8192, timeout_seconds=1800) as sbx:    sbx.exec("sudo enable-docker", check=True, timeout_ms=600_000)    hello = sbx.exec("docker run --rm hello-world", check=True, timeout_ms=600_000)    print(hello.stdout)
Terminalsudo enable-docker          # once per sandbox; the first docker command runs it toodocker run --rm hello-worlddocker compose up -d

enable-docker installs Docker Engine, Buildx and Compose from Ubuntu's archive, and starts them. After that, docker works without sudo. Installs take longer than the 60-second default for a command, so set timeoutMs for them.

Run a Compose project and open it in a browser

Upload the project, start it, and share the published port as a private HTTPS preview:

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ diskMiB: 16_384, timeoutSeconds: 3600 });const slow = { check: true, timeoutMs: 900_000 } as const;await sbx.files.upload("./app", "/workspace/app");await sbx.exec("sudo enable-docker", slow);await sbx.exec("docker compose up -d --build", { ...slow, cwd: "/workspace/app" });const preview = await sbx.previews.create(8080); // the port compose publishesconsole.log(preview.url, preview.token);
Pythonfrom withruntime import Sandboxwith Sandbox.create(disk_mib=16_384, timeout_seconds=3600) as sbx:    sbx.files.upload("./app", "/workspace/app")    sbx.exec("sudo enable-docker", check=True, timeout_ms=900_000)    sbx.exec("docker compose up -d --build", cwd="/workspace/app",             check=True, timeout_ms=900_000)    preview = sbx.previews.create(8080)  # the port compose publishes    print(preview["url"])

A published port (-p 8080:80) listens inside the sandbox. A preview shares it, and runtime sandboxes port-forward <id> 8080 brings it to your own machine. A preview is private by default. A request needs its token, sent in the x-runtime-preview-token header (share a port).

Start every sandbox with Docker ready

Build a custom image whose recipe installs Docker. Every sandbox made from it skips the install. With --no-start, the daemon starts on the first docker command:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "docker",  recipe: { commands: ["enable-docker --no-start"] },});await using sbx = await runtime.sandboxes.create({ image: "docker", diskMiB: 8192 });await sbx.exec("docker run --rm hello-world", { check: true, timeoutMs: 300_000 });
Pythonfrom withruntime import Runtimeruntime = Runtime()runtime.images.build(name="docker", recipe={"commands": ["enable-docker --no-start"]})with runtime.sandboxes.create(image="docker", disk_mib=8192) as sbx:    sbx.exec("docker run --rm hello-world", check=True, timeout_ms=300_000)

Building an image is free. A stored image is charged by its size. An account without credit can store its first three images free (custom images). An image can also come from your own Dockerfile. That image runs as a Runtime image, without Docker in the sandbox at all.

Options and limits

What How it works
Install sudo enable-docker, once per sandbox, or in an image with enable-docker --no-start
Daemon Starts on the first docker command after a boot; a sandbox that runs no containers spends nothing on it
Disk Images and containers live on the sandbox's disk. Ask for more than the default 4 GiB, such as diskMiB: 8192
Pulls Docker Hub images come through Google's public mirror, mirror.gcr.io, first
Internet from containers No proxy settings needed: their connections out go through the sandbox's relay
Network rules The sandbox's allow and deny lists apply to its containers too
Published ports Listen inside the sandbox; share them with a preview or runtime sandboxes port-forward

In a measurement on 24 September 2026, the default 4 GiB sandbox had about 2.5 GiB free. That is why the samples ask for 8 GiB or more (disk, CPU and memory).

Compose services calling each other. Services, and containers on one Docker network, reach each other by name, as anywhere. Containers get no proxy settings, so nothing needs to go in NO_PROXY.

Where this helps

  • An agent that builds and runs a multi-service app can do it in a sandbox and show you the result through a preview (preview agent-built apps).
  • Integration tests that need a real Postgres or Redis get their own. It is discarded with the sandbox.
  • A coding agent can run a repository's own docker compose setup unchanged.

To learn why a microVM, and not a container, is the boundary, see microVM vs container and Firecracker vs Docker.

Start

Terminalnpx withruntime sandboxes run --timeout 600 -- bash -c 'sudo enable-docker && docker run --rm hello-world'

A new account gets 100 free hours of a 1 GB machine in its first 30 days, with no card. The first run prints a link to approve in your browser. For full details, see Docker in the sandbox environment.

Facts on this page were checked on 26 October 2026.

Related.

100 free hoursin your first 30 days.

of a 1 GB machine

  • No credit card
  • Four sandboxes at once, 2 vCPU and 4 GiB each
  • Then prepaid credit from $10, no plan fee
Start free, no card
Start free, no card