CLI Reference
Beyond install and uninstall (see Install Vision), the vision binary wraps the rest of day-to-day operation: starting and stopping the service, checking its health, backing up and restoring data, and inspecting configuration. Each command is a thin, honest wrapper — most print the underlying systemctl or journalctl command they run (to stderr, so piped stdout stays clean), and those raw commands remain fully supported if you’d rather use them directly.
Run vision help for the full list, or vision help <command> for one command’s detail.
Service
Section titled “Service”| Command | What it does |
|---|---|
vision start [--force] | Validates the config, then systemctl start vision. |
vision stop | systemctl stop vision. |
vision restart [--force] | Validates the config, then systemctl restart vision. |
vision enable [--now] | systemctl enable [--now] vision — start at boot. |
vision disable [--now] | systemctl disable [--now] vision. |
vision logs [-f] [-n N] [--since W] [--until W] [-o FMT] | journalctl -u vision --no-pager, with your flags. -f follows. |
vision logs never needs root: journal reads work for members of the systemd-journal (or adm) group. If you see no entries, add your user to that group or run it with sudo.
Diagnostics
Section titled “Diagnostics”| Command | What it shows |
|---|---|
vision status [--json] [--verbose] | Unit state, the same checks /readyz runs, config/data paths and sizes, and two drift warnings: a binary that was replaced without a restart, and root-owned WAL sidecar files the service can’t write to. A License line shows the license file’s public ID, or not activated (the live state and expiry are on Settings → License). |
vision doctor [--json] [--config PATH] [--db PATH] | An offline checkup for a box where the service won’t start: config validation, schema/environment/keyring checks, systemd unit shape, a database integrity check and schema-version check, file ownership, free disk space, the effective enabled-workers set, the reconcile-sweep safety settings, the license file (exists, owner vision, mode 0600, granted by the unit), and whether the license servers answer (warning only — see Licensing). Every finding is paired with a fix. |
vision version | Prints the binary version and build time. |
Both status and doctor work without root — root-only checks are shown as skipped rather than failing. status never exits 0 while the service is down, so it’s safe to use in monitoring scripts:
| Exit code | Meaning |
|---|---|
0 | ok |
4 | not installed |
5 | unit not active |
6 | active, but not ready |
On a fresh install, status reports Not ready: no Alta server yet with the address of Settings → Connections — add a server and it turns ready.
| Command | What it does |
|---|---|
vision backup [--output PATH|-] [--no-secrets] [--no-maps] [--force] [--recover-wal] [--db PATH] [--config PATH] | Consistent hot backup — no downtime. See Backup & Restore. |
vision restore <archive> [--dry-run] [--stop-service] [--yes] [--force-key-mismatch] | Verified, guarded restore. --yes accepts the host-specific prompt in scripts. See Backup & Restore. |
vision reset-password <email> [--url BASE] [--config PATH] [--db PATH] | Mints a one-time password-reset link for a locked-out admin. See Recover a forgotten password. |
Configuration
Section titled “Configuration”| Command | What it does |
|---|---|
vision config validate [--config PATH] [--env-file PATH] | Checks the installed configuration exactly the way boot would — the same merge of config.yaml and the systemd env file. |
vision config print [--format text|json] | Prints the effective, merged configuration with every secret redacted — safe to paste into a support ticket. |
vision config print --reference | Prints the full annotated reference configuration (every key, its default, and a description) — no installed config needed. |
Neither config subcommand needs root.
| Command | What it does |
|---|---|
vision install [--no-restart] | Installs or upgrades the service without replacing config or secrets. A changed binary restarts an active service unless --no-restart is set. |
vision uninstall | Removes the service but keeps config and data. |
vision uninstall --purge [--yes] [--no-backup] | Also deletes config, data, the system user, and binary. Takes a final backup and requires purge <hostname> confirmation; --yes is for scripts. Avoid --no-backup unless the data is disposable. |
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 | success |
1 | attempted and failed |
2 | usage error |
3 | precondition failed — not Linux, no systemctl, or needs root |
4 | not installed (no unit, config, or database found) |
5 / 6 | status only — see the table above |
Root policy
Section titled “Root policy”- Mutating commands (
start,stop,restart,enable,disable,install,uninstall,restore) check for root themselves and refuse with exit3rather than lettingsystemctlfall through to a polkit prompt — which would hang forever without a terminal (cron, CI, a pipe). - Read-only commands (
status,logs,config,doctor) never require root; they degrade individual rows or checks instead.
Changing the log level
Section titled “Changing the log level”The log level is fixed at boot — there’s deliberately no runtime toggle. Set it in the env file and restart:
echo 'VISION_LOG_LEVEL=debug' | sudo tee -a /etc/vision/vision.envsudo vision restartRemember to remove it afterwards — debug is verbose.
Journal sizing
Section titled “Journal sizing”Service logs are structured JSON on stdout, which lands in journald — log rotation is journald’s job, not Vision’s. If vision logs shows the journal eating disk space, cap it in /etc/systemd/journald.conf:
[Journal]SystemMaxUse=1Gthen sudo systemctl restart systemd-journald.
Upgrading
Section titled “Upgrading”Re-run the installer with the new binary — it’s idempotent (config and secrets are never overwritten) and restarts the service once the binary has actually changed:
curl -fsSL https://vision.cesbo.com/install.sh | shFor a controlled maintenance window, run the newly downloaded binary without restarting, then apply it when ready:
sudo /path/to/new/vision install --no-restartsudo vision restartvision install also restarts a service still running an older copy of the binary — the one-liner moves the new binary into place first. vision status warns if the running process predates the binary on disk.
Reverse proxy / TLS
Section titled “Reverse proxy / TLS”The binary has no TLS listener by design — production terminates TLS at a reverse proxy in front of it. A minimal nginx site:
server { listen 443 ssl; server_name vms.example.com; ssl_certificate /etc/letsencrypt/live/vms.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/vms.example.com/privkey.pem;
location / { proxy_pass http://127.0.0.1:3303; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
# SSE (alerts/status feeds) and long-lived requests: proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 3600s; }}or Caddy, which handles certificates automatically:
vms.example.com { reverse_proxy 127.0.0.1:3303 { flush_interval -1 }}Then, in /etc/vision/config.yaml, add the public origin to http.allowed_origins, set http.secure_cookies: true, and run sudo vision restart. If you also set http.internal_addr for a separate metrics/health listener, don’t point the proxy’s own health check at /readyz on the public listener — see the note printed by vision status.