CLI
statio --help groups the commands the same way this page does — Setup, Apps & config,
Operate, Maintenance, and Internal (run by systemd & the Action, not by hand).
# Setup — on the server, then in your repostatio init server # wizard: configure + start the agent (CI joins with its own tag:ci OAuth client)statio init integrations # wizard: NPMplus + Cloudflare + public IPstatio init repo # wizard: statio.yaml + how to call the Action
# Apps & config — on the serverstatio app add [name] # wizard: accept an app — image repo, signer identity, domainsstatio app list # list apps; pick one to view its config + setup steps, or edit itstatio app edit <name> # re-run the wizard (current values pre-filled) to change an appstatio app rm <name> # stop accepting an app's deploysstatio env set <svc> KEY=VALUE [--protected] [--required]statio env set <svc> KEY --secret-stdin # ops secret via stdinstatio env list <svc>statio env rm <svc> KEY
# Operate — from a machine ON the tailnet (your laptop or CI), NOT the serverstatio status --target <agent-host> # the agent's health + the apps it acceptsstatio logs <svc> [--target <agent-host>] # deploy audit log (local file, or a remote agent)
# Maintenancestatio upgrade [--check] [--no-restart] # self-update (verifies the checksum)statio doctor [--fix] # environment diagnostics (and safe auto-fixes)statio version # or: statio --version
# Internal — run by systemd & the GitHub Action, not by handstatio agent run --config <path>statio deploy ...statio preflight ... # read-only dry-run: port + proxy/DNS readinessstatio preflight takes the same inputs as statio deploy and sends the same signed payload, but
to the agent’s read-only /preflight endpoint: it checks the app’s host port is free and — if the
statio.yaml requests a public domain — that NPMplus is configured, reachable and the domain is
allowlisted, changing nothing. The Action runs it automatically before each deploy (disable with
the preflight: false input). A failed check is a non-zero exit with the reason and a hint.
The wizards (init server, init integrations, init repo, app add, app edit) are
interactive: run them without flags and they guide you. app list is interactive too — it lets you
pick an app and then view its config (with the workflow snippet and secrets) or re-run the wizard to
edit it. In CI/scripts they accept flags and secrets via --*-stdin; the
Action uses the flag form automatically.
Private images
Section titled “Private images”Nothing to configure on the server. The agent has no GitHub identity, so the Action forwards the
run’s short-lived token (the same GITHUB_TOKEN it pushes with) inside the signed deploy; the agent
uses it only to read the image’s cosign signature and pull it, in memory, then discards it. Keep
packages: write in the workflow permissions. The token is per-run and expires when the job ends —
no credential is ever stored on the server.
Checking a running agent
Section titled “Checking a running agent”Two different checks, for two different places:
- On the server →
sudo statio doctor. The server’s own OS is not a tailnet peer (the agent runs in userspace via tsnet), so you can’t reach the agent from the server itself —doctorchecks it locally instead (service state, config, the agent’s last log line if it’s down). - From your laptop or CI (a machine on the tailnet) →
statio status --target <agent-host>queries the agent’s/statusover the tailnet and prints its health and the apps it accepts. The<agent-host>is the agent’s MagicDNS name (e.g.statio.your-tailnet.ts.net) — the addressinit serverprinted.statio logs <svc> --target <agent-host>fetches a service’s deploy history the same way.
Self-update & diagnostics
Section titled “Self-update & diagnostics”statio upgradedownloads the latest release, verifies its sha256 againstchecksums.txt, replaces the running binary in place, and restarts thestatio-agentservice when it’s active (so the new binary takes effect immediately).--no-restartskips that;--checkonly reports whether a newer version exists.statio doctorchecks your environment: binary version vs latest, Docker daemon, git, gh and whether it’s logged in, cosign (only relevant in CI), the agent config and the secret files it references, the state dir and the service, and GitHub reachability. It runs the same secret-file check the agent runs at boot, so a missing or world-readable secret is caught here instead of as a silent crash-loop — and when the service is down it prints the agent’s last log line (read as root) so you see why. On a server run it withsudo statio doctorfor the full picture — the config, the secret files and the service all need root, while the gh check is still done as the user you sudo from.statio doctor --fixresolves what it safely can on its own (create a missing state dir, tighten a loose secret’s perms, restart a crash-looping agent) and tells you which remaining fixes need asudore-run. A missing secret it can’t fabricate — it points you at theinitstep that regenerates it.- The CLI also nudges you when a newer version exists. Disable it with
STATIO_NO_UPDATE_CHECK=1.
Server install & update
Section titled “Server install & update”curl -fsSL https://statio.accentio.dev/install.sh | sudo shRe-running the installer updates only when a newer version exists, and restarts the statio-agent
service when it’s running. STATIO_VERSION=vX.Y.Z pins a version; STATIO_BINDIR=/usr/bin changes
the install dir.