Skip to main content
Version: 1.0

Installing the centre

There are two ways to get a centre running: the guided Rocky Linux appliance install (recommended), or running the ballast-centre binary directly on any supported platform.

A Rocky Linux appliance carries a second, unprivileged-by-design program alongside the centre: Ballast Manager, a small web UI (default 0.0.0.0:9444) that does the entire install for you.

Ballast Manager's Status page on a running appliance, showing the machine name, centre version, certificate authority fingerprint, secret key fingerprint, PostgreSQL version, and passing health checks for PostgreSQL and the centre

This is what it looks like once installed and running, the Status page is where it lives day to day, with Install (used below), Backup, Restore and Updates alongside it in the same rail.

Getting Manager onto a bare box​

There is currently no packaged installer or pre-built appliance image for this step, it's on the roadmap, not shipped yet. What follows is the actual manual process today, and it will stay accurate even once a packaged path exists alongside it.

Manager has to already be running before it can do anything, which means one manual bootstrap on a fresh Rocky 9 box before you ever open a browser:

  1. Before any of this, give the box a real root partition. Rocky's default partitioning splits off a /home logical volume sized for a multi-user desktop, which strands a large share of the disk on an appliance with no interactive users, enough, on a 60 GB disk, to leave / without the room PostgreSQL 18's install needs. Either give / the bulk of the disk at OS-install time, or check df -h right after and reclaim /home into / before going further.

  2. Get the binary onto the box. Download ballast-manager from ballast.halvantic.com/download and verify it against the published SHA256SUMS. Manager is closed source, so this download is the only way to get it, there is no repository to build it from yourself.

  3. Copy it to the box as /usr/local/bin/ballast-manager (the exact path its own systemd unit expects) and make it executable, a plain file transfer (scp/pscp) does not carry the execute bit, so this step is easy to skip and the box will not say so until you actually try to run it:

    chmod +x /usr/local/bin/ballast-manager
  4. Relabel it for SELinux. A file copied into /usr/local/bin keeps the SELinux context of wherever it came from, not a context that's allowed to execute, the failure looks like a plain permission error and points nowhere near SELinux. restorecon -F /usr/local/bin/ballast-manager (if getenforce reports Enforcing).

  5. Open its port, if firewalld is active, nothing does this for you automatically the way the centre's own ports get opened during install:

    firewall-cmd --permanent --add-port=9444/tcp && firewall-cmd --reload
  6. Run it once, as root, so it starts serving and, as a side effect of starting, writes and enables its own systemd unit (nothing installs that unit ahead of time; the running program installs it for itself):

    ballast-manager

    Browse to https://<box>:9444. The browser will warn about an untrusted certificate on first visit, Manager issues itself a self-signed one covering the box's hostname and addresses; the certificate's fingerprint is also printed to the console output, if you want to verify it before trusting the browser prompt.

    This first run is only enabled, not started, under systemd, deliberately, because starting the unit immediately would try to bind port 9444 a second time while this foreground process is still holding it. That means the process in your terminal is the only thing serving Manager until one of two things happens, and closing the session before either one kills it:

    systemctl start ballast-manager # takes over right now, no reboot needed

    A reboot gets you there too, since the unit is already enabled, but there's no need to wait for one. Either way, once the unit is actually running, Manager survives session closes and reboots both, without any of the steps above.

Browse to it and the first visit lets you set an administrator password for the manager itself, separate from the centre's own admin account, set later at its first sign-in.

Ballast Manager&#39;s Status page on a bare box before anything is installed: every state field reads &quot;—&quot;, PostgreSQL running fails as not-yet-started, and disk space is the only passing check

This is what a fresh box looks like at this point, nothing installed yet, two checks failing (expected: there's no database or centre to check). Install in the left rail is where you go next.

From the install page, give it:

  • The advertise address agents will be told to reach the centre on. Agents store this in their Windows service definition at onboarding, so changing it later means re-onboarding every host.
  • An uploaded linux/amd64 build of ballast-centre, downloaded from the downloads page the same way as Manager itself, the centre is closed source too, so this is the only way to get it. The manager cannot fetch it for you, it's meant to work on an isolated management network with no route out, so this is always a browser upload, the same way a database restore is. A newer centre later on is the same upload, from Manager's Updates page rather than Install.
  • Optionally, a Windows agent .exe. This step is about push onboarding only, uploading it here lets the console deploy it to a host directly over WinRM, no RDP or console session needed. Skipping it does not make the agent itself optional: every Hyper-V host still needs one, and without this upload the way to get it there is downloading it yourself, from the downloads page or the agent's own public source (Apache 2.0, unlike the centre and Manager), and installing it by hand per Installing the agent.
  • Optionally, whether to install the VM console (guacd), which needs a route to a container registry to pull its image.

Ballast Manager&#39;s install form: Advertised address filled in as &quot;ballastdev&quot;, Centre binary and Windows agent file pickers both showing &quot;No file chosen&quot;, &quot;Install the VM console as well&quot; checked, a note on what gets written, and the Install the centre button

This is the actual form, the four fields above are everything it asks for. Nothing happens until Install the centre is clicked.

From there the manager runs the whole install as one ordered, resumable sequence, each step independently verified rather than trusted on exit code:

  1. Create the ballast system service account (no login shell, no home directory)
  2. Create /etc/ballast (root-owned, group ballast) and the service account's state directory
  3. Install PostgreSQL via the postgresql:18 module stream, deliberately not Rocky's default package, which is PostgreSQL 13 and can never load a dump taken from the 17/18 servers this product runs on, since pg_restore only loads forward
  4. Initialise the database cluster
  5. Start PostgreSQL
  6. Set password_encryption to scram-sha-256 before the role's password is created, set afterwards, the stored hash would be unusable and the failure would read as a wrong password
  7. Set loopback authentication in pg_hba.conf (local peer and replication lines are left untouched)
  8. Create the centre's database role and database, generating a password
  9. Write /etc/ballast/centre.env (root-owned, 0640, group ballast), generating BALLAST_SECRET_KEY if this machine has none
  10. Place the uploaded centre binary and relabel it for SELinux
  11. Install the ballast-centre systemd unit
  12. Label the agent port for SELinux
  13. Open 443/9443 in firewalld (PostgreSQL is never opened, it listens on loopback only)
  14. Place the agent binary, if one was uploaded
  15. Start the centre and confirm it answers its own /healthz
  16. Install guacd, if the console was requested

A failed or interrupted install is safe to just run again: completed steps are skipped, but every skipped step is still re-verified, so "already done" never quietly means "unchecked."

Ballast Manager&#39;s install page after a completed run: every one of the 16 steps ticked green, each with the outcome it verified, ending in &quot;The install is done, Finished in 21s&quot;

This is what a completed run looks like, each step names what it actually checked, not just that a command exited zero, and a step skipped because it was already done (from a previous, interrupted attempt) is re-verified and ticked the same as one just performed.

Immediately below this, the install page prompts you to escrow the secret key, download a passphrase-encrypted copy of BALLAST_SECRET_KEY before doing anything else with this box. See Certificates below for why this key is the one thing a database backup on its own cannot recover.

Ballast Manager&#39;s Status page after a completed install: machine name, centre version 1.0.2, certificate authority and secret key fingerprints, PostgreSQL 18, and four checks all passing, &quot;Everything checked passes.&quot;

Back on Status, this is the healthy end state: every field populated, every check green.

Manual install (any platform)​

Flags and defaults below are taken from the centre binary's source as of a recent build. They will drift as the product moves, treat centre --help on the binary you actually run as the source of truth, and this page as a convenience copy of it.

There is no configuration file. Everything is a command-line flag, Ballast Manager's install above simply generates these same flags into a systemd EnvironmentFile rather than you typing them.

1. Provide a database​

The centre stores desired state, inventory and job history in PostgreSQL. Create an empty database and a role the centre can connect as, then pass the connection string as a DSN.

2. Run the centre binary​

./ballast-centre \
-db "postgres://ballast:password@localhost:5432/ballast?sslmode=disable" \
-listen 0.0.0.0:9443 \
-rest-listen 0.0.0.0:8080 \
-advertise centre.example.internal
FlagDefaultPurpose
-db(none)PostgreSQL DSN. Omitted entirely, the centre falls back to an in-memory store, nothing survives a restart. Development only.
-listen127.0.0.1:9443Address the gRPC service (agent channel) binds to.
-rest-listen127.0.0.1:8080Address the REST API and console bind to. Empty disables the console.
-advertise(none)Address agents should dial back on. Required whenever the bind address is not what agents can reach.
-authtrueAuthentication for the console/REST API.
-tlstrueMutual TLS on the agent gRPC channel.
-rest-tlsfalseHTTPS on the console/REST listener. Browsers trust it once they import /ca.crt.
-agent-binary(off)Serves the agent installer at /agent/ballast-agent.exe so hosts can fetch it directly from the centre.
-iso-dir(none)Directory backing the ISO library.
-guacd(none)Address of a guacd instance, enabling the interactive VM console in the browser. Pair with -console-secret naming the stored credential to use.

First sign-in​

Browse to the REST/console listener address (port 443 on the Rocky Linux appliance). The first visit lets you set the initial administrator password, there is no default credential and no separate token step.

That local administrator stays as the break-glass login. Once the centre is up you can also let operators sign in with their Active Directory account; see Active Directory sign-in.

Certificates​

With -tls at its default of true, the agent channel uses mutual TLS. On first run without existing certificates, the centre generates a CA and issues itself a server certificate. Agents are issued their own certificate during agent installation.

The root CA certificate is valid for 10 years; issued leaf certificates (the centre's own server certificate and each agent's client certificate) are valid for 2 years by default. Renewal is a convenience rather than a hard deadline, an agent keeps enforcing its last-known desired state even past certificate expiry, so a lapsed cert does not stop the fleet from running.

The CA's private key is sealed by BALLAST_SECRET_KEY, an environment variable that is not stored in the database. This is the single most important fact for backups: a PostgreSQL dump on its own restores the whole fleet's configuration with no usable credentials and a CA that can no longer sign anything. A backup of the centre must also include a verified copy of BALLAST_SECRET_KEY, the centre's key escrow export (a passphrase-encrypted copy of the key) is the supported way to do this. Verify that an escrow actually decrypts before you need it, not at the point of a real recovery.

Running as a service​

On the Rocky Linux appliance this is handled for you: Ballast Manager installs ballast-centre.service under systemd, reading its flags from /etc/ballast/centre.env as an EnvironmentFile. For any other platform, running the binary under your own systemd unit (Linux) or as a Windows service is on you for now, packaged guidance for platforms outside the Rocky Linux appliance will be added here once that path exists.