Rework `rsmon-worker install` so one host can run several isolated workers and so the installer consumes the full worker env-var set. - main.go now loads .env before dispatching management commands, so install/deploy read the same environment as the runtime. - New --name flag installs a co-located worker as rsmon-worker-<name> with its own binary (/usr/local/bin/rsmon-worker-<name>), config (/etc/rsmon-worker-<name>), data dir (/var/lib/rsmon-worker-<name>), and systemd unit. Named instances require an explicit WORKER_PORT. - Configuration is resolved flags > --env-file > process env/.env (godotenv) > defaults; the resolved set is written as a stable, systemd-safe 0600 env file. - WORKER_LOGIN/WORKER_PASSWORD default to a generated admin password (printed once) when both are unset; XOR is rejected. - The generated unit is now hardened (After=docker.service, CAP_NET_RAW, ProtectSystem=full, ReadWritePaths=data dir) and parameterized by instance; the Docker unit is namespaced by instance too. - install creates the data + config directories and prints a summary (unit, binary, env file, data dir, console URL, generated password). - New flags: --name, --host, --port, --login, --password/--password-file. - Tests: resolvePaths, validateInstanceName, resolveInstallEnv precedence/XOR/port-required, renderEnvFile, validateEnvValue, plus named-instance unit assertions. End-to-end verified by installing and removing a throwaway --name instance. - docs/install.md documents the tool, config sources/precedence, single- and multi-instance flows, the exact actions performed, the generated unit, options, and uninstall.
9.8 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 shell installer that downloads a pre-built binary is planned. Today
installcopies the binary you invoke it from (or pulls the--imagedigest), so build first withmake buildand run the resulting./bin/rsmon-worker.
Requirements
- Linux with systemd.
- Root (
install must be run as root). The worker runs asrootso it can reach the Docker socket for Compose discovery and useCAP_NET_RAWfor ping checks without extra setup. - For the binary install: the worker binary you want to install.
- For the Docker install (
--docker): thedockerCLI and an immutablerepository@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):
- Explicit flags (
--url,--token,--host,--port,--login,--password,--name). --env-file— a strict, systemd-safeKEY=VALUEfile (validated before anything is written to disk).- Process environment, including a
.envfile in the working directory (loaded automatically at startup viagodotenv). - Built-in defaults (
RSMON_URL=https://rsmon.ru,WORKER_HOST=127.0.0.1,WORKER_PORT=27401for 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. |
WORKER_URL |
no | none | Public URL advertised to 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.
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:
- Validates the instance name, the
--env-file(if any), and the resolvedRSMON_URL/RSMON_TOKEN. Nothing on the host changes before validation passes. - Resolves every supported variable with the precedence above and, when
WORKER_LOGIN/WORKER_PASSWORDare both unset, generates a random console password. - Copies the binary from the running executable (or
--binary) to/usr/local/bin/rsmon-worker[-<name>]with an atomic rename. - Creates the data directory (
/var/lib/rsmon-worker[-<name>]/webapp) and the config directory (/etc/rsmon-worker[-<name>], mode0750). - Writes the env file to
<config dir>/worker.env(mode0600), in a stable canonical order. - Writes the systemd unit to
/etc/systemd/system/rsmon-worker[-<name>].service. - Runs
systemctl daemon-reload,systemctl enable, and, unless--no-start,systemctl restartfollowed bysystemctl is-active --quietto confirm the service came up. - 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.envEnvironment=HOME=/var/lib/rsmon-worker[-<name>]Environment=RSMON_WEBAPP_DATA_DIR=/var/lib/rsmon-worker[-<name>]/webappAmbientCapabilities=CAP_NET_RAW/CapabilityBoundingSet=CAP_NET_RAWfor ICMP checks.PrivateTmp,ProtectHome,ProtectSystem=full, andReadWritePaths=<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.envmode0600; the installer writes it that way. - Prefer
--token-file/--password-fileor a.envover 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.