Run your own image

Last updated 2 November 2026

View .md

Machines are not open yet. These pages describe Machines as they will open; until then, a create answers region_not_offered (422), “Machines are not offered in any region yet.”

Package your own program for a Machine when the quickstart’s image is not enough: how to build and publish its image, how the Machine runs it, and what it finds inside.

Build for linux/arm64

A Machine runs only linux/arm64 images, from a registry that serves them without credentials. Build and push one with Docker’s multi-platform builds, which work from an x86 computer too:

docker buildx build --platform linux/arm64 -t registry.example.com/you/app:1 --push .

A program that opens its database starts from a glibc-based image, such as:

Dockerfile
FROM node:22-bookworm-slim
WORKDIR /app
COPY package.json package-lock.json server.js ./
RUN npm ci --omit=dev
CMD ["node", "server.js"]

Try it on your computer first

What a Machine’s program prints cannot be read, so run the image on your computer before you create the Machine, to check that it starts. The variables the platform sets (below) exist only on a Machine, so on your computer a program that opens its database stops at the open:

docker run --platform linux/arm64 -p 8080:8080 registry.example.com/you/app:1

Create the Machine

tonbo machine create app --image registry.example.com/you/app:1 --shape s-2 --port 8080 --region us-east-1 --wait

Words after -- replace the image’s CMD; its ENTRYPOINT stays:

tonbo machine create app --image registry.example.com/you/app:1 --shape s-2 --port 8080 --region us-east-1 --wait -- node server.js --verbose

What runs, and as whom

A Machine runs the image’s Entrypoint followed by its Cmd (or your command), as the image’s User, in its WorkingDir, with its Env plus PATH and HOME. The other settings of an image’s configuration are not used, its stop signal included: when a sleep signals the program, the signal is SIGTERM (see Stopping).

Environment variables

Up to 128 variables, each named like LOG_LEVEL with a value of up to 32,768 characters. A change applies at the next wake:

tonbo machine update app --env LOG_LEVEL=debug

Every member of your account, and every Agent key of it, can read them through the API, and a Machine has no other store for secrets, so put in them only what every member may hold (see the rule).

What the platform sets

VariableWhat it holds
TONBO_DATABASE_URLthe URL of the Machine’s own database, to pass to open()
TONBO_VFS_CACHE_DIRthe directory for the database’s local copy, to pass as dir
TONBO_VFS_MAX_PENDING_BYTEShow much committed data, in compressed bytes, may wait to be sent; pass it as maxPendingBytes
TONBO_REGIONthe Machine’s region
TONBO_MACHINE_NAMEthe Machine’s name
TONBO_MACHINE_IDthe Machine’s id, which never changes

The platform sets a few more for the database package itself. Every name it sets is reserved: a Machine whose environment variables set one fails to wake (see Database wiring). How a program uses the database’s variables is on Keep data in its database and Volume.

Disks

The program sees the image’s own files with 1 GiB free beyond them, and the shape’s scratch disk at /scratch. Both start empty at every wake, so keep nothing there that must last: keep it in the database or on the Machine’s Volume (see What a wake starts with).

Which images a Machine can use

Public images from a registry reachable over IPv4, within the bounds on Limits. Anyone can pull a public image, so build no secret into it. What Tonbo does with your image is on Image pulls.