Capsule files
A capsule: the recipe for a short-lived Linux sandbox. Which packages to install, which users to create, which file systems and secrets to mount and which commands to run when it starts. It ends when its commands finish (with autoTerminate), when it is stopped, or when it runs out of time.
What capsules are for, and how to use them: Capsules.
Where the file goes
Section titled “Where the file goes”capsules/, or any sub-folder of it. The file name without .mtr is the capsule’s name.
A resource’s name is its file name without .mtr (an app’s is its folder’s name). Use letters, digits, _, - and . (but not ..), at most 128 characters. Two files of the same kind may not have the same name, even in different sub-folders or with different capitals.
Properties
Section titled “Properties”Every property is optional.
template
Section titled “template”Optional. Text.
A base image name, recorded with the capsule. Every capsule runs on the same image today (with Python 3, Node.js 22, .NET 8, Java 17, git and build tools), so it does not change what runs.
template = "ubuntu:22.04"packages
Section titled “packages”Optional. List of text.
Extra Debian packages to install with apt when the capsule starts, such as ["jq", "sqlite3"]. Lowercase letters, digits, +, - and .; each named once.
packages = [ "jq", "sqlite3" ]Optional. List of blocks.
Linux users to create. Commands run as the default user unless they say otherwise.
Optional. List of blocks.
Virtual file systems to mount. Each one appears at /mnt/<mountName>.
secrets
Section titled “secrets”Optional. List of blocks.
Secrets to mount. Each one is written to the file /mnt/secrets/<mountName>, readable by the default user.
startup
Section titled “startup”Optional. List of blocks.
Commands to run, in order, when the capsule starts. Their output is not kept.
autoTerminate
Section titled “autoTerminate”Optional. true or false. Default: false.
Stop the capsule as soon as its startup commands have finished.
autoTerminate = truemaxDuration
Section titled “maxDuration”Optional. Duration, "hh:mm:ss".
The longest the capsule may run, as "hh:mm:ss", counted from when it starts. Ten minutes when it is not set. A capsule still starting up then fails; a ready one finishes, and the command it is running is stopped.
maxDuration = "00:05:00"Each item of users
Section titled “Each item of users”A Linux user the capsule creates: { name = "builder" sudoAs = ["deployer"] }.
users › name
Section titled “users › name”Required. Text.
The user name: lowercase letters, digits, _ and -, starting with a letter or _, at most 32 characters, and not root.
name = "sandbox"users › sudoAs
Section titled “users › sudoAs”Optional. List of text.
Other users of the capsule this user may run commands as, with sudo. Never root.
sudoAs = [ "deployer" ]Each item of vfs
Section titled “Each item of vfs”A virtual file system mounted in the capsule: { vfs = @ref("sales-data") mountName = "data" }.
vfs › vfs
Section titled “vfs › vfs”Required. Reference to a virtual file system.
The virtual file system. Create it before you deploy.
Virtual file systems are not part of a project: create them in the portal, with the SDK or with mt vfs-create before you deploy.
vfs = @ref("sales-data")vfs › mountName
Section titled “vfs › mountName”Required. Text.
Where it appears: /mnt/<mountName>.
mountName = "data"Each item of secrets
Section titled “Each item of secrets”A secret written to a file in the capsule: { secret = @ref("deploy-key") mountName = "deploy-key" }.
secrets › secret
Section titled “secrets › secret”Required. Reference to a secret.
The secret. Create it before you deploy.
Secrets are not part of a project: create them in the portal, with the SDK or with mt secret-create before you deploy.
secret = @ref("orders-api-key")secrets › mountName
Section titled “secrets › mountName”Required. Text.
The file name: the secret’s value is written to /mnt/secrets/<mountName>.
mountName = "data"Each item of startup
Section titled “Each item of startup”A command the capsule runs when it starts: { command = "python3" arguments = ["report.py"] }.
startup › command
Section titled “startup › command”Required. Text.
The program to run, such as "python3" or "bash".
command = "python3"startup › arguments
Section titled “startup › arguments”Optional. List of text.
The program’s arguments. Each is passed as one word exactly as given, so spaces and quotes inside an argument reach the program. To pipe or redirect, run sh with arguments ["-c", "<line>"].
arguments = ["/mnt/data/summarise.py"]startup › runAsUser
Section titled “startup › runAsUser”Optional. Text.
The user to run the command as, one of the capsule’s users. The default user when not set.
runAsUser = "builder"startup › maxDuration
Section titled “startup › maxDuration”Optional. Duration, "hh:mm:ss".
The longest the command may run, as "hh:mm:ss". Five minutes when it is not set.
maxDuration = "00:02:00"startup › wait
Section titled “startup › wait”Optional. true or false. Default: true.
Wait for the command to finish before the next one starts. Set false to start it and move on.
wait = trueA complete example
Section titled “A complete example”From the 21-sandboxes example project:
// A capsule is a short-lived Linux sandbox. This one mounts the sales-data file system,// runs a Python script on the CSV in it, and stops when the script finishes.autoTerminate = truemaxDuration = "00:05:00"
// The file system must exist before you deploy: create it and upload the data first.vfs = [ { vfs = @ref("sales-data") mountName = "data" }]
startup = [ { command = "python3" arguments = ["/mnt/data/summarise.py"] wait = true maxDuration = "00:02:00" }]