Installation
Swarm ships as three binaries: swarm (CLI client), swarm-server
(control-plane daemon), and swarm-agent (runs on each VM — the
server deploys it automatically, you never install it by hand).
From source
Section titled “From source”Requires Go 1.25+.
make build-allThis produces three binaries in dist/:
| Binary | Purpose |
|---|---|
swarm |
CLI client |
swarm-server |
Control-plane server |
swarm-agent-linux-amd64 |
Agent binary (deployed to VMs) |
To build individually:
make build # CLI onlymake build-server # Server onlymake build-agent # Agent only (linux/amd64)Install the CLI to your $GOPATH/bin:
make installHomebrew (macOS)
Section titled “Homebrew (macOS)”brew tap hyperengineering/tapbrew install swarmDebian/Ubuntu (apt, Gemfury)
Section titled “Debian/Ubuntu (apt, Gemfury)”swarm and swarm-server are published as Debian packages via the
GPG-signed Gemfury apt repository:
curl -fsSL https://apt.fury.io/neuralmux/gpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/neuralmux-keyring.gpg > /dev/nullecho "deb [signed-by=/usr/share/keyrings/neuralmux-keyring.gpg] https://apt.fury.io/neuralmux/ * *" | sudo tee /etc/apt/sources.list.d/neuralmux.listsudo apt updatesudo apt install swarm swarm-serverThe gpg --dearmor step matters: Gemfury serves the key
ASCII-armored, which apt cannot use directly (NO_PUBKEY).
swarm-server installs the binaries to /usr/bin, an example config
to /etc/swarm/swarm-server.json (never overwritten on upgrade), a
systemd unit, and a swarm service user. Start it with:
sudo systemctl enable --now swarm-serverDocker (server)
Section titled “Docker (server)”The server image is published to
ghcr.io/hyperengineering/swarm-server.
Docker Compose
Section titled “Docker Compose”cd packaging/dockercp ../swarm-server.json.example swarm-server.json# edit swarm-server.json with your credentials and pathsdocker compose up -dThe Compose file mounts:
| Mount | Container path | Purpose |
|---|---|---|
swarm-data volume |
/var/lib/swarm |
Persistent registry data |
./swarm-server.json |
/etc/swarm/swarm-server.json |
Configuration (read-only) |
~/.ssh/id_ed25519.pub |
/etc/swarm/id_ed25519.pub |
SSH public key (read-only) |
The container exposes port 8800 and restarts unless explicitly stopped.
Manual
Section titled “Manual”docker run -d \ --name swarm-server \ -p 8800:8800 \ -v /path/to/swarm-server.json:/etc/swarm/swarm-server.json:ro \ -v /path/to/id_ed25519:/etc/swarm/id_ed25519:ro \ -v /path/to/id_ed25519.pub:/etc/swarm/id_ed25519.pub:ro \ -v swarm-data:/var/lib/swarm \ --restart unless-stopped \ ghcr.io/hyperengineering/swarm-server:latestThe image is based on Alpine and runs as a non-root swarm user.
Bare-metal tarball (systemd)
Section titled “Bare-metal tarball (systemd)”make package-serverThis creates dist/swarm-server-linux-amd64.tar.gz containing the
server binary, agent binary, systemd unit, installer script, and
example configuration. Copy it to the host and run:
tar xzf swarm-server-linux-amd64.tar.gzcd swarm-server-packagesudo bash install.shThe installer copies the binaries to /usr/bin, creates the swarm
system user, creates /etc/swarm/ and /var/lib/swarm/, places an
example config if none exists, and installs the systemd unit. It is
idempotent — safe to re-run for upgrades.
The service runs as the swarm user with ProtectSystem=full,
NoNewPrivileges=true, and PrivateTmp=true hardening. It restarts
on failure after a 5-second delay.
Upgrading
Section titled “Upgrading”Systemd / bare metal: rebuild the package, copy the tarball, and
re-run the installer. The installer never overwrites an existing
/etc/swarm/swarm-server.json. Then:
sudo systemctl restart swarm-serverDocker Compose: rebuild and restart:
docker compose builddocker compose up -dUpgrading from v0.7-beta: the API is HTTPS-only and authenticated
(mTLS) since that release. After the upgrade the first server start
prints a one-time enrollment token — re-enroll with
swarm login --token <token> and point the CLI at the https:// URL
(swarm config set server https://…).
Configure the server — see Server setup.