Skip to main content
The cloudflare_container machine provider reaches a Cloudflare Container, and runs the programs it captures in it. A container belongs to a Durable Object, which decides when it starts and stops. Mirage reaches it in one of two ways:
  • In the Durable Object: a workspace on Cloudflare Workers hands the handle its own ctx.container. TypeScript only.
  • Through a relay: you deploy a ContainerRelay Durable Object with the container, and a workspace anywhere reaches it by url and token. Python, Node, browsers and other Workers.

Installation

The ssh extra serves the workspace into the container with mount_type: ssh. The relay itself is a Worker, so deploying it needs @struktoai/mirage-cloudflare whichever language the workspace runs in. Start the image from a Debian or Ubuntu base, which has the shell tools Mirage’s own lines use. Add the interpreters it runs, here python3 and nodejs, and sshfs and fuse3 for mount_type: ssh:
Dockerfile
Programs do not see the image’s ENV lines: a program starts from Cloudflare’s own PATH and HOME=/root, with the machine’s env and the session’s environment on top. Put anything a program needs, such as a PATH entry for a tool installed outside /usr/local/bin or /usr/bin, in the machine’s env.

Usage through a relay

Deploy a Worker whose Durable Object class extends ContainerRelay, and route requests to it with relayFetch:
src/relay.ts
wrangler.jsonc
Set the token every call must carry, then deploy:
A relay without MIRAGE_RELAY_TOKEN refuses every call. The last path segment before the call names the container: each <name> in https://mirage-relay.<account>.workers.dev/<name> is a Durable Object, and a container, of its own. Point a machine at one:
The relay starts the container with the image its wrangler config names. To start it with options of your own, such as enableInternet: false, override startContainer:

Usage in the Durable Object

A workspace that already runs in a Durable Object builds the handle from its own ctx.container and a function that starts the container when it is not running:
src/worker.ts
Give the Durable Object class the container in your wrangler config, as the relay’s is above, and set the Worker up as the Cloudflare quickstart does. Mirage calls the start function the first time it reaches the machine, and again the first time after the container has stopped: for a line that runs there, and for ps, kill and the like when they ask it. An error it throws, such as a quota of your own, fails that line with the error’s message.

Configuration

The container’s image, instance type and network belong to the Durable Object that starts it, so none of them is a field. An entry with neither url nor a container handed in fails its first line and says how to reach one.

Connecting the workspace

Use mount_type: ssh: Mirage serves the workspace’s mounts through the container’s exec pipe, over the relay when there is one, and the container mounts each with sshfs. No port, key or network is needed in the container, so it works with enableInternet: false.

Notes

  • The container’s own disk is scratch: it is gone when the container stops. Files a program should keep belong in a mounted folder.
  • If the container stops while a line runs, the line fails: it exits 129 and says the container stopped, or, when the Durable Object destroys the container itself, it may exit 137. The next line starts it again. A relay connection that drops under a line fails it the same way.
  • The first line after a start waits for the container to answer, up to 60 seconds. Most starts answer within a second; a start that never comes up fails that line, and the next line starts the container again.
  • Output comes back as the program wrote it, binary included, with stdout and stderr separate. Without piped input, stdin starts closed.
  • Closing the workspace leaves a running container running and starts no stopped one. Stop it from the Durable Object.