Runtime

How to run ImageMagick in a cloud sandbox

Install Ubuntu's imagemagick package in a microVM, run convert, mogrify or identify on the uploaded images, and download the results.

On Runtime, image processing on untrusted uploads happens on a machine that holds nothing but the uploads. Every sandbox is a Firecracker microVM with its own Linux kernel, so a crafted file that trips a decoder bug lands on an empty machine you throw away, not on your web servers. A batch of resizes is CPU work billed as used: $0.08 an hour for 2 vCPU and 4 GiB at full load, $0.03125 while it waits (pricing). Ubuntu 24.04 shipped ImageMagick 6.9.12.98 on 25 September 2026.

ImageMagick 6 on Ubuntu 24.04

Ubuntu's imagemagick package is the 6 series, so its commands are convert, mogrify, identify, montage and composite. The magick command belongs to ImageMagick 7, which Ubuntu 24.04 does not package; scripts written for 7 need magick replaced with convert here.

Make thumbnails from a folder of uploads

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ diskMiB: 6144, timeoutSeconds: 1800 });await sbx.exec("sudo apt-get update -qq && sudo apt-get install -y -qq imagemagick ghostscript", {  check: true,  timeoutMs: 600_000,});await sbx.network.off(); // a crafted image cannot call outawait sbx.files.upload("./uploads", "/workspace/in");await sbx.exec(  "mkdir -p out && mogrify -path out -auto-orient -resize '640x640>' -strip -quality 82 -format jpg in/*",  {    check: true,    timeoutMs: 900_000,  },);const sizes = await sbx.exec("identify -format '%f %wx%h\\n' out/*", { check: true });console.log(sizes.stdout);await sbx.files.download("/workspace/out", "./thumbs");
Pythonfrom withruntime import Sandboxwith Sandbox.create(disk_mib=6144, timeout_seconds=1800) as sbx:    sbx.exec("sudo apt-get update -qq && sudo apt-get install -y -qq imagemagick ghostscript",             check=True, timeout_ms=600_000)    sbx.network.off()  # a crafted image cannot call out    sbx.files.upload("uploads", "/workspace/in")    sbx.exec("mkdir -p out && mogrify -path out -auto-orient -resize '640x640>' -strip "             "-quality 82 -format jpg in/*", check=True, timeout_ms=900_000)    print(sbx.exec("identify -format '%f %wx%h\\n' out/*", check=True).stdout)    sbx.files.download("/workspace/out", "thumbs")
  • mogrify -path out writes new files to out and leaves the originals.
  • 640x640> shrinks only images larger than 640 pixels on a side.
  • -strip removes metadata such as camera and location data before the images go anywhere else.
  • The folder goes up and comes back as one compressed archive each way.

Render PDF pages as images

ImageMagick hands PDF and PostScript to Ghostscript, which the sample installs (Ubuntu recommends it alongside ImageMagick; 10.02.1 in noble):

TypeScriptimport { Sandbox } from "withruntime";await using sbx = await Sandbox.create({ image: "imagemagick" });await sbx.files.upload("./brochure.pdf", "/workspace/brochure.pdf");await sbx.exec("convert -density 150 'brochure.pdf[0]' -background white -flatten cover.png", {  check: true,  timeoutMs: 300_000,});await sbx.files.download("/workspace/cover.png", "./cover.png");

[0] selects the first page; -density sets the rendering resolution before the PDF is read.

The security policy Ubuntu ships

/etc/ImageMagick-6/policy.xml, from the imagemagick-6-common package in Ubuntu 24.04, sets these limits. Each row is the file's own setting and its own comment, read from the package on 25 September 2026:

Policy Value What happens past it
memory 1024 MiB Pixels are cached to memory-mapped disk instead of the heap
map 2048 MiB Pixels are cached to disk
area 256 MP An image larger than that is cached to disk
disk 2 GiB The pixel cache is not created and an exception is thrown
width, height 32 KP each An exception is thrown
path @* none Indirect reads (a file that lists other files) are not permitted
delegate URL, HTTP, HTTPS none ImageMagick will not fetch an image from a web address

Two consequences for sandboxes:

  • Fetch first. convert https://... is refused by the delegate policy, so download with curl and convert the file.
  • Very large images. A scan or a panorama that needs more than the disk limit fails. Raise it by editing the policy with sudo, and give the sandbox the memory and disk to match: memory is what you ask for with memoryMiB, and the default 4 GiB disk had about 2.5 GiB free on 24 September 2026.

Root in the sandbox can edit the policy, but not the sandbox's network rules, CPU, memory or cost, which the host enforces.

Start every sandbox with ImageMagick installed

The imagemagick image the PDF sample uses, as a custom image:

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "imagemagick",  recipe: { apt: ["imagemagick", "ghostscript"] },});
Pythonfrom withruntime import RuntimeRuntime().images.build(name="imagemagick", recipe={"apt": ["imagemagick", "ghostscript"]})

Building is free and uses no trial hours; the free trial stores three images free.

When a sandbox is the right place

Job Why a sandbox
Thumbnails for user uploads The decoder never runs on your web servers
An agent that edits or composes images Its commands run on a machine it cannot damage beyond itself
A one-off batch of thousands of files Split it across sandboxes; a paid account runs 100 at once, the trial eight

For video frames and posters, see FFmpeg in a sandbox. To read the text in a scanned image, see Tesseract OCR in a sandbox. For the general case, see run untrusted LLM code.

Sources

Facts on this page were checked on 25 September 2026.