# How to build a sandbox image from a Dockerfile Run `runtime images 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, with multi-stage builds and heredocs included. Sandboxes from the image start as Firecracker microVMs, each with its own kernel.** The build is free. A rebuild uploads only the files that changed. 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 runs in its own Firecracker virtual machine, with the same web access as a sandbox. Nothing on your side needs a Docker daemon. ## Build and run ```bash no-run runtime images build . -t web:v1 runtime sandboxes 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. The build packs every file that its `.dockerignore` leaves in. 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 in your account that begins with the same steps starts from the latest checkpoint. So when you change your code, only the steps after the `COPY` that brings it in run again. Any Dockerfile that uses a base another build already pulled skips the pull. Put dependency installs before that `COPY`, as you would for Docker's own cache. A build that fails keeps its checkpoints until your next build finishes. Fixing the failing step then reruns only the steps from the last command before it. Checkpoints count toward your image disk quota, and they are not charged. `--no-cache` (`cache: false`) builds every step from scratch. ```bash no-run runtime images build . -t web:v2 --build-arg NODE_ENV=production --target app runtime images logs web:v2 --follow runtime images 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 the same time | 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 the sandbox 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 26 October 2026.