# 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](/docs/pricing#snapshots-images-and-volumes)). 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 ```bash no-run runtime image build . -t web:v1 runtime sandbox create --image web:v1 ``` ```ts check import { 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); ``` ```python check from withruntime import Runtime runtime = 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 `, `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 <` with `--ready-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. ```bash no-run runtime image build . -t web:v2 --build-arg NODE_ENV=production --target app runtime image logs web:v2 --follow runtime image tag web@2 prod ``` ## Limits | 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 `USER` to set who runs commands.** `USER` applies to the build's `RUN` steps. Commands in a sandbox run as the sandbox user, uid 1000, with passwordless `sudo`. - **`FROM runtime` in an early stage.** Only the last stage can start from it. Start earlier stages from a public image such as `ubuntu:24.04`. - **Pulling a private base image with no credential.** Store one first ([private registry images](/how-to/use-a-private-registry-image)). - **Running Docker inside instead.** When the sandbox itself must build or run containers, see [Docker in a sandbox](/how-to/run-docker-in-a-sandbox); for a short package list, a [recipe](/how-to/build-an-image-from-a-recipe) is simpler. Facts on this page were checked on 25 September 2026.