Installation
Install RMON for your team, sign in with the administrator account created during installation, then connect agents and create your first check. See the current free offering and installation support.
Before preparing firewall rules and certificates, review network requirements and connection directions. For an existing installation, prepare a backup and recovery plan before moving data or changing services.
- Docker installation and migration
- Kubernetes installation
- Native installation requirements
- RPM installation
- Ubuntu installation
- Initial configuration
- RMON Server and secure result delivery
RMON in Docker
Use this guide to start RMON, connect your services and agents, and preserve your data when moving an existing installation. Run one RMON web instance. For installation options and assistance, see the installation guide.
Keep web, scheduler, operations and proxy running. The agent operations service needs SSH access to your agent hosts. Use one scheduler instance.
New installation
Use a deployment directory containing compose.yaml and .env.example. Copy .env.example to .env, restrict its permissions to 0600, and set RMON_PUBLIC_URL and RMON_TLS_NAME to your address. Select the available web and proxy images with RMON_WEB_IMAGE and RMON_PROXY_IMAGE; the default web image is ghcr.io/roxy-wi/rmon/rmon-web:1.4.0, also available as ghcr.io/roxy-wi/rmon/rmon:1.4.0. Select the proxy image available for your installation. Keep this directory and its name for updates. Before starting, make sure the selected images are available on the host. Run the following commands from that directory:
docker compose config --quiet
docker compose run --rm --no-deps web init
docker compose up -d --no-build
docker compose ps
Use your IP or hostname instead of the example address, then open its HTTPS URL. Initialization prompts for an admin password (minimum 12 characters). For unattended initialization, mount a password file and set RMON_ADMIN_PASSWORD_FILE only on the init command. Never put passwords in command arguments.
Run init once for a new installation with an empty database. It creates the initial configuration, application keys and administrator account. Sign in with that account to add users. Do not run initialization for an existing installation or in multiple terminals at once. If initialization fails, check the error before retrying; contact support if the database is no longer empty.
On first start, RMON creates a self-signed HTTPS certificate if none is supplied. Trust its public certificate on the devices used to access RMON, or mount your existing certificate and key at /etc/ssl/certs/rmon.crt and /etc/ssl/certs/rmon.key in the proxy service. Supply both files together. Set RMON_SELF_SIGNED=0 in .env to require your own certificate. Generated certificates are saved in the storage selected by RMON_TLS_SOURCE.
The other volumes preserve /etc/rmon, /var/lib/rmon, and /var/log/rmon. Back up configuration, database and application keys together. Do not run docker compose down --volumes unless you intend to delete these data.
Existing RMON installation
Do not run init. Back up your DB, config, application keys and certificates. Stop the existing RMON web service, scheduler, operations service and result servers before updating the database or starting their replacements. Preserve the exact application keys and environment settings. In .env, select the existing host directories; all RMON services and the optional server will use these same sources:
RMON_CONFIG_SOURCE=/etc/rmon
RMON_DATA_SOURCE=/var/lib/rmon
RMON_LOG_SOURCE=/var/log/rmon
Use absolute paths and confirm that the directories and rmon.cfg exist before starting. These settings select host directories; do not substitute new volume names or run init to resolve a missing configuration error. For your existing HTTPS certificate, place a copy of rmon.crt and rmon.key in a protected directory such as /srv/rmon/tls, then set RMON_TLS_SOURCE=/srv/rmon/tls and RMON_SELF_SIGNED=0. Keep the original pair. Configuration and application keys must be readable by uid/gid 33, with data and logs writable by that account. Check permissions before starting an existing installation. The TLS key may remain root-owned with mode 0600.
Config format and existing paths stay unchanged. SQLite remains /var/lib/rmon/rmon.db (or the existing RMON_DB_PATH override); MySQL/PostgreSQL still use their existing rmon.cfg sections. Custom data, log, secret and outbound CA paths require corresponding mounts. Keep all existing application keys; carry over any keys previously supplied through the service environment.
Container localhost is not the host. Select reachable addresses for your database and RMON Server. An optional host-gateway mapping can help reach host services, but does not change their listening addresses or firewall.
Starting RMON does not update the database. To review and apply database updates, back up the database, stop web, scheduler, operations and any result servers using this database, and run:
docker compose run --rm --no-deps --pull never --user 33:33 -e RMON_SCHEDULER_ENABLED=0 \
--entrypoint /opt/rmon-venv/bin/python web app/migrate.py list
docker compose run --rm --no-deps --pull never --user 33:33 -e RMON_SCHEDULER_ENABLED=0 \
--entrypoint /opt/rmon-venv/bin/python web app/migrate.py migrate
After the update succeeds, start RMON with docker compose up -d --no-build. See updates, backups and rollback for the complete procedure.
RMON Server on the same host
For an existing external RMON Server, keep using compose.yaml alone. To run a result server on this Docker host, add compose.server.yaml and create its access token once in a new deployment directory:
umask 077
mkdir -p secrets
(set -C; openssl rand -hex 32 > secrets/server-token)
sudo chown 33:33 secrets/server-token
sudo chmod 600 secrets/server-token
Do not regenerate this token during updates. RMON_SERVER_TOKEN_FILE selects its path on the host. The file must be readable by uid 33; Compose does not change bind-mounted file ownership.
Set COMPOSE_FILE=compose.yaml:compose.server.yaml in .env on Linux. The remaining docker compose commands then include both files. Use a single Compose project for all commands, including backups and updates.
Initialize a new installation as described above, or use the existing-data procedure. Then run:
docker compose config --quiet
docker compose up -d --no-build
docker compose exec -T server python -m modules.common.probe ready
The server uses the same configuration and database as web. Set RMON_SERVER_IMAGE to the available server version. Both services must be able to access custom database paths and any files referenced from rmon.cfg.
The result port is published only on 127.0.0.1:5100 by default. For agents on other hosts, set RMON_SERVER_BIND_IP to a reachable private interface and restrict the port to the agent network. Set the RMON master address and port to that host address and RMON_SERVER_PORT. A containerized agent cannot use 127.0.0.1 or the Compose name server to reach a different container or host.
Existing server HTTPS/mTLS settings in rmon.cfg remain supported. For a new secure connection, follow the server transport guide. Keep referenced certificates under a mounted directory. Set RMON_SERVER_INTERNAL_URL to the server's HTTPS address, with RMON_SERVER_CA_FILE and client certificate settings for the web connection. For the Compose address https://server:5100, the certificate must include the DNS name server as well as the addresses used by agents. Configure probe CA and client certificate paths separately. Plain HTTP is for trusted networks only.
HTTP, HTTPS and external services
| Compose variable | Default | Purpose |
|---|---|---|
RMON_PROXY_SCHEME | https | Access RMON over HTTP or HTTPS |
RMON_WEB_PORT | 443 | Published proxy port |
RMON_BIND_IP | 0.0.0.0 | Published interface |
RMON_TLS_NAME | localhost | SAN for a newly generated certificate |
Put deployment settings in .env or the shell environment. Shell values take precedence over .env. Compose passes the application key, JWT, configuration path and server connection settings listed in compose.yaml to web, along with RMON_PUBLIC_URL, RMON_COOKIE_SECURE, RMON_AGENT_IMAGE and RMON_AGENT_CONTROL_URL. Unset values leave the existing application defaults and configuration in effect. Single-quote literal secrets containing $ or #. Web can also read public_url and cookie_secure from an optional [container] section in the existing config. Existing configs need no new section.
For deliberate plain HTTP on a trusted network:
RMON_PROXY_SCHEME=http RMON_WEB_PORT=80 RMON_COOKIE_SECURE=0 docker compose up -d
HTTP sends credentials without encryption; use HTTPS for normal access. Expose RMON through the proxy service only. Keep the web service's port unpublished.
Set RMON_PUBLIC_URL to the address users open in their browser for company sign-in and agent connections. Configure the RMON Server connection in RMON settings. Services marked Managed externally must be started, stopped and updated on their host.
Server diagnostics keep the existing HTTP, HTTPS and mTLS options through RMON_SERVER_INTERNAL_URL, token-file, CA-file and client-certificate settings. Mount outbound trust/identity files read-only. Self-signed remote certificates must be trusted through a CA file; certificate verification is not disabled.
Docker agents, managed over SSH
Configure SSH credentials with sudo access for the target Linux host in RMON. Agent installation also installs Docker when needed. Ensure that host can download your agent image. If image access requires authentication, sign in to the registry on the target host.
The default agent image is ghcr.io/roxy-wi/rmon/rmon-agent:2.0. To use another available version, set RMON_AGENT_IMAGE or [agent_deployment] image in rmon.cfg before installing or reconfiguring the agent.
Install, start, stop and restart agents from RMON using their configured SSH credentials. If an update fails, RMON attempts to restore the previous agent. Existing agents keep their current installation until you reconfigure them.
Existing connection and certificate settings in /etc/rmon/rmon-agent.cfg are preserved. If agents cannot reach RMON at its public address, set RMON_AGENT_CONTROL_URL or [agent_deployment] control_url to an address they can reach. An existing explicit control URL is not replaced.
For HTTPS/mTLS, select the required transport and provide the trusted CA. Supply a client certificate and key, or enable generation with an authorized signing CA. Existing certificate paths and connection settings are retained unless you explicitly change the transport. This includes the public CA/certificate for a self-signed RMON control endpoint. Back up /etc/rmon/rmon-agent.cfg, /var/lib/rmon/rmon-agent, /var/log/rmon and the configured certificate files. Agent installation preserves these paths.
Stopped rmon-agent-previous-* containers are retained for deliberate rollback with automatic restart disabled. Review/clean old snapshots and containers explicitly. Uninstall stops/removes the active container, but preserves queues, configuration, certificates and rollback containers.
Restrict access to the agent's published port to your monitoring network. For checks of the agent host, use its reachable IP address: localhost refers to the agent container.
Application keys
For a self-hosted installation, configure and back up the application keys:
RMON_SECRET_KEY: a random value of at least 32 characters for user sessions.RMON_SECRET_PHRASE: a Fernet key for stored SSH passwords, passphrases, and private keys. Generate one withpython3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())".RMON_JWT_PRIVATE_KEY_FILEandRMON_JWT_PUBLIC_KEY_FILE: optional overrides for the default JWT key paths in/var/lib/rmon/keys.
The session key may instead be stored in RMON_SECRET_KEY_FILE; when neither setting exists, RMON creates /var/lib/rmon/keys/flask-secret. Keep /var/lib/rmon/keys with your database and configuration backups. Preserve the existing keys when updating or moving RMON.
To rotate an existing credential key, back up the database and run rotate_credential_secret.py with both RMON_OLD_SECRET_PHRASE and the new RMON_SECRET_PHRASE in the environment.
Company sign-in
Super administrators can configure company sign-in under Admin area → OIDC. Add one or more identity providers, choose allowed email domains, enable automatic user creation or email linking, and map company groups to RMON groups and roles. Users can then choose their provider on the login page. Local and LDAP login remain available.
Set RMON_PUBLIC_URL=https://rmon.example.com to the address users open in their browser. Register the callback URL displayed in RMON with your identity provider and include at least the openid scope.
Complete the OIDC setup and sign-in test before giving the team access. The walkthrough also covers existing accounts and company group mappings.
Troubleshooting
Check docker compose ps and docker compose logs web scheduler operations proxy; application logs are also available in /var/log/rmon. After installation or an update, sign in, confirm that checks receive fresh results, and verify a test notification. For assistance, contact RMON support.
Kubernetes installation
Install RMON with Helm 3 or Helm 4 from oci://ghcr.io/roxy-wi/rmon/rmon-chart. Chart 1.4.2 installs RMON 1.4.0 and RMON Server 7.0. Agents are installed on the hosts you monitor through RMON; they are not installed on Kubernetes nodes by this chart.
Prepare a Kubernetes cluster with Linux amd64 nodes, a persistent StorageClass, an Ingress controller, a DNS name and its HTTPS certificate. The chart requires Kubernetes 1.25 or newer. Allow access to your database, SSH access to agent hosts and outbound access to your notification providers. Agents need to reach both the RMON address and their configured result server.
The initial configuration uses SQLite and one instance of each service. All RMON pods share ReadWriteOnce storage on one node. Use a StorageClass suitable for a local SQLite database; do not put SQLite on an NFS or other shared network filesystem. For an external PostgreSQL or MySQL database, ReadWriteMany storage is also supported. Persistent storage is still required for application keys, SSH files and logs. This chart does not configure a highly available installation.
Prepare a new installation
Run the following commands from a trusted administration machine with Python 3, Helm and kubectl. They create files for a new installation only. Choose an administrator password of at least 12 characters. Back up the generated configuration and keys securely.
kubectl create namespace rmon
umask 077
python3 - <<'PY'
import base64, configparser, getpass, secrets
from pathlib import Path
password = getpass.getpass('Initial admin password: ')
if len(password) < 12:
raise SystemExit('Use at least 12 characters')
if password != getpass.getpass('Confirm password: '):
raise SystemExit('Passwords do not match')
config = configparser.ConfigParser()
config['main'] = {'lib_path': '/var/lib/rmon', 'log_path': '/var/log/rmon',
'secret_phrase': base64.urlsafe_b64encode(secrets.token_bytes(32)).decode()}
config['mysql'] = {'enable': '0', 'mysql_host': '', 'mysql_port': '3306',
'mysql_user': 'rmon', 'mysql_password': '', 'mysql_db': 'rmon'}
config['pgsql'] = {'enable': '0', 'host': '', 'port': '5432',
'user': 'rmon', 'password': '', 'db': 'rmon'}
with Path('rmon.cfg').open('x') as stream:
config.write(stream)
with Path('admin-password').open('x') as stream:
stream.write(password)
with Path('server-token').open('x') as stream:
stream.write(secrets.token_urlsafe(32))
PY
kubectl -n rmon create secret generic rmon-config --from-file=rmon.cfg
kubectl -n rmon create secret generic rmon-admin --from-file=admin-password
kubectl -n rmon create secret generic rmon-server-token --from-file=token=server-token
kubectl -n rmon create secret tls rmon-web-tls --cert=fullchain.pem --key=privkey.pem
For a new external database, edit the corresponding section of rmon.cfg before creating the Secret and enable only that backend. See database configuration. Do not change lib_path or log_path. Restrict access to Kubernetes Secrets and Helm release records.
Create values.yaml, replacing the hostname, Ingress class and storage class with your cluster's values:
fullnameOverride: rmon
publicURL: https://monitor.example.com
cookieSecure: true
existingConfigSecret: rmon-config
bootstrap:
enabled: true
existingSecret: rmon-admin
persistence:
size: 5Gi
storageClass: YOUR_STORAGE_CLASS
accessModes: [ReadWriteOnce]
server:
existingTokenSecret: rmon-server-token
transport: http
service:
type: ClusterIP
ingress:
enabled: true
className: YOUR_INGRESS_CLASS
host: monitor.example.com
tls:
- secretName: rmon-web-tls
hosts: [monitor.example.com]
The result server initially accepts HTTP connections inside the cluster. Before connecting agents outside the cluster, configure a reachable result endpoint as described below. publicURL must be reachable by users and agents; set agentControlURL only if agents need a different RMON address.
helm upgrade --install rmon oci://ghcr.io/roxy-wi/rmon/rmon-chart \
--version 1.4.2 --namespace rmon --values values.yaml --wait --timeout 10m
kubectl -n rmon get pods,pvc,services,ingress
Open your HTTPS address and sign in as admin with the password you chose. Set bootstrap.enabled: false in values.yaml after the first successful installation, and repeat the Helm command. You can then remove the initial-password Secret and its local file. Preserve rmon-config, the server token, the data volume and their backups. Initialization never changes an existing administrator password or applies database migrations.
Connect agents to the result server
For external agents, use a LoadBalancer or another reachable TCP endpoint for the result service, create a DNS record and allow access from agent networks. Do not expose the initial HTTP endpoint publicly. Configure HTTPS or mTLS on RMON Server before opening the endpoint.
Create a Secret with the server certificate and key, and another Secret with the trusted CA. The server certificate must include the public result hostname, rmon-server (the Service name with the example values) and 127.0.0.1 for local health checks. For mTLS, the client Secret must also contain a client certificate and key trusted by the server. Keep the CA signing key outside the cluster.
kubectl -n rmon create secret generic rmon-result-tls \
--from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt
kubectl -n rmon create secret generic rmon-result-client \
--from-file=ca.crt=ca.crt
For mTLS, add --from-file=tls.crt=client.crt --from-file=tls.key=client.key when creating rmon-result-client. Update the server section in your values file and run the Helm command again:
server:
enabled: true
existingTokenSecret: rmon-server-token
transport: https # use mtls to require client certificates
tls:
existingServerSecret: rmon-result-tls
existingClientSecret: rmon-result-client
service:
type: LoadBalancer
port: 5100
In RMON, set the result server hostname and port under Admin area → Settings. Configure the matching connection mode and certificates for the agents as described in Standalone RMON Server. Installing the chart does not configure existing agents. Create a check and confirm that fresh results arrive before moving the rest of your agents.
To use an existing result server instead, set server.enabled: false, server.externalURL and server.existingTokenSecret. If it uses a private CA or mTLS, mount its client certificates with extraVolumes/extraVolumeMounts and set RMON_SERVER_CA_FILE, RMON_SERVER_CLIENT_CERT_FILE and RMON_SERVER_CLIENT_KEY_FILE through extraEnv. RMON Server and RMON must use the same database.
Move an existing installation
Take a consistent backup and stop the old services before moving data. Preserve the existing rmon.cfg, its encryption key and the complete application-key directory. Restore the database, keys and SSH files to the persistent volume; put logs in its logs directory. The data must be accessible to UID/GID 33:33. Keep backups until checks, notifications and agent management work on the new installation.
Use existingConfigSecret for the original configuration and persistence.existingClaim for the restored volume. Keep bootstrap.enabled: false. For an external database, preserve its connection details and do not initialize it again. A move between database engines requires a separate data migration; changing Helm values does not copy data.
Update, maintenance and recovery
For every update, check the version-specific update guide and back up the database, configuration, application keys and SSH files. A pod restart or Helm upgrade does not migrate the database. If the target version requires migrations, use these steps. Replace CHART_VERSION with the target chart version and keep the same release name, namespace, Secrets and volume.
# First stop the current version and wait for every RMON pod to exit.
helm upgrade rmon oci://ghcr.io/roxy-wi/rmon/rmon-chart \
--version CURRENT_CHART_VERSION -n rmon -f values.yaml \
--set bootstrap.enabled=false --set maintenance=true --wait
kubectl -n rmon wait pod -l app.kubernetes.io/instance=rmon --for=delete --timeout=35m
# Run the existing database migration command with the target version.
helm upgrade rmon oci://ghcr.io/roxy-wi/rmon/rmon-chart \
--version CHART_VERSION -n rmon -f values.yaml \
--set bootstrap.enabled=false --set maintenance=true --set migration.enabled=true \
--wait --wait-for-jobs --timeout=10m
kubectl -n rmon logs -l app.kubernetes.io/component=migration
# Start services only after the migration job succeeds.
helm upgrade rmon oci://ghcr.io/roxy-wi/rmon/rmon-chart \
--version CHART_VERSION -n rmon -f values.yaml \
--set bootstrap.enabled=false --set maintenance=false --set migration.enabled=false \
--wait --timeout=10m
If a migration fails, keep maintenance enabled, inspect the Job logs and correct the cause before proceeding. Do not use an older application against a changed schema without following the recovery guide. To restore service after a failed update, restore the matching database, keys, configuration and application version together.
After changing an existing Secret, restart the affected deployments during a maintenance window because running pods may still use the previous values. Use kubectl -n rmon rollout restart deployment -l app.kubernetes.io/instance=rmon and wait for readiness. Verify sign-in, agent management, a fresh check result and a notification.
helm uninstall keeps the chart-created data volume by default (persistence.keep: true). Secrets you supplied yourself also remain. This is not a backup: keep independent backups and delete stored data only when you intend to remove the installation permanently.
Native installation requirements
This documentation describes RMON 1.4.0, RMON Server 7.0 and Agent 2.0. Package availability can differ by operating system and release. Check the versions offered by your package manager before installing. If the intended version is absent, wait for its publication or use an available deployment option; installing an older package does not provide the features described for 1.4.
RPM and DEB packages are publicly available from the RMON package repository. Downloading and installing them requires no account, password or access key. Confirm that the repository contains packages for your Linux release and CPU architecture before installing.
Prepare a hostname, HTTPS certificate and administrator access to the installation host. Allow SSH administration of agent hosts, access from agents to their monitoring targets and result server, and outbound access needed by your notification providers.
RPM installation
On Enterprise Linux 8 or 9, download the public repository configuration to /etc/yum.repos.d/rmon.repo. It selects the repository for your Enterprise Linux major version and configures RPM signature verification:
sudo dnf install curl ca-certificates
sudo curl --fail --show-error --silent --location https://repo.rmon.io/rmon.repo --output /etc/yum.repos.d/rmon.repo
sudo dnf makecache --refresh
sudo dnf list --showduplicates rmon rmon-server
Confirm that the listed versions match your intended installation, then install the services needed on this host:
sudo dnf install rmon rmon-server
sudo systemctl enable --now rmon-server httpd
When the result server runs on another host, install rmon-server there and use its reachable address in RMON.
Ubuntu installation
On Ubuntu with an amd64 CPU architecture, check that your release is listed in the available Ubuntu repositories. Create /etc/apt/sources.list.d/rmon.list using the code name of your installed Ubuntu release:
Download the repository's public signing key, then create the source entry. These commands do not require a repository account or access token:
sudo apt install ca-certificates curl
sudo install -d -m 0755 /etc/apt/keyrings
sudo curl --fail --show-error --silent --location https://repo.rmon.io/RPM-GPG-KEY-RMON --output /etc/apt/keyrings/rmon.asc
sudo chmod 0644 /etc/apt/keyrings/rmon.asc
. /etc/os-release
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rmon.asc] https://repo.rmon.io/ubuntu ${VERSION_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/rmon.list > /dev/null
The public key verifies the repository signature; it is not a login credential or license key. If this host already has an older RMON source entry, replace it with the entry above instead of keeping duplicate entries. Refresh the package list and install RMON:
sudo apt update
sudo apt-cache policy rmon rmon-server
Confirm that the candidate versions match your intended installation, then install:
sudo apt install rmon rmon-server
sudo systemctl enable --now rmon-server apache2
Use the installation's initial administrator account and change any temporary password before adding users. Docker initialization asks you to choose the password; do not assume a universal default password.
Initial configuration
Open RMON over HTTPS. Under Admin area → Settings, enter the license, time zone and the reachable result server address. Continue with groups, SSH credentials and servers, agents, checks and notifications.
Database configuration
SQLite is the default. For a new MySQL or PostgreSQL deployment, ask the database administrator to create the database and a dedicated account, then configure /etc/rmon/rmon.cfg before initializing RMON. Enable only the backend you use. Replace the example host and password with the values supplied for your database.
[mysql]
enable = 1
mysql_user = rmon
mysql_password = REPLACE_WITH_DATABASE_PASSWORD
mysql_db = rmon
mysql_host = db.example.com
mysql_port = 3306
For PostgreSQL, leave MySQL disabled and configure:
[pgsql]
enable = 1
user = rmon
password = REPLACE_WITH_DATABASE_PASSWORD
db = rmon
host = db.example.com
port = 5432
Restrict access to this file. Changing the backend does not migrate existing data. For an existing installation, take a consistent backup and preserve its database and application keys using the backup and recovery guide; arrange a separate data migration before changing database type.
HTTPS access
For a native installation, configure the supplied Apache virtual host with your public hostname and certificate. Its certificate paths are /etc/ssl/certs/rmon.crt and /etc/ssl/certs/rmon.key. Include the required certificate chain, protect the private key, check Apache's configuration and reload the web service.
For Docker, use the proxy certificate settings. Verify HTTPS from the user's device before adding saved credentials to RMON.
Preserve application keys
Application keys protect saved credentials and sign-in sessions. For a new installation, use the generated keys. Keep the same keys during updates, moves and restores; replacing them can make saved credentials unreadable. See application keys and backups.
Standalone RMON Server
Run a separate result receiver when it belongs on another host or needs its own HTTP, HTTPS or mTLS endpoint. Follow the Standalone RMON Server guide for deployment, database access, certificates, diagnostics and final verification.