PLATINUM DOCS
Self-hosting

Sandbox hosts

Enroll a KVM machine with a one-time install command, then check it is ready.

A sandbox host runs your sandboxes as micro-VMs. Enroll one with a one-time install command from the control plane, and repeat it for each extra host.

Check what you need

NeedDetail
A machineUbuntu 24.04 on bare metal, with /dev/kvm. See Hardware.
RootThe installer runs as root and reboots the machine at the end.
A control planeRunning, and reachable from this machine. See Installation.
Free ports:80 (edge proxy) and :18048 (control channel).

Mint an install command

Minting needs the ADMIN_TOKEN from .env. A host joins the region you name: eu-west or us-east by default.

# on the control plane, in platinum/infra/compose
ADMIN_TOKEN=$(grep '^ADMIN_TOKEN=' .env | cut -d= -f2)
curl -s -X POST https://api.example.com/v1/admin/hosts/bootstrap-tokens \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H 'content-type: application/json' \
  -d '{"label":"host-1","region":"eu-west"}'
FieldDefaultMeaning
labelnoneFree text, shown when you list tokens.
regionnoneThe region the host joins. The installer refuses to run without one.
zonethe regionThe zone within the region.
ttl_seconds86400Token lifetime, from 60 seconds to 7 days.

The response carries install_command and token_returned_once. The plaintext token appears only in this response.

Regions come from the placement.regions config key. To add your own, see Configuration.

Run the installer

Run the printed install_command as root on the new machine.

# on the sandbox host
curl -fsSL -H 'Authorization: Bearer htok_…' https://api.example.com/install.sh \
  | sudo bash -s -- htok_… https://api.example.com eu-west eu-west

The arguments after the token are the API URL, region and zone. When the control plane reaches this host on a private address, append it as a fifth argument. sudo strips environment variables, so pass these as arguments.

The installer logs to /var/log/platinum-install.log and reboots the machine when it is done. Set PT_INSTALL_REBOOT=0 to reboot yourself.

The script is served only for a valid token, because it embeds the object storage keys and the control-channel token.

Check the host is ready

After the reboot the host agent registers, runs a self-test, and moves from verifying to ready.

# on the sandbox host
sudo journalctl -u platinum-host-agent -b | grep -E 'registered as|self-test'
# [host-agent] registered as host_…
# [host-agent] self-test passed (…) → state=ready
# on the control plane
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" https://api.example.com/v1/admin/hosts

Each host row carries its state and hb_age_s, the seconds since its last heartbeat. A host gets sandboxes once it is ready.

Open the network paths

FromToPortFor
HostControl plane443 (or 80)Install, registration, heartbeats
HostControl plane5432Postgres, read by the edge proxy
HostControl plane9000The bundled object store, if you run it
Control planeHost18048Exec, files and terminals
Control planeHost80Preview traffic, through the edge proxy

Manage install tokens

ActionRequest
CreatePOST /v1/admin/hosts/bootstrap-tokens
List the last 100GET /v1/admin/hosts/bootstrap-tokens
RevokeDELETE /v1/admin/hosts/bootstrap-tokens/<id>

Remove a host

  1. Drain it: POST /v1/admin/hosts/<id>/drain. Add {"dry_run":true} to preview, or {"mode":"now"} to stop running sandboxes too.
  2. Delete it: DELETE /v1/admin/hosts/<id>. This revokes the host's key, and returns 409 while something still depends on it.
  3. On the host, stop the services:
sudo systemctl disable --now platinum-host-agent platinum-edge-proxy platinum-edge-env-sync

Add more hosts

Mint a new command and run it on each machine. Before a second host, connect object storage: without it a template exists only on the host that built it.