# 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 triggers a decoder bug runs on an empty machine that 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](/docs/pricing)). Ubuntu 24.04 shipped ImageMagick 6.9.12.98 on 25 October 2026. ## ImageMagick 6 on Ubuntu 24.04 Ubuntu's `imagemagick` package is version 6, 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 must replace `magick` with `convert` here. ## Make thumbnails from a folder of uploads ```ts check import { 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 out await 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"); ``` ```python check from withruntime import Sandbox with 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 upload and the download each move the folder as one compressed archive. ## Render PDF pages as images ImageMagick hands PDF and PostScript files to Ghostscript. The sample installs Ghostscript, which Ubuntu recommends alongside ImageMagick. Ghostscript 10.02.1 is the version in Ubuntu's noble release: ```ts check import { 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 shows the file's own setting and comment, as read from the package on 25 October 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. Use `curl` to download the file, then convert it. - **Very large images.** A scan or a panorama that needs more than the `disk` limit fails. Raise the limit by editing the policy with `sudo`. Give the sandbox matching memory and disk. Request memory with `memoryMiB`. The default 4 GiB disk had about 2.5 GiB free on 24 September 2026. Root in the sandbox can edit the policy. It cannot change the sandbox's network rules, CPU, memory or cost. The host enforces those. ## Start every sandbox with ImageMagick installed This is the `imagemagick` image that the PDF sample uses, built as a [custom image](/docs/images): ```ts check import { Runtime } from "withruntime"; const runtime = new Runtime(); await runtime.images.build({ name: "imagemagick", recipe: { apt: ["imagemagick", "ghostscript"] }, }); ``` ```python check from withruntime import Runtime Runtime().images.build(name="imagemagick", recipe={"apt": ["imagemagick", "ghostscript"]}) ``` Building is free. Without credit, a build counts toward the free usage. An account without credit 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 sandboxes at the same time, and an account without credit runs four | For video frames and posters, see [FFmpeg in a sandbox](/integrations/ffmpeg). To read the text in a scanned image, see [Tesseract OCR in a sandbox](/integrations/tesseract). For the general case, see [run untrusted LLM code](/use-cases/run-untrusted-llm-code). ## Sources - Ubuntu 24.04 imagemagick and imagemagick-6.q16 packages, from the noble package index at http://archive.ubuntu.com/ubuntu/dists/noble/universe/binary-amd64/, read 25 October 2026 - policy.xml from imagemagick-6-common 6.9.12.98+dfsg1-5.2build2, http://archive.ubuntu.com/ubuntu/pool/universe/i/imagemagick/, read 25 October 2026 - Ubuntu 24.04 ghostscript package, from the noble package index at http://archive.ubuntu.com/ubuntu/dists/noble-updates/main/binary-amd64/, read 25 October 2026 - ImageMagick command-line tools, https://imagemagick.org/command-line-tools/, read 25 October 2026 Facts on this page were checked on 25 October 2026.