Skip to content

Server setup

The server requires a JSON configuration file (default: swarm-server.json).

{
"listen_addr": ":8800",
"registry_path": "/path/to/registry.json",
"known_hosts_path": "/path/to/known_hosts.json",
"ssh_key_path": "/path/to/id_ed25519",
"provider_username_cmd": "op read op://Private/UpCloud/username",
"provider_password_cmd": "op read op://Private/UpCloud/password",
"agent_binary_path": "/path/to/swarm-agent-linux-amd64"
}
Field Description
listen_addr Address to listen on (default :8800)
registry_path Path to the registry JSON file
known_hosts_path TOFU SSH host-key store; defaults to <registry-dir>/known_hosts.json. Records each VM’s host key on first connect; subsequent connects reject on mismatch. Entries are dropped automatically on VM destroy.
ssh_key_path Path to SSH private key (public key derived as <path>.pub for VM provisioning)
provider_username_cmd Shell command that outputs the UpCloud username
provider_password_cmd Shell command that outputs the UpCloud password
provider_token_cmd Shell command that outputs an UpCloud API token (alternative to username/password)
agent_binary_path Path to the swarm-agent binary (uploaded to VMs during bootstrap)
ca_dir Directory holding the swarm CA (ca.key, ca.crt) and auth state; defaults to the registry’s directory
tls_cert / tls_key Optional operator-provided TLS certificate/key for the server (replaces the CA-signed self-signed cert)
tls_sans Extra hostnames/IPs for the self-signed server certificate (defaults: localhost, 127.0.0.1). Set the public name clients connect to, e.g. ["swarm.example.com"]
enroll_token_ttl Lifetime of one-time enrollment tokens (Go duration, e.g. 15m); default 15m
proxy_target_port Port the container HTTP proxy dials inside containers (default 8900)
private_network Private network new VMs join (name, create_if_missing, ip_network); private_networks is the multi-network list form; private_network_id joins an existing network by UUID
git_credentials Per-host git credentials for private repo clones: [{"host": "github.com", "token": "..."}] (optional username). Tokens are injected at clone time only — never stored in the registry. Alternatively register via swarm git-credential add (client-side)

Use either provider_token_cmd or provider_username_cmd/provider_password_cmd, not both. If neither is set, the provider falls back to environment variables (UPCLOUD_TOKEN or UPCLOUD_USERNAME/UPCLOUD_PASSWORD).

Credential commands are executed via sh -c, so pipes and shell syntax work. Compatible with 1Password, Bitwarden, pass, or any secret manager.

For packaged installs, environment variables can live in the service’s environment file, /etc/swarm/swarm-server.env (root-only; read by systemd before the service drops to the swarm user):

UPCLOUD_TOKEN=xxxx

The installed systemd unit reads it via EnvironmentFile=-/etc/swarm/swarm-server.env (the - tolerates a missing file). Config provider_*_cmd values take precedence over these variables.

The server needs the SSH keypair it uses to bootstrap and reach VMs. If ssh_key_path is /etc/swarm/id_ed25519 and the key does not exist, create it (the apt package generates it automatically on install; manual installs need this):

Terminal window
sudo ssh-keygen -t ed25519 -N '' -f /etc/swarm/id_ed25519
sudo chown swarm:swarm /etc/swarm/id_ed25519 /etc/swarm/id_ed25519.pub
sudo chmod 0600 /etc/swarm/id_ed25519
Terminal window
./dist/swarm-server --config swarm-server.json

The server logs to stderr:

swarm-server listening (https) on :8800

On first start the server also prints a one-time enrollment token:

swarm enrollment token (valid 15m0s, single-use):
<token>
run: swarm login --token <token>

Keep the token private — anyone holding it can enroll as a user of the server. It is single-use and expires after enroll_token_ttl (default 15 minutes). Mint a fresh one any time with swarm server token (requires an enrolled operator). The full enrollment and certificate lifecycle is covered in the Security model.