Last active 1751737843 Unlisted

threes-container.md Raw

Booting a container directly on Threes

threes can boot a container that runs on a VM of its own. This is designed to balance the ease of building and shipping containers with the security benefits of an isolated VM.

Pre-requisites

  1. A container base image, built via this repository
  2. A container you actually want to run

Setup

$ threes network create myapp

(Or whatever- I'll use this name in this doc

Creating

$ threes vm create -i container -t teeny -n myapp -k "$(cat ~/.ssh/id_ed25519.pub)" myapp
2025/07/05 17:15:24 myapp
2025/07/05 17:15:24     ID: d1klra72hcamemlkvns0
2025/07/05 17:15:24     Management Address: 10.10.133.145  
$ threes vm kv upsert -p image=my-image -p version=latest -p port=8080 d1klra72hcamemlkvns0

the threes vm kv upsert command

A threes vm can have an arbitrary set of key/value pairs attached to it, which can be read from within the virtual machine.

Key/Value pairs can either be public or secret. The difference is that only the VM can access secret values; everyone else sees (for instance):

hrees vm kv get d1klra72hcamemlkvns0
2025/07/05 17:46:06 version = "latest"
2025/07/05 17:46:06 PASSWORD = "** REDACTED SECRET VALUE **"
2025/07/05 17:46:06 image = "thomaspoignant/hello-world-rest-json"
2025/07/05 17:46:06 port = "8080"

The container base image uses these Key/Value pairs to derive a container to run; it expects a key called image- without this, it will fail. The keys version and port have sensible defaults of latest and 8080 respectively.

Any key in all caps will be treated as an environment variable.

Next Steps

From here, it's easy enough to access your container app via http://myapp:8080 on the tailnet, or to slap a reverse proxy in front of it.

As always with threes, the name on the tailnet is derived from the name of the vm. The command:

$ threes vm create -i container -t teeny -n myapp -k "$(cat ~/.ssh/id_ed25519.pub)" blahhhhhh

Would result in the container being available at http://blahhhhhh:8080.