Skip to content
Alpha: for testing only; it does not yet meet the Cyber Resilience Act’s requirements. Status and limits →

Your first environment

An environment is what runs on a production or staging server: a set of Kubernetes-style YAML files in a Git repository, which Podman runs on the server as systemd units. The hub fetches the branch every minute and hands the files to the server’s agent; the server needs no Git and no credential of its own.

$ vai host create web-1 --env production

The hub creates the server in the hub’s project from the release’s image; its agent enrolls over the private network. On Hetzner, hosts were ready 60–70 s after host create (lab run, 20 October 2026).

There is no vai subcommand for this yet; the portal or one signed request sets it (an owner’s device):

$ vai api PUT /clusters/<host id>/environment '{"name": "shop", "repository": "https://git.example.com/acme/shop.git", "branch": "main", "path": "deploy"}'
  • path is the directory of the YAML files; dataSizeMiB the data volume (default 1024, grown, never shrunk); token a read-only token for a private repository, stored encrypted and never shown again.
  • Secrets live in the repository as a SOPS file, secrets.prod.enc.env, encrypted to the host’s age recipient (vai api GET /clusters/<host id>/environment shows it). Twins read secrets.twin.enc.env, encrypted to the twins’ recipient, so a twin never holds production’s secrets.

A twin’s data comes from your repository, not from production, unless an owner allows a copy on purpose. Put the seed under the environment’s path:

  • .vaicoa/seed.yaml: one Job that fills the empty data volume before the units start;
  • .vaicoa/seed-files/: small files the Job reads (at most 200 files, 512 KiB together);
  • .vaicoa/web.yaml: the entry points the twin proxy serves ({entrypoints: [{label, port}]}).

The directory was called pbx/ before the rename. The hub still reads pbx/ for one release, with a warning in its log; rename it to .vaicoa/.

After the seed runs, the twin takes a checkpoint; vai twin reset returns to it.

$ vai twin create --production web-1 --task task-42 --branch fix/42 --ttl 4
$ vai open twin task-42

The twin runs your environment from that branch on a server of its own in the twins’ project, with seed data. It opens no port to the internet: vai open twin asks the hub for a grant from your address, valid an hour, and opens the page through the hub. On Hetzner a twin was ready in 44 s (lab run, 20–21 October 2026). It expires after its time to live (1 to 72 hours, default 4), or vai twin delete task-42 --confirm task-42 ends it.

Read more about twins.