Cluster
A single OPanel server is a cluster of one. Join more servers and they share the same platform database, cluster certificate authority and panel — customers and staff never see individual servers, just capacity.
Every server takes on one or more roles:
| Role | What it runs |
|---|---|
control |
The controller: API, web UI, job engine, billing, the cluster’s certificate authority |
web |
Sites: nginx, per-site PHP-FPM |
edge |
Public HTTP/HTTPS/HTTP/3, on-demand TLS, the WAF |
ssh |
The customer SFTP/SSH gateway |
db |
Customer MariaDB databases |
cache |
A shared Valkey pool |
opanel install gives the first server every role. Servers you add afterwards join with just the
roles they need.
Adding a server
Section titled “Adding a server”A joined server shares the first server’s platform database, cluster CA and panel; new sites go to whichever server has room in the plan’s pool.
-
On an existing control server, create a one-time join token for the new server’s roles:
Terminal window opanel cluster token create --roles web,edge --pool default --ttl 1hThis prints the exact
opanel joincommand to run, including the controller address and the cluster CA’s fingerprint. -
If the new server has the
edgerole, make every edge share the same TLS certificates:Terminal window opanel cluster share-certificates -
On the new, fresh Debian 13 server, with the
opanelpackage installed, run the printed command as root:Terminal window opanel join --controller 10.0.0.1:7444 --token opj_... --ca-sha256 <fingerprint>The server verifies the controller against the pinned CA fingerprint before it ever sends the token, so the token is useless to anyone who intercepts it in transit to anywhere but your controller. It then installs the packages its roles need, generates its own keys, receives its certificates and starts its services.
Flag Purpose --node-nameName of the server in the cluster (default: its hostname). --node-addressAddress other servers reach it at (default: the address it used to reach the controller). --public-ipv4,--public-ipv6Public addresses of an edge server, for domain DNS checks. -
Check it:
opanel doctoron the new server, andGET /api/v1/nodesfrom the console shows it online and in sync within about a minute.
Give servers a private network for cluster traffic — it isn’t encrypted between edges and web servers. Point customer domains at the public addresses of every edge server, or at a load balancer in front of them.
Node pools and placement
Section titled “Node pools and placement”Plans point at a node pool (for example standard, premium-nvme, eu-west); customers never
pick a specific server. When a new site is created, OPanel filters candidate web servers (role,
status, pool membership, PHP version, disk and memory headroom) and scores the rest on recent CPU,
memory and disk usage plus site count, picking the best fit. Databases are placed on a database
pool the same way.
Moving sites and draining servers
Section titled “Moving sites and draining servers”Operators move individual sites, drain a server before maintenance, and act on the rebalancer’s suggestions — customers see only a note in the site’s activity log.
- Move a site:
POST /api/v1/sites/{id}/move. Files copy in the background while the site keeps serving from its current server; the cutover to the new server takes seconds once its copy is caught up. The previous server keeps a stopped copy for a rollback window (24 hours by default) in case you need to move back quickly. - Cordon a server (
POST /api/v1/nodes/{id}/cordon): stop sending it new sites; its existing sites stay put. - Drain a server (
POST /api/v1/nodes/{id}/drain): cordon it and move all of its sites off, a few at a time, before you take it down for maintenance or retirement.GET /api/v1/nodes/{id}/drainshows progress and flags any site whose move failed repeatedly. - Uncordon (
POST /api/v1/nodes/{id}/uncordon): let a server take new sites again.
The rebalancer
Section titled “The rebalancer”Every 15 minutes OPanel scores each pool’s web servers on CPU, memory, disk and site count. When a
pool stays unbalanced for three evaluations in a row, the rebalancer proposes moving a few busy,
small sites from the hottest server to the coolest. By default it only suggests these moves
(GET /api/v1/rebalancer/proposals) for an operator to accept or dismiss; turn on
rebalancerAutoMoves in placement settings to let it start one move per pool automatically. Pinned
sites are never proposed.
| Placement setting | Default | Purpose |
|---|---|---|
maxMovesPerNode |
2 | Concurrent moves touching one server |
maxMovesPerPool |
4 | Concurrent moves in one pool |
rollbackWindowHours |
24 | How long a moved site’s previous copy is kept |
transferMBPerSecond |
100 | Throughput cap per transfer stream |
rebalancerThreshold |
0.25 | Load spread that triggers rebalancing proposals |
rebalancerAutoMoves |
off | Let the rebalancer start moves itself |