Files
worker/docs/install.md
2026-08-12 18:40:43 +03:00

10 KiB

Installation

The rsmon-worker install subcommand turns a built binary (or a published Docker image) into a running, enabled systemd service on a Linux host. It is the supported way to deploy the worker: it writes the configuration, the systemd unit, and the data directory, then starts the service.

A Go SSH source installer is planned in source-installation.md. Today install copies the binary you invoke it from (or pulls the --image digest), so build first with make build and run the resulting ./bin/rsmon-worker.

Requirements

  • Linux with systemd.
  • Root (install must be run as root). The worker runs as root so it can reach the Docker socket for Compose discovery and use CAP_NET_RAW for ping checks without extra setup.
  • For the binary install: the worker binary you want to install.
  • For the Docker install (--docker): the docker CLI and an immutable repository@sha256:<64 lowercase hex> image digest.

Host dependencies for browser-backed HTTP checks (Debian/Ubuntu):

sudo apt-get update
sudo apt-get install -y ca-certificates chromium libcap2-bin tzdata

Configuration sources

The installer reads the same environment variables the worker runtime reads. Each variable is resolved with this precedence (highest first):

  1. Explicit flags (--url, --token, --host, --port, --login, --password, --name).
  2. --env-file — a strict, systemd-safe KEY=VALUE file (validated before anything is written to disk).
  3. Process environment, including a .env file in the working directory (loaded automatically at startup via godotenv).
  4. Built-in defaults (RSMON_URL=https://rsmon.ru, WORKER_HOST=127.0.0.1, WORKER_PORT=27401 for the primary instance).

.env files are loaded before the install command runs, so sudo rsmon-worker install from a directory containing a .env picks up those values automatically. To override a value, pass the matching flag.

Variables

Variable Required Default Purpose
RSMON_URL yes https://rsmon.ru Control-plane base URL.
RSMON_TOKEN yes none Worker bearer token.
WORKER_HOST no 127.0.0.1 Operator-console bind address.
WORKER_PORT no 27401 (primary) Operator-console port. Required for named instances.
PUBLIC_URL no none Proposed public HTTPS origin; accepted by the control plane.
WORKER_LOGIN no admin (generated) Operator-console basic-auth login.
WORKER_PASSWORD no generated Operator-console basic-auth password.
WORKER_COMPOSE_ENABLED no feature default (on) Enable Docker Compose discovery/management.
WORKER_CLUSTER_* no none Optional Raft cluster (ID, PORT, PEERS, DATA_DIR, ENABLED).
WORKER_RELEASE_URL no none Self-update release feed URL.

WORKER_LOGIN and WORKER_PASSWORD must both be set or both be left empty. If both are empty, the installer generates a random password (login admin), writes it to the env file, and prints it once. Record it; the operator console requires it for both the browser login and the /web/api/* HTTP basic-auth endpoints.

PUBLIC_URL does not bind a listener or terminate TLS. It advertises the one external origin used for the console, authenticated peer status, and planned Raft /raft transport. See public-endpoint-and-identity.md.

Values must be systemd-safe: no whitespace, quotes, backslashes, or $ interpolation inside a value. This keeps the file unambiguous across systemd EnvironmentFile and docker --env-file.

Single-instance install (one worker per host)

The classic install uses the canonical paths and the default port 27401.

make build
printf '%s\n' 'YOUR_WORKER_TOKEN' > worker-token
chmod 600 worker-token
sudo ./bin/rsmon-worker install \
  --token-file worker-token \
  --port 27401 \
  --password 'choose-a-console-password'
rm worker-token

If you keep configuration in a .env (recommended for repeatability):

# .env
RSMON_URL=https://rsmon.ru
RSMON_TOKEN=...
WORKER_PORT=27401
WORKER_LOGIN=admin
WORKER_PASSWORD=...
sudo ./bin/rsmon-worker install

Installed layout:

Path Contents
/usr/local/bin/rsmon-worker Worker binary.
/etc/rsmon-worker/worker.env Configuration, mode 0600.
/var/lib/rsmon-worker/ Data directory (SQLite, webapp state).
/etc/systemd/system/rsmon-worker.service systemd unit.

Multi-instance install (several workers per host)

--name installs a co-located worker under rsmon-worker-<name> with its own binary, config, data, systemd unit, and port. This is how you run a staging build next to production, or isolate tenants on one host.

sudo ./bin/rsmon-worker install --name edge --port 27403 --password '...'

A named instance must have an explicit WORKER_PORT (the default 27401 belongs to the primary). The name must be 1–32 chars, lowercase alphanumeric and hyphens, starting and ending alphanumeric.

Named layout (for --name edge):

Path Contents
/usr/local/bin/rsmon-worker-edge Binary.
/etc/rsmon-worker-edge/worker.env Configuration, mode 0600.
/var/lib/rsmon-worker-edge/ Data directory.
/etc/systemd/system/rsmon-worker-edge.service systemd unit.

Each instance is an independent service (rsmon-worker.service, rsmon-worker-edge.service, …) and can be managed separately.

What the installer does

For a binary install, rsmon-worker install performs these actions in order:

  1. Validates the instance name, the --env-file (if any), and the resolved RSMON_URL/RSMON_TOKEN. Nothing on the host changes before validation passes.
  2. Resolves every supported variable with the precedence above and, when WORKER_LOGIN/WORKER_PASSWORD are both unset, generates a random console password.
  3. Copies the binary from the running executable (or --binary) to /usr/local/bin/rsmon-worker[-<name>] with an atomic rename.
  4. Creates the data directory (/var/lib/rsmon-worker[-<name>]/webapp) and the config directory (/etc/rsmon-worker[-<name>], mode 0750).
  5. Writes the env file to <config dir>/worker.env (mode 0600), in a stable canonical order.
  6. Writes the systemd unit to /etc/systemd/system/rsmon-worker[-<name>].service.
  7. Runs systemctl daemon-reload, systemctl enable, and, unless --no-start, systemctl restart followed by systemctl is-active --quiet to confirm the service came up.
  8. Prints a summary: unit name, binary, env file, data dir, console URL, status, and the generated password if one was created.

The generated systemd unit

The unit is a hardened Type=simple root service ordered after network-online.target and docker.service:

  • ExecStart=/usr/local/bin/rsmon-worker[-<name>]
  • EnvironmentFile=/etc/rsmon-worker[-<name>]/worker.env
  • Environment=HOME=/var/lib/rsmon-worker[-<name>]
  • Environment=RSMON_WEBAPP_DATA_DIR=/var/lib/rsmon-worker[-<name>]/webapp
  • AmbientCapabilities=CAP_NET_RAW / CapabilityBoundingSet=CAP_NET_RAW for ICMP checks.
  • PrivateTmp, ProtectHome, ProtectSystem=full, and ReadWritePaths=<data dir> to constrain writes.
  • Restart=always, RestartSec=5s.

Docker install

Installs a systemd unit that runs the published image instead of a local binary. Requires an immutable digest; mutable tags are rejected.

sudo ./bin/rsmon-worker install --docker \
  --image 'reg.rsxx.ru/rsmon/rsmon-worker@sha256:<64-hex-digest>' \
  --token-file worker-token

--name works with --docker too; the container and volume are namespaced by instance (rsmon-worker-edge, rsmon-worker-data-edge). The container always mounts its data volume at the in-image /var/lib/rsmon-worker.

Options reference

rsmon-worker install [--token TOKEN|--token-file FILE|--env-file FILE]
                     [--name NAME] [--port PORT] [options]
Flag Purpose
--token, --api-key Worker API token (RSMON_TOKEN).
--token-file File containing the worker token (avoids shell history).
--env-file Strict worker env file; validated then used as the config source.
--url Control-plane URL (RSMON_URL).
--host Console bind address (WORKER_HOST).
--port Console port (WORKER_PORT; required with --name).
--login Console login (WORKER_LOGIN).
--password, --password-file Console password, or a file containing it.
--name Instance name for a co-located worker.
--binary Binary to install (default: this executable).
--docker Install the prebuilt Docker image (requires --image).
--image Immutable repository@sha256:<64 hex> digest.
--no-start Enable without starting.

--token/--token-file and --password/--password-file are mutually exclusive within each pair; combining a direct secret with its file form is an error.

Post-install operations

systemctl status rsmon-worker[-<name>]
journalctl -u rsmon-worker[-<name>] -f
sudo systemctl restart rsmon-worker[-<name>]

The public liveness endpoint is GET /healthz; probe it with rsmon-worker liveness. The operator console is at http://127.0.0.1:<port> (loopback by default) and exposes the JSON API under /web/api/* using HTTP basic auth.

Uninstall

There is no uninstall subcommand yet. To remove an instance manually:

sudo systemctl disable --now rsmon-worker-<name>
sudo rm /etc/systemd/system/rsmon-worker-<name>.service
sudo rm -rf /etc/rsmon-worker-<name> /var/lib/rsmon-worker-<name> /usr/local/bin/rsmon-worker-<name>
sudo systemctl daemon-reload

Security notes

  • Keep /etc/rsmon-worker[-<name>]/worker.env mode 0600; the installer writes it that way.
  • Prefer --token-file/--password-file or a .env over passing secrets as flags, which can leak through shell history and process inspection.
  • Bind the console to loopback (WORKER_HOST=127.0.0.1, the default) or front it with an authenticated TLS reverse proxy.
  • Each worker should use its own control-plane token.