A template is a single orgo.ai/v1 document, written in YAML or JSON. This page is the field-by-field reference. The canonical machine-readable contract is the JSON Schema at GET /api/template-schema — point your editor at it for autocomplete and inline validation.
Environment variables written to the VM. Keys must be UPPER_SNAKE_CASE. Each value is a literal string, or a {secret: <name>} reference resolved from the launching user’s vault at create time.
secrets: - name: anthropic_api_keyenv: NODE_ENV: production ANTHROPIC_API_KEY: secret: anthropic_api_key
Package and command steps run once when baking the golden snapshot, before app installs. This is where dependencies get pre-installed so launches are instant.
build: apt: [ffmpeg, ripgrep] pip: [requests, httpx] npm: [pnpm] run: # up to 64 shell commands, in order - curl -fsSL https://example.com/install.sh | bash
Files materialized into the VM. Each entry sets exactly one of from or inline.
files: - to: /opt/hello.txt inline: "hello world" - to: /usr/share/backgrounds/bg.png from: https://example.com/bg.png # http, https, git, s3, file, or secret:// - to: /opt/run.sh mode: "0755" # octal permissions inline: | #!/bin/bash echo hi - to: /root/.config/app.json from: secret://app_config # pulled from the vault when: runtime # build (default) or runtime
Field
Description
to
Absolute destination path (or ~/…). No .., no reserved system paths.
from
Source URI: file, git, http, https, s3, or secret://<name>.
inline
Inline file content.
mode
Octal permissions, e.g. "0644".
owner / group
Ownership, resolved against the VM’s /etc/passwd.
when
build (baked into the snapshot) or runtime (re-applied each boot).
to must be an absolute path with no ... Reserved system paths are rejected: /proc, /sys, /boot, /dev, /tmp, /run, plus the Orgo runtime (/etc/orgo, /var/orgo, /orgo, /etc/supervisor, and Orgo’s own binaries under /opt and /usr/local/sbin). Your apps can still write under /opt and elsewhere — only Orgo’s own runtime files are off-limits.
An app bundles an install step with the long-running services, health checks, and ports it needs. Services are managed by supervisord, so they start at boot and respawn on crash.
on_resume is the right place to do per-VM work that depends on launch-time state (like a freshly injected secret), because it runs on every restore — see Secrets.
telemetry: metrics: true # flag the VM as scrape-ready logs: [my-app-server] # service log paths/names to ship otel_endpoint: https://otel.example.com # push OTLP metrics + logs