Skip to content

Languages

How to compile and run Rust code in a sandbox

Install Rust with rustup or Ubuntu's rustc and cargo in an isolated microVM, build the code there, and run it with the network off.

Updated · Facts checked · By Runtime Cloud

5 min read

Read as Markdown

On Runtime, untrusted Rust is contained at two points: build time and run time. Cargo runs a package's build.rs just before it builds the package, so the build executes other people's code. That code belongs in the sandbox, as the binary does. Each Runtime sandbox is a Firecracker microVM with its own kernel, gcc and sudo. A 2 vCPU, 4 GiB sandbox costs $0.08 an hour with both CPUs compiling (pricing).

Which Rust to install

Source Package or command Version on 26 October 2026
Ubuntu 24.04 archive (main) sudo apt-get install -y rustc cargo 1.75.0
Ubuntu 24.04 archive (universe) sudo apt-get install -y rustc-1.91 1.91.1
rustup, the official installer the sh.rustup.rs script, below 1.99.1, the current stable release

The image has none of these. It has the C toolchain (gcc, g++, make) that crates with C code build against. Choose rustup if your code or its crates need a recent compiler.

Install with rustup and run a program

rustup installs rustc, cargo and rustup into ~/.cargo/bin (Rust); in a sandbox, home is /workspace. -y skips the prompts and --profile minimal leaves out the docs (rustup).

TypeScriptimport { Sandbox } from "withruntime";const program = `fn main() {    let words = ["sandbox", "microvm", "kernel"];    let longest = words.iter().max_by_key(|w| w.len()).unwrap();    println!("{longest}");}`;await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 1200, onLeaseEnd: "stop" });await sbx.exec(  "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal",  { check: true, timeoutMs: 600_000 },);await sbx.network.set({ internet: false }); // compile and run offlineawait sbx.files.write("/workspace/job/main.rs", program);const cargoBin = "/workspace/.cargo/bin";const build = await sbx.exec([`${cargoBin}/rustc`, "-O", "main.rs", "-o", "main"], {  cwd: "/workspace/job",  timeoutMs: 300_000,});if (build.exitCode !== 0) console.error(build.stderr);const run = await sbx.exec(["./main"], { cwd: "/workspace/job", timeoutMs: 10_000 });console.log(run.stdout); // sandbox
Pythonfrom withruntime import Sandboxprogram = """fn main() {    let words = ["sandbox", "microvm", "kernel"];    let longest = words.iter().max_by_key(|w| w.len()).unwrap();    println!("{longest}");}"""with Sandbox.create(disk_mib=8192, timeout_seconds=1200, on_lease_end="stop") as sbx:    sbx.exec("curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal",             check=True, timeout_ms=600_000)    sbx.network.set(internet=False)  # compile and run offline    sbx.files.write("/workspace/job/main.rs", program)    cargo_bin = "/workspace/.cargo/bin"    build = sbx.exec([f"{cargo_bin}/rustc", "-O", "main.rs", "-o", "main"],                     cwd="/workspace/job", timeout_ms=300_000)    if build.exit_code != 0:        print(build.stderr)    run = sbx.exec(["./main"], cwd="/workspace/job", timeout_ms=10_000)    print(run.stdout)  # sandbox
  • Disk the default 4 GiB sandbox had about 2.5 GiB free on 26 October 2026. A toolchain and a target folder use a lot of space, so request 8 GiB.
  • Time set a timeoutMs on the install and on each build. The default is 60 seconds. The sandbox has no time limit unless timeoutSeconds sets one.
  • Errors compiler errors go to stderr. Return them to the model that wrote the code, unchanged.

A Cargo project

Fetch the crates with the network on, then build and test offline, so neither build.rs nor the tests can make outside calls:

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({  image: "rust",  diskMiB: 8192,  timeoutSeconds: 3600,  onLeaseEnd: "stop",});await sbx.files.upload("./my-crate", "/workspace/crate");await sbx.exec("cargo fetch", { cwd: "/workspace/crate", check: true, timeoutMs: 600_000 });await sbx.network.set({ internet: false });const test = await sbx.exec(["cargo", "test", "--offline"], {  cwd: "/workspace/crate",  timeoutMs: 1_800_000,  onStdout: (text) => process.stdout.write(text),  onStderr: (text) => process.stderr.write(text),});console.log("exit", test.exitCode);
Pythonimport sysfrom withruntime import Sandboxwith Sandbox.create(image="rust", disk_mib=8192, timeout_seconds=3600, on_lease_end="stop") as sbx:    sbx.files.upload("./my-crate", "/workspace/crate")    sbx.exec("cargo fetch", cwd="/workspace/crate", check=True, timeout_ms=600_000)    sbx.network.set(internet=False)    test = sbx.exec(["cargo", "test", "--offline"], cwd="/workspace/crate", timeout_ms=1_800_000,                    on_stdout=sys.stdout.write, on_stderr=sys.stderr.write)    print("exit", test.exit_code)

This uses the rust image defined below. Both streams print as the build runs.

Rust in every sandbox

Install the toolchain once in a custom image so that no sandbox has to wait for it. rustup reads RUSTUP_HOME and CARGO_HOME to find its files, and both must be set whenever the toolchain runs (rustup). A recipe's env stays set in every sandbox made from the image. Recipe commands run as root, so the last command lets the sandbox user write to Cargo's cache.

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "rust",  recipe: {    env: { RUSTUP_HOME: "/usr/local/rustup", CARGO_HOME: "/usr/local/cargo" },    commands: [      "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --no-modify-path",      "ln -sf /usr/local/cargo/bin/* /usr/local/bin/",      "chmod -R a+w /usr/local/rustup /usr/local/cargo",    ],  },});
Pythonfrom withruntime import Runtimeruntime = Runtime()runtime.images.build(name="rust", recipe={    "env": {"RUSTUP_HOME": "/usr/local/rustup", "CARGO_HOME": "/usr/local/cargo"},    "commands": [        "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --no-modify-path",        "ln -sf /usr/local/cargo/bin/* /usr/local/bin/",        "chmod -R a+w /usr/local/rustup /usr/local/cargo",    ],})

To use Ubuntu's compiler instead, the recipe is { apt: ["rustc", "cargo"] }. Building an image is free. A stored image is charged by its size.

Many builds at once

Each sandbox is its own machine with its own disk, so parallel builds never share a target folder or a lock on Cargo's cache. A paid account runs 100 sandboxes at the same time. Every account gets 100 free hours of a 1 GB machine in its first 30 days, with no card required:

Terminalnpx withruntime sandboxes run -- bash -c 'sudo apt-get update -q && sudo apt-get install -y -q rustc && rustc --version'

Sources

Facts on this page were checked on 26 October 2026.

Cut your cloud billby 75%.

No card to start. Billed by the second after.

Start free, no card