Skip to content

Installing from binary releases

A prebuilt static binary with no package manager — for containers, immutable images and distributions without deb/rpm. Unlike the packages, here you create the systemd unit, the system user and the state directories by hand.

The binaries are published in the release for Linux/amd64:

BinaryPurposeWhere to install
keepercentral servercentral node (1+ instance)
soulon-host agentevery managed host
soulctloperator client CLIoperator workstation
soul-lintoffline linteroperator workstation / CI

Download the binaries you need from the release and lay them out under /usr/local/bin:

Terminal window
sudo install -m 0755 keeper /usr/local/bin/keeper
sudo install -m 0755 soul /usr/local/bin/soul
sudo install -m 0755 soulctl /usr/local/bin/soulctl
sudo install -m 0755 soul-lint /usr/local/bin/soul-lint

Check the built binary’s version (format <binary> <version> (<go-runtime>)):

Terminal window
keeper version
soul version
soulctl --version
soul-lint --help

The keeper and soul daemons run under the soul-stack system user. The binary release doesn’t create it for you — do it by hand.

On the keeper host:

Terminal window
sudo useradd --system --no-create-home --shell /usr/sbin/nologin soul-stack
sudo install -d -o soul-stack -g soul-stack /etc/keeper /var/lib/keeper

On the soul host:

Terminal window
sudo useradd --system --no-create-home --shell /usr/sbin/nologin soul-stack
sudo install -d -o soul-stack -g soul-stack /etc/soul /var/lib/soul-stack

soulctl and soul-lint are client tools; they need no separate user or directories.

Packages carry the unit out of the box; with a binary install you write it by hand. A minimal Keeper unit (/etc/systemd/system/keeper.service):

[Unit]
Description=Soul Stack Keeper
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=soul-stack
Group=soul-stack
EnvironmentFile=/etc/keeper/keeper.env
ExecStart=/usr/local/bin/keeper run --config=${KEEPER_CONFIG}
Restart=on-failure
RestartSec=5s
StartLimitIntervalSec=60s
StartLimitBurst=5
# hardening (security first)
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
RestrictNamespaces=true
LockPersonality=true
MemoryDenyWriteExecute=true
# The only writable path — the Keeper state directory.
ReadWritePaths=/var/lib/keeper
[Install]
WantedBy=multi-user.target

The env file /etc/keeper/keeper.env sets the path to the config:

Terminal window
KEEPER_CONFIG=/etc/keeper/keeper.yml

The agent unit (/etc/systemd/system/soul.service) is analogous but with softer hardening — Soul applies Destiny (installs packages, edits files, manages services) and needs real privileges on the host, so ProtectSystem=strict / MemoryDenyWriteExecute aren’t set for it:

[Unit]
Description=Soul Stack Soul agent
After=network-online.target
Wants=network-online.target
[Service]
Type=exec
User=soul-stack
Group=soul-stack
EnvironmentFile=/etc/soul/soul.env
ExecStart=/usr/local/bin/soul run --config=${SOUL_CONFIG}
Restart=on-failure
RestartSec=5s
StartLimitIntervalSec=60s
StartLimitBurst=5
# hardening (soft profile: Soul changes the system by nature)
NoNewPrivileges=true
PrivateTmp=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictSUIDSGID=true
LockPersonality=true
# The agent state directory: SHA-256-keyed module cache, mTLS identity.
ReadWritePaths=/var/lib/soul-stack
[Install]
WantedBy=multi-user.target

The env file /etc/soul/soul.env:

Terminal window
SOUL_CONFIG=/etc/soul/soul.yml

Enable and start:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now keeper # on the keeper host
sudo systemctl enable --now soul # on the soul host

Provisioning Vault (KV secrets, the PKI engine, AppRole), issuing the Keeper’s server TLS material, filling in keeper.yml / soul.yml, bootstrapping the first operator (keeper init) and onboarding an agent don’t depend on how the binaries were installed. The full procedure is in From deb/rpm packages, starting from step 2.