Admin web UI
Since version 1.2 there is a browser view for admins at
https://<server hostname>:2087/ (the
port WHM uses, for the cPanel-minded). It shows the whole server and
covers the day-to-day account work; anything destructive or server-level
stays on the command line.
What it does
The pages and their names follow WHM, so admins coming from cPanel find things where they expect them. The menu on the left (a slim bar at the top on a phone) groups them into Accounts, Server and System; Home shows a tile for each function plus the server's vital signs and what needs attention.
| Page | Contents |
|---|---|
| Home | tiles for the account functions, a search box, server usage graphs (CPU, memory, disk IO for the last hour, 24 hours or 7 days, sampled every minute) with the busiest accounts of the last minute, account count, disk used, certificate warnings, health summary, updates, what needs attention. Every admin page shows the load average top right. |
| List Accounts | every account with its domain, user, contact email, created date, disk used against its quota, state; search by domain, account name or email; filter by active, suspended or needs attention; per account Manage, Modify, Terminate; tick several accounts to suspend or unsuspend them together |
| Create a New Account | domain, username, contact email, disk quota, PHP version, shell access; the password is shown once, with the client's DNS records |
| Account | details, domains with certificate state and retry, recent audit entries; buttons for Manage, Modify, Domains, Email, Databases, Files, Terminate; suspend / unsuspend, reset the client's password |
| Modify an Account | contact email, default PHP version for new domains, shell access, disk quota |
| Terminate | what will be removed, then the typed account name and your current authenticator code; the account is archived first (see below) |
| List Domains | every domain on the server with its account, IP address, document root, PHP version and certificate; search, filters for certificates and IP address; tick domains and assign them to an IP address; links to the domain's DNS records |
| IP Addresses | the shared address and every additional one with its public (DNS) address, how many domains use it and whether it is still configured; add an address (spare addresses on the server are suggested), edit its public address or label, remove it |
| SSL | every certificate lineage, retry a pending or failed one |
| Backups | archives on disk, run a full backup now; archives of terminated accounts show how long they are kept |
| Audit Log | every audited action, filter by account and time; admin actions show the admin's name |
| Server | version, hostname, health checks in full, admin logins |
| Updates | installed vs latest release, check the feed, install the newer release with one confirmation, installer log |
| My Login | change your own password |
Not in the web UI, by design: restoring backups and terminated
accounts, rebuild, installing PHP versions, and managing
admin logins. Those are panelctl commands over SSH.
Manage: working inside an account
Manage opens the account's own panel inside the
admin UI, at
https://<hostname>:2087/cp/<account>/ (WHM's
"log in to cPanel", without leaving 2087 or knowing the client's
password). Everything the client can do is available: domains and DNS
records, PHP settings, databases and phpMyAdmin, SSH keys, cron jobs,
files, email, logs, backup downloads.
- A banner on every page says which account you are managing and as which admin.
- Every change is recorded in the audit log with your admin name and the account.
- The client's own password and two-factor settings are not reachable;
reset the password from the account page instead. Restores from the
client's Backups page need the client's password, so as admin use
panelctl backup restore FILE --account NAME --confirm.
IP addresses
Every site uses the server's shared address until you assign it another one. To spread sites over several addresses (say 10 on one, 2 on another, 30 on a third):
- Configure the addresses on the server first.
panelOwl never changes network settings; add the addresses with netplan
(or your provider's panel) so
ip addrlists them. - Add them under IP Addresses. Addresses that are configured but unused are suggested. Behind NAT, enter the public address that is forwarded to it; that is what clients put in DNS.
- Assign domains under List Domains. Filter or search, tick the domains, choose the address, Assign.
After an assignment the domain's DNS page (in the client's panel and under Manage) shows the new address, and the site answers on both the new and the old address until the client's DNS is updated. Only assigned sites answer on an additional address; anything else gets the 404 page there. Certificates keep working, and mail is unaffected (it always uses the server hostname).
panelctl doctor fails if an address in the pool
disappears from the server (for example after a netplan change), because
its sites stop answering there. Remove an address only after moving its
domains away, or tick move its domains to the shared address
when removing it.
DNS
Since version 1.10 panelOwl can host DNS zones itself. Choose one provider under DNS:
- PowerDNS on this server: one click installs
pdns-server, and the server answers on port 53 for every hosted domain. Give the nameserver names your customers should use (ns1.example.net ns2.example.net; their A records must point at this server or at your secondaries). Optional secondary addresses receive NOTIFY and may transfer zones. - Cloudflare: an API token with Zone:Read and DNS:Edit. Zones must already exist in the Cloudflare account unless you also give the account ID (and Zone:Edit on the account), in which case panelOwl creates them. Records are published unproxied.
- cPanel DNSOnly / WHM cluster: a WHM API token from a cluster member. Zones created there replicate to the cluster, so customers moving from cPanel keep the nameservers they already use and the cut-over is an A-record change. Use a dedicated DNSOnly member if you can: the token can then only touch that member's zones.
Test connection checks the token without saving. After saving, every hosted domain gets a zone and its records are published within five minutes (or at once with Publish all now). The zone table shows each zone's status and the last error; edit opens the client's zone editor under Manage.
What gets published automatically: the A/AAAA records of each domain
(and www), following IP assignments; MX, SPF, DKIM, DMARC;
the autoconfig/autodiscover names and SRV records. Clients add their own
records on the DNS page and can unlock an automatic one to take
it over. panelOwl only ever rewrites the record sets it manages;
anything else in a zone is shown but left alone, so records created
directly at Cloudflare or in WHM survive. A zone panelOwl created is
deleted with its last domain; a pre-existing zone only loses the
automatic records.
Switching the provider off (or to another one) leaves the zones where
they are. panelctl doctor reports an unreachable provider
and zones that failed to publish.
Resource limits
Every account can be given a CPU share, a memory cap, a process cap and IO limits, the way a cPanel package would. They apply to the account's PHP, SSH and cron processes together, take effect immediately, and never affect other accounts.
- Set them on Create a New Account or Modify an Account. Empty or 0 means unlimited. CPU is a percentage of one core (100 = one core, 200 = two).
- See them on the account page, in the Resources card: the limits next to the account's live CPU %, memory, processes and IO, and whether it is being throttled.
- Cool-down (opt-in per account): if the account stays at its limit for the configured number of minutes, it is paused: its sites show a "temporarily paused" page and its PHP is stopped, and you get an email. It resumes automatically after the cool-down, or at once with Resume now on the account page. Suspension of the whole account is separate and manual.
IO bandwidth caps need the io cgroup controller, which
is available on a normal server but not inside containers;
panelctl limits status lists what the host enforces.
Suspended and pause pages
Under Server → Suspended and pause pages you edit the two HTML pages Apache serves as a 503: the one shown on every site of an account you suspended, and the default shown when the resource limiter pauses a site (clients can replace that one per domain from their Domains page). Both are static files served without PHP, so they add no load while the account is in trouble; images and fonts have to be embedded or hosted elsewhere, because the site's own URLs answer 503. Preview opens the page in a sandboxed tab; Back to the stock page restores the file panelOwl ships. Edits take effect at once on accounts that are suspended or paused right then.
Terminating an account
Terminate removes the account completely: websites, mail, databases and their users, cron jobs, SSH keys, certificates and the system user. Two things make it safe to offer in the browser:
- A fresh second factor. Besides typing the account name you enter the current code from your authenticator app (or a recovery code). The helper daemon checks it, so a stolen browser session alone cannot terminate accounts.
- An archive first. Before anything is removed, the
whole account is written to
/var/backups/minipanel/minipanel-deleted-<account>-<time>.tar.gz, including its panel settings (domains, mailboxes with their passwords, forwarders, databases and users, cron jobs, SSH keys). If the archive cannot be written, nothing is deleted. The archive is kept for 30 days ([backup] keep_deleted_days), and the notification address gets an email naming the admin.
To bring a terminated account back within those 30 days, on the server:
panelctl backup list # find minipanel-deleted-<account>-...
panelctl account restore minipanel-deleted-acme-20260928T101500Z.tar.gz --confirm
The account comes back with its old uid (when free), files, mail, databases, passwords and settings; certificates are requested again. It is refused while the name, one of its domains or databases is in use.
Logins
Admin logins are separate from client accounts and are created on the server:
panelctl admin create alice
This prints a generated password once (or use
--password-stdin). Two-factor authentication is
mandatory: the first login walks the admin through setting up
an authenticator app and shows eight recovery codes. Other commands:
panelctl admin list
panelctl admin passwd alice # new password (and clears a lockout)
panelctl admin totp-reset alice # lost authenticator: the next login sets it up again
panelctl admin delete alice
Five failed logins in 15 minutes lock the login for 15 minutes (per admin and per client address); failures are logged for fail2ban like client logins.
Security model
The admin UI is a second copy of the panel process
(minipanel-admin.service) running as its own unprivileged
user, minipanel-admin, on 127.0.0.1:8082 behind Apache. The
helper daemon recognises that user by its uid and lets it run only an
explicit allowlist of actions (listing, creating, modifying, suspending
and terminating accounts, everything a client can do inside an account,
certificate retry, running and listing backups, health and audit). Every
action it performs is audited with the admin's name.
So a compromise of the admin web app cannot restore or read backups,
change server configuration, manage admins, or reach the root helper
beyond that list. Terminating an account additionally needs a valid
authenticator code of an admin, checked by the helper, and always leaves
a 30-day archive behind. Even so, treat port 2087 as sensitive:
restrict it to your office or VPN addresses in the
firewall. The installer opens it in ufw for
convenience; tighten with
ufw delete allow 2087/tcp
ufw allow from 203.0.113.0/24 to any port 2087 proto tcp
or the equivalent rule on the firewall in front of the server.