Skip to main content

Register & Install the Agent

Installation

When adding a pool, you will be asked whether the pool will be for HAProxy nodes. 

Only select the HAProxy Pool if the backend server(s) are currently running, or will be running, HAProxy.

For all other server types—including cPanel, OpenLiteSpeed, Galera, database servers, and general-purpose Linux hosts—select Generic Linux.

Choosing the correct template ensures that ServersCTL enables the appropriate features and management tools for that server type. If you accidentally select the wrong template, remove any members from the pool and recreate the pool on the correct template.

Recommended: one-shot from the dashboard

You can access the UI using https://serversctl.com/app or https://balctl.com/app. Only the public websites are different.

  1. Register an account at https://serversctl.com/app/
  2. Add a new pool. https://serversctl.com/app/sites
    • Servers can be pooled together. For example, cPanel Servers, LiteSpeed, MariaDB/MySQL all use the Generic Linux template, or HAProxy servers use the dedicated HAProxy template.
  3. Select Add Member. The modal generates a paste-ready command that:
    • Ensures unzip + python3 (via apt or dnf/yum).
    • Downloads https://download.serversctl.com/agent.zip.
    • Runs balctl-agent.sh --enrol --key … --hostname … --api-base ….
    • Writes /etc/balctl/agent.env, runs --update, enables systemd.
  4. The ServersCTL UI will now start to report agent information.
    • See troubleshooting if you have problems.

To add further members to a pool. Keep using the Add Member button. There are no limits to the number of pools or members.

Files after install

Path Role
/usr/local/bin/balctl_heartbeat.py
Agent binary
/etc/systemd/system/balctl-heartbeat.service
systemd unit
/etc/balctl/agent.env
Secrets + config (chmod 600)
/var/lib/balctl/
State stamps (e.g. .haproxy-provisioned)

Bundle contents (agent.zip)

Flat zip: balctl_heartbeat.pybalctl-agent.shbalctl-heartbeat.env.examplebalctl-heartbeat.serviceREADME.mdLICENSEINSTALL_VM.txt.


Configuration (/etc/balctl/agent.env)

If your configured hostname is different from the hostname sent to ServersCTL, use BALCTL_HOSTNAME

Variable Required Default Purpose
BALCTL_ENROLLMENT_SECRET
Yes (heartbeat)
48 hex chars from modal
BALCTL_API_BASE
No
https://serversctl.com
Control plane origin
BALCTL_INTERVAL_SEC
No
1
Bootstrap interval only; control plane returns authoritative heartbeatIntervalSec (1–60s)
BALCTL_HOSTNAME
No
OS hostname/FQDN
Override reported hostname
BALCTL_DECLARE_IP
No
Fixed IPv4 in heartbeat JSON (for DNS failover)
BALCTL_PROBE_PUBLIC_IP
No
off
Discover public IPv4 via HTTPS each heartbeat
BALCTL_PUBLIC_IP_URL
No
https://api.ipify.org
Probe URL
BALCTL_UPDATE_URL
No
https://download.serversctl.com/agent.zip
Self-update zip
BALCTL_PROVISION_HAPROXY
No
off
One-shot HAProxy install on first start (root)
BALCTL_ALLOW_AGENT_DOWNGRADE
No
off
Allow installing older agent from zip (not recommended)

Systemd loads this via EnvironmentFile=/etc/balctl/agent.env. Manual sudo python3 … runs merge missing vars from the same file.