How to build a sandbox image from a Dockerfile
Run runtime image build . -t web:v1, or pass dockerfile and contextDir to images.build; the folder is the build context.
On Runtime your existing Dockerfile builds as it is, multi-stage builds and heredocs included, and sandboxes from it start as Firecracker microVMs with their own kernel. The build is free, a rebuild uploads only the files that changed, and a stored image costs $0.08 per decimal GB per 30-day month (rate in force since 23 September 2026, pricing). The build itself runs in its own Firecracker virtual machine, with the same web access as a sandbox, so nothing needs a Docker daemon on your side.
Build and run
Terminalruntime image build . -t web:v1runtime sandbox create --image web:v1TypeScriptimport { readFile } from "node:fs/promises";import { Runtime } from "withruntime";const runtime = new Runtime();const image = await runtime.images.build( { name: "web", dockerfile: await readFile("Dockerfile", "utf8"), contextDir: "." }, { onLog: (line) => console.log(line.text) },);await using sbx = await runtime.sandboxes.create({ image: "web" });console.log(image.version, sbx.id);Pythonfrom withruntime import Runtimeruntime = Runtime()with open("Dockerfile") as handle: image = runtime.images.build(name="web", dockerfile=handle.read(), context_dir=".", on_log=lambda line: print(line["text"]))with runtime.sandboxes.create(image="web") as sbx: print(image["version"], sbx.id)The folder is the build context. Every file its .dockerignore leaves in is
packed, and only the parts that changed since your last build are uploaded.
What works and what to use instead
| Dockerfile feature | On Runtime |
|---|---|
Multi-stage, FROM <stage>, COPY --from |
Works; only the stages the image needs are built |
--target |
Works (target in the SDKs): builds a named stage |
ARG and --build-arg K=V |
Works, before and after FROM; TARGETARCH is amd64 |
Heredocs: RUN <<EOF, COPY <<EOF /path |
Works |
ADD from a URL, or of a local .tar.gz |
Works; --checksum=sha256:... is checked; archives are unpacked |
COPY --chown, --chmod, WORKDIR, ENV, USER |
Works |
RUN --mount=type=cache |
Runs, without the cache mount |
CMD, ENTRYPOINT, HEALTHCHECK |
Become the image's start command and ready check |
FROM runtime |
Runtime's base image, with Python, Node, Bun and the usual tools; last stage only |
RUN --mount=type=secret, ssh, bind |
Refused, with a message saying what to do instead |
ONBUILD, ADD from git, COPY --exclude |
Refused, with a message saying what to do instead |
For a secret the build needs, keep it out of the Dockerfile; code in the sandbox can use a secret it never sees at run time instead.
CMD and HEALTHCHECK become start and ready
A sandbox from the image runs its CMD or ENTRYPOINT once, in the
background, as the sandbox user. Its HEALTHCHECK becomes the ready check, so
the create answers once the server is up, with start.state saying ready,
started, timeout or exited. Override both with start, or drop them with
start: null for an image that should start idle
(start and ready commands).
From the CLI, --start <command> with --ready-port <port> sets them.
Rebuild fast
A build keeps up to three checkpoints of its filesystem. A later build of your
account that begins with the same steps starts from the latest one, so
changing your code reruns only the steps after the COPY that brings it in.
Put dependency installs before that COPY, as you would for Docker's own
cache. Checkpoints count toward your image disk quota and are not charged.
--no-cache (cache: false) builds every step from scratch.
Terminalruntime image build . -t web:v2 --build-arg NODE_ENV=production --target appruntime image logs web:v2 --followruntime image tag web@2 prodLimits
| Limit | Value |
|---|---|
| Build context | 100 MiB compressed, 20,000 files, 2 GiB unpacked |
| Context upload | 200 MiB held and 1 GiB uploaded a day per account |
| Dockerfile | 256 KiB, 200 steps across all stages, 16 earlier stages |
| Build time | 60 seconds to 1 hour (30 minutes by default) |
| Image size | 512 MiB to 20 GiB (8 GiB by default) |
| Builds at once | 1 until the account has bought credit, then 4 |
Mistakes to avoid
- A huge context.
node_modules, build output and datasets in the folder count toward the 100 MiB. List them in.dockerignore. - Expecting
USERto set who runs commands.USERapplies to the build'sRUNsteps. Commands in a sandbox run as the sandbox user, uid 1000, with passwordlesssudo. FROM runtimein an early stage. Only the last stage can start from it. Start earlier stages from a public image such asubuntu:24.04.- Pulling a private base image with no credential. Store one first (private registry images).
- Running Docker inside instead. When the sandbox itself must build or run containers, see Docker in a sandbox; for a short package list, a recipe is simpler.
Facts on this page were checked on 25 September 2026.