CLI Reference
Beyond install and uninstall (see Install Alta VMS), the altavms 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 altavms help for the full list, or altavms help <command> for one command’s detail.
Service
Section titled “Service”| Command | What it does |
|---|---|
altavms start [--force] | Validates the config, then systemctl start altavms. |
altavms stop | systemctl stop altavms. |
altavms restart [--force] | Validates the config, then systemctl restart altavms. |
altavms enable [--now] | systemctl enable [--now] altavms — start at boot. |
altavms disable [--now] | systemctl disable [--now] altavms. |
altavms logs [-f] [-n N] [--since W] [--until W] [-o FMT] | journalctl -u altavms --no-pager, with your flags. -f follows. |
altavms 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 |
|---|---|
altavms 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. |
altavms 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, and the reconcile-sweep safety settings. Every finding is paired with a fix. |
altavms 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 |
| Command | What it does |
|---|---|
altavms backup [--output PATH|-] [--no-secrets] [--no-maps] | Consistent hot backup — no downtime. See Backup & Restore. |
altavms restore <archive> [--dry-run] [--stop-service] | Verified, guarded restore. See Backup & Restore. |
altavms reset-password <email> | 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 |
|---|---|
altavms 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. |
altavms config print [--format text|json] | Prints the effective, merged configuration with every secret redacted — safe to paste into a support ticket. |
altavms 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.
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 'ALTAVMS_LOG_LEVEL=debug' | sudo tee -a /etc/altavms/altavms.envsudo altavms 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 Alta VMS’s. If altavms 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://vms.cesbo.com/install.sh | shaltavms status warns if the running process predates the binary now on disk — a sign a restart didn’t happen or was interrupted.
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 add the public origin to http.allowed_origins in /etc/altavms/config.yaml and sudo altavms 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 altavms status.