Box specs describe the machine you need

A machine in your own cloud, written as a TOML file: its CPUs, memory, disk, system and region, and the lnk on it. lnk box create --cloud <cloud> --spec <file> makes a box from it, and lnk box spec <box> prints the one a box was made from.

Every option

Every key is optional. Left out, a key is the least that works, and an empty file makes the box lnk box create --cloud <cloud> makes with no flags.

# web.toml

# The spec itself: what its boxes are called, and a number yours to bump.
name = "web"        # boxes are named web-1, web-2 and so on
version = 3         # each box remembers the version it was made from

# The lnk on the box.
[lnk]
# version = "0.13.0"   # an lnk release to install, with its plugins (default: the latest)
login = true           # leaves lnk signed in as you there; false leaves it signed out

# The machine, as you'd describe one at a store. Every cloud gets the smallest that fits.
[machine]
cpus = { min = 2, max = 8 }                   # a count (cpus = 4) or a range, either end optional
memory = { min = "4 GB", max = "16 GB" }      # a size with its unit, or a range of them
# gpus = { min = 1, max = 2, model = "nvidia-l4" }   # how many, and which; gpus = 1 is exactly one
arch = "x86_64"                               # the processor: x86_64 or arm64
disk = { min = "40 GB", type = "balanced" }   # how big, and balanced or fast
os = "ubuntu-24.04"                           # ubuntu-24.04 or ubuntu-22.04
spot = false                                  # true is cheaper, but the cloud may stop the box
tags = { team = "research" }                  # your tags, on the machine and its disk

# One cloud's own table, named by its kind (`lnk cloud list`). It takes every key
# of [machine] and replaces it on that cloud, and is the only place for region and size.
[machine.aws]
region = "eu-west-2"   # where the box is made
size = "t3.large"      # a machine type, instead of cpus, memory and gpus

[machine.gcp]
region = "europe-west2"                  # a region, or a zone in it
memory = { min = "8 GB", max = "32 GB" } # replaces [machine]'s memory here, whole
spot = true                              # spot on Google Cloud, whatever [machine] says
# size = "e2-standard-4"                 # a machine type here, instead of memory

How a spec is read

A box's setup isn't a key: each stage is a Sandbox Spec your setup script runs on the box, as Set a box up in stages shows. How to use a box spec: Describe a box in a file. Every spec Link reads, side by side: Specs.

vm

An optional VM configuration reference for a box made here or on a machine of your Local Cloud. The path resolves from the box file's folder, or from the current folder when supplied with --vm. The VM manager resolves its compatible approved base and host constraints. A missing reference leaves that choice to host defaults. Cloud machine properties do not configure a local VM. A cloud account's box is a cloud machine, so it refuses vm before anything is made, never nesting a VM or dropping the input.

env

An optional environment reference, independently selected with --env, for every placement. Creation captures the checked file and its declared inputs once, before anything is made. A VM box bootstraps compatible Link programs and verifies the sandbox, then runs uncached preparation and startup inside the private guest. A cloud box starts from the environment's image when it saves stages, then runs its start stages and services on the machine. A missing environment adds no application setup.

Kept for each start

Each box keeps its captured environment and starts it again at lnk box start, never reading its source again. The machine contract describes the saved binding.

Flags and files

Each key is a flag of lnk box create, lnk box size list and lnk box spec, and a flag wins over the file. A file is at most 64 KB. An unknown key, an empty table, or a value that isn't one is refused when the file is read, the error naming its line.

Top level

The spec's own name and version, and how long its boxes live.

name

--spec-name: lowercase letters, digits and dashes, starting with a letter, at most 27; left out, the account's name. --name is still the one box's exact name, and wins over name.

version

--spec-version: a whole number, yours to bump, which each box remembers it was made from; left out, none.

deadline

The optional deadline = "4h" (--deadline 4h) limits a box's lifetime, from one second through seven days. The deadline is shown by lnk box list, including its JSON.

How each cloud ends it

Google Cloud sets the instance's maximum run duration and deletes it at termination. AWS terminates on shutdown and installs a root-owned systemd timer at first boot to power off at the deadline. A process running as root can change that timer.

In an image

lnk box image create leaves the timer out of the image, so a box made from it never ends at the deadline of the box it was saved from.

[lnk]

The lnk installed on the box, and whether it's signed in as you.

version

--lnk-version: a version (0.14.0, or a prerelease as 0.14.0-qa.202610131900), 0.11.0 or later, since releases before 0.11.0 have no plugins; left out, the latest.

From a file

From a file, version can't be behind this computer's lnk, so a spec someone hands you can't install a release with a known hole. To mean a lower one, type --lnk-version yourself.

login

--no-login: true or false, true by default, which leaves lnk signed in as you there; false leaves it signed out.

[machine]

The machine, as you'd describe one at a store: every cloud gets the smallest that fits. region and size go only in a cloud's own table.

cpus, memory and gpus

--cpus and --memory: a count or a size, or a range of them; left out, the default size's. --gpus and --gpu-model: a count or range, and a model; left out, none (Values).

disk

--disk and --disk-type: a min size and a type, balanced or fast; left out, 20 GB, balanced.

arch and os

--arch: x86_64 or arm64, x86_64 by default. --os: ubuntu-24.04 or ubuntu-22.04, ubuntu-24.04 by default.

spot

--spot: true or false, false by default. true is cheaper, but the cloud may stop the box.

tags

--tag key=value: a table of text, your tags on the machine and its disk; left out, none.

region and size

--place: a region or zone (with --cloud), and --size: a machine type, each in a cloud's table only. Left out, the account's region, and a size picked (How the machine is picked).

A cloud's own table

A cloud's table, [machine.<cloud>], is named by the cloud's kind, as lnk cloud list says it: [machine.aws], [machine.gcp], or another adapter's.

What it replaces

It takes the same keys as [machine] and replaces them on that cloud, each key whole, so [machine.gcp] memory above has no say from [machine]'s. region and size go only there, since each names one cloud's, and a cloud's table can't hold another table. A table for a cloud the box isn't on has no say.

Which wins

A flag, then the cloud's table, then [machine], then Link's default. A flag replaces its key in every table. --size and --place go to the cloud the command names with --cloud, and a flag about the machine, such as --cpus, drops a table's size.

Values

What each [machine] key takes, and what the cloud makes of it.

A count or a range

A count or size alone means exactly that, as in cpus = 4. A range is { min = 2, max = 8 } with either end left out, but not both, and min never over max. On the command line it is 4, 2..8, 2.. or ..8. A count is at most 4096.

A size

Sizes are strings with their unit, as "8 GB", "512 MB" or "1 TB", and a bare number is refused. GB means GiB, as both clouds count memory. On the command line it is 8GB.

GPUs

gpus = 1, or gpus = { min = 1, max = 2, model = "nvidia-l4" }. A model alone means at least one. Models are nvidia-t4, nvidia-l4, nvidia-l40s, nvidia-a10g, nvidia-a100, nvidia-h100, nvidia-h200 and nvidia-b200.

arm64

arch = "arm64" gets Ubuntu's arm64 image. The machine type is matched among the cloud's arm64 ones as cpus and memory are, since the default size is x86_64, or it is the arm64 size given. It has no GPUs, because NVIDIA's images are x86_64.

A size of the other processor

A size its cloud lists as the other processor, such as t4g.small on an x86_64 box, is refused.

The disk's size

disk.min is what the box gets, unless its image needs more. NVIDIA's images for a box with GPUs are larger than 20 GB, so such a box gets its image's size, said as it's made.

The disk's type

disk.type is balanced (gp3 on AWS, pd-balanced on Google Cloud) or fast (io2 at 50 IOPS a GB, from 3,000 to 64,000, or pd-ssd). A fast disk is billed for its speed too.

Spot

spot = true is cheaper, but the cloud may take the machine back. It stops the box and never deletes it, so its disk stays and is billed. lnk box list says the cloud stopped it.

Telling the cloud stopped it

AWS says so in the instance's state reason. Google Cloud doesn't, so there it is a spot box found stopped that ran when this computer last saw it, which lnk box stop on another computer looks like too, and the list says both.

Starting again

On AWS it is a persistent spot request, which starts the box again on its own once AWS has the capacity. lnk box delete cancels the request first, and cleanup cancels Link's requests whose box is gone. On Google Cloud, lnk box start <box> starts it.

Tags

tags keys start with a lowercase letter, and keys and values are lowercase letters, digits and dashes, at most 63 each. A box takes at most 40 of yours in all. Keys starting lnk- or aws:, and Name, are Link's or the cloud's, and refused. On Google Cloud they're labels.

A region

region on Google Cloud is a region or a zone in it. A region means its first zone that's up.

How the machine is picked

From the spec's CPUs, memory and GPUs, or its size, among what the cloud has where the box is made (lnk box size list).

The default size

With no cpus, memory or gpus, the box gets the account's default size: t3.small on AWS, e2-small on Google Cloud.

The smallest that fits

Otherwise it gets the smallest that fits, by CPUs, then memory, then GPUs. Memory is at least 2 GB when the spec says none, and a box has no GPU unless it asks. Between equals it takes the cheaper when the cloud gives a price, then the cloud's order: general purpose first, current generation, cheapest family first.

A size

size wins. A machine type has its CPUs, memory and GPUs built in, so a table giving size and any of those is refused. arch with size must be its processor. A size the adapter doesn't list there, such as an older generation or a GPU Link has no name for, is made as given, with a warning, and the cloud says whether it has it.

When nothing fits

The error names the nearest on each side: "the smallest with 4 CPUs has 16 GB, over your max of 8 GB".

GPUs on Google Cloud

A box's GPUs are those built into its machine type (G2, A2, A3, A4), or T4s attached to an N1 machine. Link names an N1 machine with T4s <machine type>.nvidia-tesla-t4.<count>, such as n1-standard-4.nvidia-tesla-t4.1, and size takes that name too. A T4 box is made only in zones that have T4s.

NVIDIA's driver

A box with GPUs gets Ubuntu with NVIDIA's driver: AWS's Deep Learning Base AMI, or Canonical's accelerator image on Google Cloud. Both clouds give a new account no GPUs until you ask them to raise its quota, and lnk box create says where when the cloud refuses.

What lnk box spec prints

lnk box spec <box> prints the spec the box was made from, its flags laid over, as this computer kept it in boxes.toml. --json prints the same fields as JSON. Why it works this way: Decisions.

What its cloud pins

Its cloud's table pins what the cloud says the box is: its size and region, and its disk, os and spot where they differ.

A box from before, or elsewhere

A box made before specs, or on another computer, prints only what the cloud keeps, and its [lnk] is left to the defaults. An [lnk] version behind this computer's lnk is left out too, so the file reads back, and said on stderr with the --lnk-version that makes it again.

[attach]

Existing resources attached to the machine. The box uses these without creating or deleting them, and its own boot disk remains disposable. Removal keeps attached disks and addresses, and Link never formats a disk.

network and address

--network: a GCP network name; on AWS, a subnet ID whose VPC has an existing lnk-box security group. --address: a GCP reserved address name; on AWS, its allocation ID.

identity

--identity: a GCP service account name or email; on AWS, an instance profile name.

disks

Repeatable --attach-disk: persistent disk names on GCP; volume IDs on AWS. An AWS data volume also requires its subnet, in the same availability zone.

Checking them first

lnk box spec --spec service.toml --cloud gcp --check-attachments looks them up without making anything. The cloud refuses missing resources before launching the VM.

Checked reference

The field names below come from link_plugin_box::spec::BoxSpec. Optional values remain unset until the feature resolves its environment or inherited settings.

root: attach, deadline, env, link_tags, lnk, machine, name, self_remove, version, vm
attach: address, disks, identity, network
lnk: login, version
machine: arch, cpus, disk, gpus, memory, os, region, size, spot, tags
machine.*: arch, cpus, disk, gpus, memory, os, region, size, spot, tags
machine.*.cpus: max, min
machine.*.disk: min, type
machine.*.gpus: max, min, model
machine.*.memory: max, min
machine.cpus: max, min
machine.disk: min, type
machine.gpus: max, min, model
machine.memory: max, min

Checked defaults

These values come from the shipped defaults, including nested settings. Omitted optional values have no stored default at this layer.

resolved machine (aws) = {"cpus":{},"memory":{"min":"2 GB"},"gpus":0,"arch":"x86_64","disk":"20 GB","disk_type":"balanced","os":"ubuntu-24.04","spot":false,"tags":{},"matching":false}