CLI & daemons
NexoVirt is one CodeIgniter application plus a set of php spark sub-commands: some run continuously as
long-lived daemons, others are one-shot commands driven by cron. The installer sets all of this up for
you, start to finish, so you normally never run these by hand. This page documents what is running so you
can troubleshoot, and to satisfy curiosity.
Persistent daemons
Section titled “Persistent daemons”These are started by the installer as system services and run continuously. If one of them is down, the matching part of the panel (metrics, provisioning, consoles) stops updating.
| Command | Purpose |
|---|---|
metrics:collect |
Samples guest metrics (default every 5s) and node metrics (default every 30s) into the database, feeding the live charts. Cadence is settings-driven under Settings → Metrics. |
inventory:collect |
Every 5 minutes, pulls each active host’s nodes, guests, storages and networks into a change-only inventory snapshot, with offline-guest IP carry-forward. |
provision:work |
Drains the async provisioning_jobs queue: guest create / reinstall / delete / power actions, running the real Proxmox call and a targeted inventory refresh. Required whenever provision.async=1 (the default). |
jobs:work |
Drains the generic jobs queue (App\Libraries\Jobs\JobRunner): currently Ansible playbook runs (ansible_run), with live log streaming back to the panel. |
proxy/console-proxy.php start |
The Workerman WebSocket proxy that relays browser consoles (xterm.js / noVNC) to Proxmox, injecting the server-side PVE auth cookie so it never reaches the browser. Not a spark command: a standalone script; stop halts it, start -d daemonizes. |
plans:enforce |
Optional daemon. Suspends plan-assigned guests on expiry or traffic-over-limit, auto-deletes after the grace period, and auto-resumes traffic-suspended guests on the monthly reset. Off unless enforce.enabled=true in .env. |
Cron-scheduled commands
Section titled “Cron-scheduled commands”Installed into the system crontab by deploy/install-cron.sh (idempotent, re-run it after a git pull
if the schedule ever changes). Each line below is the actual installed cadence.
| Command | Cadence | What it does |
|---|---|---|
metrics:collect --cron |
every minute (self-locked ~55s loop) | Same sampling as the daemon form, wired as a cron tick instead of a supervised service. |
metrics:prune --once |
daily, 03:17 | Enforces metrics retention (guest_metrics 24h, node_metrics 6 months) and prunes inventory_snapshots, keeping each resource’s latest row. |
inventory:collect --once |
every 5 minutes | Single-pass inventory snapshot (ticking this one would over-poll Proxmox). |
provision:work --cron |
every minute (~55s loop) | Drains the provisioning queue. |
mail:flush --once |
every minute | Sends queued emails from the notifications outbox over SMTP. Best-effort: a mail failure never breaks the action that enqueued it. |
crash:flush --once |
every minute | Forwards queued crash reports to the vendor admin. No-op unless crash.enabled and crash.endpoint are set. |
alerts:evaluate --once |
every minute | Evaluates alert rules against metrics, inventory and events; opens or resolves alerts and notifies via inbox, email and webhook. Off unless alerts.enabled (default on). |
jobs:work --cron |
every minute (~55s loop) | Drains the generic jobs queue (see above). |
firewall:collect --once |
every 5 minutes | Reads, parses and persists a firewall snapshot per active host with a healthy agent; skips agent-unhealthy hosts. |
host:scan --once |
every 15 minutes | Runs read-only system + Proxmox scan jobs against every active host with a healthy agent, persisting system/pve inventory snapshots. Skips agent-unhealthy hosts. |
backup:run --once |
daily, 02:30 | Builds a full panel backup (database dump + uploads/images), pushes it to the configured destination(s), enforces retention. Gated by backup.enabled. |
updates:check --once |
daily, 04:40 | Polls the NexoVirt update channel and caches the latest release notes for the dashboard (the panel never calls the update channel directly). |
pbs:prune --once |
hourly | Evaluates due PBS prune (retention) policies, gated per-policy by interval_hours. |
console-proxy:ensure |
every minute | Watchdog: port-health-checks the console proxy’s listen address and start -ds it if it is down. |
Setup and one-off commands
Section titled “Setup and one-off commands”Not scheduled, run manually (or spawned automatically by the panel) for a specific task.
| Command | When to use it |
|---|---|
key:generate |
First-time setup: generates the app encryption key in .env. |
migrate |
Applies pending database migrations. Run after every install/update and whenever a feature note above says “deploy needs php spark migrate”. |
db:seed AdminUserSeeder |
First-time setup: seeds the initial admin account from SEED_ADMIN_USER/SEED_ADMIN_PASS. |
agent:register --host=<id> "<label>" |
Registers a new host agent and prints a one-time bearer token, used when linking an agent by hand instead of through Hosts → Set up agent. |
host:onboard <runId> |
Detached worker that performs a single host onboarding run (SSH bootstrap of the agent). Spawned automatically by the onboarding modal; run manually only if proc_open is restricted on your box. |
agent:op <runId> |
Detached worker for a single agent lifecycle operation (remove / remove-full / update), spawned automatically by the corresponding panel action. |
os-catalog:sync |
Pulls and seeds the Admin-managed OS-template catalog. Wired into the installer for a pre-loaded fresh install; safe to re-run any time. |
license:check |
Revalidates the install’s license against the central NexoVirt admin and caches the verdict (the panel reads the cached result on every page). Recommended daily via cron. |
domain:apply [--force] |
Applies the hostname/TLS state from the domain.* settings written by Settings → Domain. Idempotent (no-ops when unchanged); recommended on a root cron every minute so a domain change in the panel takes effect within about a minute. Must run as root. |
domain:reset |
Lockout escape hatch: restores IP-only access (resets domain.allow_ip, base URL, the HTTP catch-all vhost) if a misconfigured hostname or TLS setting makes the panel unreachable. Run as root, by hand, on the server. |
docs:error-codes [--out=<path>] |
Renders the error-code catalog as a Markdown table, either to stdout or to a file. This is how that reference page is generated from source. |