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). 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
Terminalruntime images build . -t web:v1runtime sandboxes 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. 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 <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. The
create call returns once the server is up. start.state shows ready,
started, timeout or exited. To override both, set start. To drop both,
set 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 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.
Terminalruntime images build . -t web:v2 --build-arg NODE_ENV=production --target appruntime images logs web:v2 --followruntime images 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 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
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 the sandbox 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 26 October 2026.