panelOwl docs 1.15.0

panelctl reference

panelctl is the admin command line. It must run as root and talks to the minipaneld helper over its Unix socket; every change is validated and audited there exactly like a panel action. Output is human-readable; add --json (before the command) for scripts.

panelctl [--json] [--socket PATH] <command> [args]

Errors print one line to stderr and exit with status 1 (2 for usage errors).

Accounts

panelctl account create <name> --domain <domain> --email <address> [--php 8.4] [--ssh off|sftp|shell] [--password-stdin]

Creates the Unix user (uids from 2000), home layout, primary domain, Apache vhost, PHP-FPM pool, DKIM key, SFTP access, and requests a certificate if the domain already points here. Prints the panel URL, the generated password (shown once) and the DNS records the client needs. Account names: 3–16 characters, a-z0-9, starting with a letter. The primary domain cannot be changed later. --ssh defaults to sftp; --password-stdin reads a password instead of generating one.

panelctl account list
panelctl account show <name>

list marks accounts whose configuration is not applied with ! after the state; show prints domains, SSL state, disk usage and the apply state/error.

panelctl account suspend <name>
panelctl account unsuspend <name>

A suspended account's sites return a 503 page, the Unix login is locked, SFTP/SSH groups removed, PHP pools removed, crontab removed, mailbox logins refused (mail is still accepted and stored), and the client cannot log in. Unsuspend restores everything from the state database.

panelctl account modify <name> [--email E] [--php V]

Changes the contact email and the default PHP version used for new domains (each existing domain keeps its own version; change those in the account's Domains page).

panelctl account delete <name> --confirm <name> [--no-backup]

Removes the account, its home, databases and database users, mailboxes, DKIM keys, certificates and Unix user. First it writes minipanel-deleted-<name>-<time>.tar.gz into the backup directory with everything needed to bring the account back, kept for [backup] keep_deleted_days (30); if the archive fails, nothing is deleted. --no-backup skips the archive and makes the deletion irreversible. The same termination is available in the admin UI (with your authenticator code).

panelctl account restore <file> --confirm

Recreates a terminated account from its minipanel-deleted-… archive: panel settings (domains, mailboxes and their passwords, forwarders, databases, database users and grants, cron jobs, SSH keys, quota, 2FA), the Unix user with its old uid when free, files, mail, databases and DKIM keys; certificates are requested again. Refused while the account name, one of its domains or databases exists.

panelctl account passwd <name> [--password-stdin]

Sets a new panel/SFTP/SSH password; generates and prints one unless --password-stdin. Use this for clients who are locked out or lost their password (there is no self-service reset).

panelctl account limits <name> [--cpu PCT] [--memory SIZE] [--io-weight N] [--io-read SIZE] [--io-write SIZE] [--procs N] [--cooldown on|off]
panelctl account limits <name> --restore
panelctl limits status | usage | tick

Resource limits (D-100). Each account runs its PHP in its own systemd slice (minipanel-<name>.slice) and its SSH/cron sessions in user-<uid>.slice; both get the account's CPU share (--cpu 100 = one core), memory cap, IO weight and read/write bandwidth caps, and process cap, applied live. 0 means unlimited. limits status shows which cgroup controllers this host enforces (IO caps need the io controller, which containers usually lack) and lists paused accounts; limits usage shows live CPU %, memory, processes and IO per account. With --cooldown on, the per-minute tick (minipanel-limits.timer) pauses an account that stays at its limit for [limits] cooldown_after_min minutes (its sites show a "temporarily paused" page, its PHP is stopped) and resumes it after cooldown_for_min; you are emailed both times, and --restore resumes it at once. Defaults for new accounts come from [limits] in config.toml.

Domains and certificates

panelctl ip list
panelctl ip add <address> [--public <public address>] [--label <text>]
panelctl ip update <address> --public <public address> [--label <text>]
panelctl ip remove <address> [--force]
panelctl ip assign <address> <domain>...
panelctl ip assign shared [--v6] <domain>...

Additional IP addresses (D-96). add accepts only addresses already configured on the server (netplan), never the main one; --public is the address clients put in DNS when the server is behind NAT. assign moves domains to an address (their vhosts answer there and, until DNS changes, on the old address); assign shared moves them back. remove is refused while domains use the address unless --force, which moves them to the shared address. list shows usage, whether each address is still configured, and spare configured addresses.

panelctl dns status
panelctl dns setup powerdns --ns ns1.example.net --ns ns2.example.net [--secondary <ip>]...
panelctl dns setup cloudflare --token-stdin [--account-id <id>]
panelctl dns setup cpanel --url https://dns1.example.net:2087 --token-stdin [--user root] [--insecure]
panelctl dns setup none
panelctl dns test
panelctl dns zones
panelctl dns zone <domain>
panelctl dns sync [<domain>]
panelctl dns tick

DNS management (D-101). setup powerdns installs PowerDNS on this server and switches to it; cloudflare and cpanel read the API token from standard input (echo "$TOKEN" | panelctl dns setup cloudflare --token-stdin) so it never appears in a process list; the token is kept in /etc/minipanel/dns-secret (root only). setup none stops managing DNS and leaves the zones at the provider. zones lists every zone with its status, zone prints a zone's records (automatic, custom, external), sync publishes now, and tick is what minipanel-dns.timer runs every five minutes. See Operations → DNS.

panelctl page show suspended|limited|<domain>
panelctl page set suspended|limited|<domain> --file <html>
panelctl page reset suspended|limited|<domain>

Custom 503 pages (D-102): suspended is shown on the sites of suspended accounts, limited is the default for sites paused by the resource limiter, and a domain name addresses that domain's own pause page (what the client edits). Files are static HTML (256 KiB at most) stored next to the stock pages in /var/lib/minipanel/pages/; reset goes back to the stock file.

panelctl account quota <name> <size>
panelctl quota status | enable

Disk quotas: size is 500M, 10G, 1T or unlimited; account create takes --quota too. quota enable switches on Linux user quotas for the filesystem holding the homes — see Operations → Disk quotas.

panelctl domain list [--account <name>]
panelctl ssl status
panelctl ssl retry <domain>
panelctl ssl deployed <cert-name>
panelctl ssl tick

ssl status lists every certificate lineage with state (pending_dns, issuing, active, failed), covered names and expiry. retry forces an issuance attempt now (after the client fixed DNS). deployed is what certbot's renewal hook calls to reload services; you rarely run it by hand. tick is what the hourly timer runs: retries pending domains with backoff and expands certificates whose www name started pointing here.

PHP

panelctl php list
panelctl php install <version>
panelctl php set-default <version>

install fetches the version from the PPA, adds it to config.toml and writes the placeholder pool; clients then see it in the panel. set-default changes the version used for new accounts.

Maintenance

panelctl rebuild [--account <name>]

Re-renders every managed file (vhosts, pools, sshd drop-in, crontabs, mail maps, DKIM keys, database grants) from the state database and reloads services. Safe to run any time; it is how the installer upgrades and how a failed apply is repaired.

panelctl doctor

Checks services, configuration syntax (Apache, PHP-FPM, Postfix, Dovecot, sshd), disk space, MariaDB, hostname DNS, certificate expiry, unapplied accounts and cron.allow. Exit status 1 if anything failed. Works even when minipaneld is down (it then reports the daemon as failed and checks services directly).

panelctl audit [--account <name>] [--since 24h] [--limit 100]

Prints the newest entries of /var/log/minipanel/audit.log: time, caller (admin or client, uid, client IP), account, action, target and result. Entries never contain passwords or file contents.

panelctl backup run [--account <name>]
panelctl backup list
panelctl backup restore <file> [--account <name>] --confirm

Writes, lists and restores backup archives; see Operations → Backups. A full restore (no --account) restarts minipaneld and rebuilds everything; --confirm is always required because existing data is overwritten.

panelctl admin create <name> [--password-stdin]
panelctl admin list
panelctl admin passwd <name> [--password-stdin]
panelctl admin totp-reset <name>
panelctl admin delete <name>

Logins for the admin web UI on port 2087. create and passwd print a generated password once; two-factor authentication is set up at the first login and can be reset here when a device is lost.

panelctl config show
panelctl config set KEY VALUE
panelctl notify [--test]

Server settings without re-running the installer: public_ipv4, public_ipv6 (none), admin_email, notify_email, notify (on/off), fail2ban_ignore (IPs/CIDRs never banned, space or comma separated, '' clears) and update_url. The value is validated, config.toml is rewritten and minipaneld restarts. notify mails the admin (see Operations); --test sends the current state right away.

panelctl usage refresh

Re-measures every account's disk usage (normally done daily by minipanel-usage.timer).

panelctl ping
panelctl version

ping shows daemon version, uptime and schema version.

JSON output

panelctl --json account show acme | jq .domains[].ssl_state
panelctl --json ssl status
panelctl --json doctor | jq '.checks[] | select(.status != "ok")'