Skip to content

CLI commands & background daemons

NexoVirt is one CodeIgniter application plus a set of php spark sub-commands: some run continuously as system services, others are one-shot commands driven by cron, and a few are detached workers the panel starts on its own. The installer sets all of this up, so you normally never run these by hand. This page documents what is running so you can troubleshoot.

The installer installs and enables three systemd units. If one of them is down, the matching part of the panel (live charts, inventory, consoles) stops updating.

UnitRunsPurpose
nexovirt-metricsspark metrics:collectSamples guest metrics (default every 5 s) and node metrics (default every 30 s) into the database for the live charts. Cadence and retention are set under Settings → Metrics.
nexovirt-inventoryspark inventory:collectEvery 5 minutes (inventory.interval), pulls each active host’s nodes, guests, storages and networks into change-only inventory snapshots. Also discovers PBS storages and detects externally made guest state changes.
nexovirt-consoleproxy/console-proxy.php startThe WebSocket proxy that relays browser consoles (xterm.js and noVNC) to Proxmox. It injects the Proxmox auth cookie server-side, so it never reaches the browser. Not a spark command; stop halts it, start -d daemonizes.

deploy/install-cron.sh writes these into the app user’s crontab, inside a marked block that it replaces on every run (hand-added entries outside the block are kept). Installs and updates re-run it, so the schedule always matches the installed version.

CommandCadenceWhat it does
metrics:collect --cronevery minuteSame sampling as the service, as a self-locked cron tick.
metrics:prune --oncedaily, 03:17Enforces retention: guest metrics (24 h), node metrics (180 days), inventory history (keeps each resource’s latest row), logs, error events, webhook deliveries, finished provisioning jobs. Also queues the cleanup of expired migration safety copies.
inventory:collect --onceevery 5 minutesSingle inventory pass.
provision:work --cronevery minuteDrains the provisioning queue: guest create, reinstall, delete and power actions. Required while provision.async=1 (the default).
migrate:work --cronevery minuteSeparate lane for long jobs: cross-host migrations, safety-copy cleanup, failover restores and re-keyed PBS restores. Also drives evacuation, balance and failover runs.
hooks:flush --onceevery minuteSends pending event webhook deliveries with retries. No-op without configured hooks.
mail:flush --onceevery minuteSends queued emails over SMTP. A mail failure never breaks the action that queued it.
crash:flush --onceevery minuteForwards queued crash reports. No-op unless crash reporting is enabled.
alerts:evaluate --onceevery minuteEvaluates alert rules, opens and resolves alerts, notifies by inbox, email and webhook. No-op while alerting is turned off. See Alerts.
logs:forward --onceevery minuteForwards new log entries to the configured SIEM webhook. No-op unless log forwarding is enabled.
firewall:collect --onceevery 5 minutesReads, parses and stores a firewall snapshot per host with a healthy agent.
host:scan --onceevery 15 minutesRead-only system and Proxmox scan per host with a healthy agent (the facts shown on the node page).
vpn:sync --onceevery 15 minutesRe-applies the WireGuard VPN on nodes whose desired state changed. See WireGuard VPN.
backup:run --oncedaily, 02:30Builds a panel backup (database dump plus uploads) and pushes it to the configured destinations, enforcing retention. No-op unless panel backups are enabled.
updates:check --oncedaily, 04:40Polls the NexoVirt update channel and caches the latest signed release metadata.
updates:auto-apply --oncehourly, at :07Installs the signed bug-fix release picked for automatic updates, if auto-update is on. Never installs a feature release. See Updates.
license:checkevery 5 minutesRe-validates the license so a renewal, suspension or tier change shows up promptly. Degrades to Community Edition on an invalid license, never blocks the panel.
dyndns:statusevery 5 minutesRefreshes the status of enabled DynDNS names. No-op without enabled names. See DynDNS.
pbs:prune --oncehourlyRuns due PBS prune (retention) policies.
console-proxy:ensureevery minuteWatchdog: checks the console proxy’s listen port and restarts it if it is down.

One entry runs as root: nexovirt-domain run, every minute. It applies the hostname and TLS settings from Settings → Domain. It is a root-owned script in /usr/local/sbin, not app code: it asks the app (as the app user) what to apply, validates every field and reports the result back.

CommandPurpose
plans:enforce [--once]Suspends plan-assigned guests on expiry or when the traffic limit is exceeded, deletes them after the grace period and resumes traffic-suspended guests on the monthly reset. Off unless enforce.enabled = true in .env, and not scheduled by the installer: run it as a service or from cron if you use plan enforcement. Only touches guests that were created from a plan.

These are started in the background by a panel action. You only run them by hand to debug, or when the PHP proc_open function is disabled on your server.

CommandStarted by
host:onboard <runId>Set up agent: SSH bootstrap of the node agent.
agent:op <runId>Update agent, Remove agent and host delete.
host:rescan <hostId>Rescan host facts on the node page (system and Proxmox facts plus the firewall snapshot).
sdn:provision <projectId> / sdn:deprovision <projectId>Creating, retrying or deleting an SDN project.
backup:run --onceRun now under Settings → Backups.
updates:applyA manual or automatic panel update (hands off to the root updater).
CommandWhen to use it
migrateApplies pending database migrations. The installer and updater run it for you.
agent:register <label> --host=<id>Registers a host agent by hand and prints its one-time bearer token. Normally Set up agent does this.
os-catalog:sync [--force]Pulls the OS template catalog. Without --force only new templates are added; --force also updates already-synced ones.
license:checkRe-validates the license right now (for example after activating Enterprise from the shell).
updates:target auto|manualPrints the exact release version an automatic or manual update would install.
updates:verify <tarball> [auto|manual]Verifies a downloaded release (SHA-256 and signature) before extracting.
updates:linePrints the effective release line.
updates:healthPost-update health check (app boots, database reachable). Exit code 0 or 1.
docs:error-codes [--out=<path>]Renders the error-code catalog as a Markdown table.

Two root-owned scripts in /usr/local/sbin cover the tasks that need root. Root never runs code from the app-user-owned install directory.

CommandPurpose
nexovirt-domain run [--force]Applies the Settings → Domain state (nginx, certificates). Runs from root cron every minute; --force re-applies.
nexovirt-domain resetLockout escape: restores plain IP access over HTTP if a bad hostname or TLS setting made the panel unreachable. Run by hand on the server.
nexovirt-update auto|manualThe updater (verify, back up, migrate, roll back on failure). The app user may run only this, through a sudoers rule; the panel calls it for you.