XRPL Validator Docker Monitoring Guide
Revision: September 2026
Need monitoring credentials? If you do not have a Basic Auth username and password, request monitoring access before you start this guide.
Introduction
This guide explains how to connect an xrpld validator host to the XRPL monitoring platform with Grafana Alloy running in Docker.
Still running rippled (pre-3.2.0)? rippled was renamed to xrpld in version 3.2.0. Use your existing
rippled.cfgwherever this guide saysxrpld.cfg. In the Docker commands, replace the host paths before the first:in the configuration and log mounts with your existing paths. Keep the paths inside Alloy unchanged.
Opting in gives the validator operator access to validator health in Grafana. Metrics and logs make it easier to catch problems early, confirm that telemetry is flowing, and troubleshoot incidents without manually collecting log files after the fact.
The setup is designed to stay under the operator’s control. Alloy reads local telemetry and pushes it with credentials provided by the XRPL Foundation, but the Alloy container does not edit xrpld.cfg or restart xrpld. You make any required node changes in the steps below.
The mental model is simple:
xrpld -> Docker -> Alloy container -> XRPL monitoring proxy -> Grafana
Grafana Alloy runs in a container on the validator host. It reads local xrpld telemetry and pushes it to the monitoring platform:
- StatsD metrics are collected.
- The commands below also enable host resource metrics. You can disable them as described under Optional Host Metrics.
debug.logandperf.logare collected.- Grafana shows the validator dashboards.
The trusted validator identity is the Basic Auth username provided by the XRPL Foundation. The local node label is only a dashboard filter. Operators may optionally supply the validator’s public master key for correlation with public XRPL network statistics.
Use the Docker path when the host already runs Docker and you want Alloy kept in a container. Use the native guide when you prefer the hosted installer, systemd, and OS packages.
What You Need
The XRPL Foundation provides:
- Monitoring push host:
push.monitoring.xrplf.org. - Grafana URL:
https://monitoring.xrplf.org. - Basic Auth username and password.
- Grafana account access.
The validator host needs:
- Linux with Docker and permission to run Docker commands.
- Bash and
curlfor the setup commands. - A readable
xrpld.cfg. - Optionally, the validator’s public 52-character
nHmaster key for correlation with public XRPL network statistics. This is not an account address, signing key, private key, or seed. - StatsD metrics,
debug.log, andperf.logavailable fromxrpld. - Outbound HTTPS access to
push.monitoring.xrplf.organd Docker Hub.
Check Monitoring Credentials
Check the username and password before storing them in the Alloy config. Replace <username> with the Basic Auth username from the XRPL Foundation:
curl --fail-with-body \
--user '<username>' \
https://push.monitoring.xrplf.org/healthcurl asks for the password without displaying it. A successful check prints:
ok
An HTTP 401 means the username or password is wrong. An HTTP 403 means the credentials are valid but are not yet assigned to a monitoring tenant. Contact the XRPL Foundation if either error continues.
Configure xrpld
These settings apply whether xrpld runs directly on Linux or in Docker.
Back up xrpld.cfg before changing it.
Set StatsD to the node’s localhost. Use UDP port 9125 unless it is already in use:
[insight]
server=statsd
address=127.0.0.1:9125
prefix=xrpld
Keep your existing prefix if you already use one. The container reads the prefix from xrpld.cfg and builds the StatsD mapping at startup.
Keep the address on 127.0.0.1. If you choose another port, use that port in the matching Alloy command below.
Enable both debug and perf logs.
You can keep your existing filenames and directories. In xrpld.cfg, use paths that xrpld can write to. If xrpld runs in Docker, use paths inside its container.
When you run Alloy below, mount the host directories that contain these logs. For different filenames, also set ALLOY_LOG_DEBUG and ALLOY_LOG_PERF to the paths inside the Alloy container. See Log Directory Mount for examples, including logs in separate directories.
Example debug log setting:
[debug_logfile]
/var/log/xrpld/debug.log
Example perf log settings:
[perf]
perf_log=/var/log/xrpld/perf.log
log_interval=2
Restart xrpld using your normal process after changing that file.
Run With Docker
Pull the latest published image before starting or recreating the container:
docker pull xrplf/xrpl-monitoring-alloy:latestRun the setup commands in Bash, in the same terminal. Create the password file without a final newline:
(
set -e
umask 077
password_tmp="$(mktemp ./.xrpl-push.XXXXXX)"
trap 'rm -f -- "$password_tmp"' EXIT
printf '%s' 'Monitoring push password: ' >&2
IFS= read -r -s xrpl_push_password
printf '\n' >&2
printf '%s' "$xrpl_push_password" >"$password_tmp"
unset xrpl_push_password
chmod 0600 "$password_tmp"
mv -fT -- "$password_tmp" xrpl-push
trap - EXIT
)
password_file="$(realpath xrpl-push)"Keep this file outside version control.
Use this table to choose Host node or Docker node below, then copy its command:
| Where xrpld runs | Choose |
|---|---|
On Linux, or in Docker with --network host |
Host node |
| In Docker with its own network | Docker node |
Replace the labels, username, public key, and host paths in the command. If you do not use a public validator master key, remove the entire -e ALLOY_VALIDATOR_MASTER_KEY=... line. These commands enable host metrics with read-only host mounts. Remove the host-metrics flag and its three mounts if you do not want that access.
Use this for a Linux node or an xrpld container started with --network host. Alloy receives StatsD through the published host loopback port.
docker run -d \
--name xrpl-monitoring-alloy \
--restart unless-stopped \
-p 127.0.0.1:9125:9125/udp \
-p 127.0.0.1:12345:12345 \
-e ALLOY_NODE=<node-label> \
-e ALLOY_PUSH_HOST=push.monitoring.xrplf.org \
-e ALLOY_USERNAME=<basic-auth-user> \
-e ALLOY_VALIDATOR_MASTER_KEY=<public-validator-master-key> \
-e ALLOY_HOST_METRICS_ENABLED=true \
--mount type=bind,src="$password_file",dst=/run/secrets/xrpl_monitoring_password,readonly \
-v /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro \
-v /var/log/xrpld:/xrpld-logs:ro \
--mount type=bind,src=/,dst=/host/root,readonly,bind-propagation=rslave \
--mount type=bind,src=/proc,dst=/host/proc,readonly \
--mount type=bind,src=/sys,dst=/host/sys,readonly \
-v alloy-data:/var/lib/alloy/data \
xrplf/xrpl-monitoring-alloy:latestFor another StatsD port, such as 19125, use -p 127.0.0.1:19125:9125/udp and add -e ALLOY_XRPLD_STATSD_ADDRESS=127.0.0.1:19125. The container port stays 9125.
Use Docker Compose instead
Use this instead of the docker run command. Save it as compose.yaml beside the xrpl-push password file created above. Replace the node label, username, and host paths. Leave the public key empty to skip validator correlation.
These settings enable host metrics, as in the command above.
services:
alloy:
image: xrplf/xrpl-monitoring-alloy:latest
container_name: xrpl-monitoring-alloy
restart: unless-stopped
ports:
- "127.0.0.1:9125:9125/udp"
- "127.0.0.1:12345:12345"
environment:
ALLOY_NODE: "<node-label>"
ALLOY_PUSH_HOST: "push.monitoring.xrplf.org"
ALLOY_USERNAME: "<basic-auth-user>"
ALLOY_VALIDATOR_MASTER_KEY: ""
ALLOY_HOST_METRICS_ENABLED: "true"
ALLOY_XRPLD_STATSD_ADDRESS: "127.0.0.1:9125"
secrets:
- xrpl_monitoring_password
volumes:
- /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro
- /var/log/xrpld:/xrpld-logs:ro
- /:/host/root:ro,rslave
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- alloy-data:/var/lib/alloy/data
volumes:
alloy-data:
name: alloy-data
secrets:
xrpl_monitoring_password:
file: ./xrpl-pushFrom that directory, check the file and start Alloy:
docker compose config --quiet
docker compose pull
docker compose up -dView its logs with docker compose logs --tail 100 alloy. For another StatsD port, change the host port in ports and the port in ALLOY_XRPLD_STATSD_ADDRESS to match xrpld.cfg. Keep the container port 9125.
After changing the password file, run docker compose up -d --force-recreate alloy. To stop Alloy, run docker compose down. Keep the data volume by leaving out --volumes.
Start the node first. Replace xrpld in --network container:xrpld with its container name. Use the host paths of the node’s configuration and log mounts. Sharing its network does not share its files.
docker run -d \
--name xrpl-monitoring-alloy \
--restart unless-stopped \
--network container:xrpld \
-e ALLOY_NODE=<node-label> \
-e ALLOY_PUSH_HOST=push.monitoring.xrplf.org \
-e ALLOY_USERNAME=<basic-auth-user> \
-e ALLOY_VALIDATOR_MASTER_KEY=<public-validator-master-key> \
-e ALLOY_HOST_METRICS_ENABLED=true \
-e ALLOY_STATSD_LISTEN=127.0.0.1:9125 \
-e ALLOY_XRPLD_STATSD_ADDRESS=127.0.0.1:9125 \
--mount type=bind,src="$password_file",dst=/run/secrets/xrpl_monitoring_password,readonly \
-v /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro \
-v /var/log/xrpld:/xrpld-logs:ro \
--mount type=bind,src=/,dst=/host/root,readonly,bind-propagation=rslave \
--mount type=bind,src=/proc,dst=/host/proc,readonly \
--mount type=bind,src=/sys,dst=/host/sys,readonly \
-v alloy-data:/var/lib/alloy/data \
xrplf/xrpl-monitoring-alloy:latest \
run --server.http.listen-addr=127.0.0.1:12345 \
--storage.path=/var/lib/alloy/data \
/etc/alloy/config.alloyFor another StatsD port, change 9125 in both StatsD environment values. Do not add -p options. Alloy’s UI is on localhost inside the node’s network, not on host localhost. Both listener ports must be free in that network.
After the node container restarts or is replaced, recreate Alloy with this command to join its current network. Keep the alloy-data volume.
Use Docker Compose instead
Use this instead of the docker run command. Save it as compose.yaml beside the xrpl-push password file created above. Replace the node label, username, and host paths. Leave the public key empty to skip validator correlation. Replace xrpld in network_mode with your running node container’s name.
These settings enable host metrics, as in the command above.
services:
alloy:
image: xrplf/xrpl-monitoring-alloy:latest
container_name: xrpl-monitoring-alloy
restart: unless-stopped
network_mode: "container:xrpld"
environment:
ALLOY_NODE: "<node-label>"
ALLOY_PUSH_HOST: "push.monitoring.xrplf.org"
ALLOY_USERNAME: "<basic-auth-user>"
ALLOY_VALIDATOR_MASTER_KEY: ""
ALLOY_HOST_METRICS_ENABLED: "true"
ALLOY_STATSD_LISTEN: "127.0.0.1:9125"
ALLOY_XRPLD_STATSD_ADDRESS: "127.0.0.1:9125"
secrets:
- xrpl_monitoring_password
volumes:
- /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro
- /var/log/xrpld:/xrpld-logs:ro
- /:/host/root:ro,rslave
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- alloy-data:/var/lib/alloy/data
command:
- run
- --server.http.listen-addr=127.0.0.1:12345
- --storage.path=/var/lib/alloy/data
- /etc/alloy/config.alloy
volumes:
alloy-data:
name: alloy-data
secrets:
xrpl_monitoring_password:
file: ./xrpl-pushFrom that directory, check the file and start Alloy:
docker compose config --quiet
docker compose pull
docker compose up -dView its logs with docker compose logs --tail 100 alloy. For another StatsD port, change both StatsD environment values to match xrpld.cfg. Do not add ports to this setup.
After changing the password file or restarting the node container, run docker compose up -d --force-recreate alloy. To stop Alloy, run docker compose down. Keep the data volume by leaving out --volumes.
After changing the password file, recreate Alloy so Docker mounts the new file. Verify new xrpld_* metrics and both log streams in Grafana.
Command Breakdown
This table explains the general options in both commands. Docker node only marks options specific to that setup. Keep reading for details on passwords, metrics, ports, and mounts under Why These Options Matter.
| Part | What it does |
|---|---|
docker run -d |
Creates and starts a new container. -d runs it in the background so the terminal remains available. |
--name xrpl-monitoring-alloy |
Names this container. Use this name with docker logs, docker stop, and docker rm. It must be unique on the Docker host. |
--restart unless-stopped |
Restarts the container if it exits or Docker restarts. If you stop it manually, it stays stopped until you start it again. |
--network container:xrpld |
Docker node only. Shares the node container’s network so Alloy can receive metrics at the node’s local address. Replace xrpld with your node’s container name. |
-e ALLOY_NODE=… |
Sets the node label shown in Grafana. Replace <node-label> with a stable name that distinguishes this node within your monitoring tenant. |
-e ALLOY_PUSH_HOST=… |
Sets push.monitoring.xrplf.org as the destination for telemetry sent over HTTPS. |
-e ALLOY_USERNAME=… |
Sets the Basic Auth username supplied by the XRPL Foundation. This account determines the monitoring tenant. The password comes from the file mount below. |
xrplf/xrpl-monitoring-alloy:latest |
The published image pulled earlier. Docker starts a container from that local image. latest is a tag, not an automatic update service. |
run after the image name |
Docker node only. Starts Alloy with the settings that follow. The Host node command uses the image’s default startup settings. |
/etc/alloy/config.alloy |
Docker node only. Selects the Alloy configuration included in the image. This is separate from the node’s xrpld.cfg. |
Why These Options Matter
Monitoring Password Secret
--mount type=bind,src=<password-file>,dst=/run/secrets/xrpl_monitoring_password,readonly
The password is stored in a host file with mode 0600, not in a Docker environment variable. The entrypoint rejects a missing, empty, unreadable, or newline-terminated file. Alloy reads the file with local.file and is_secret = true. This keeps the password redacted in the Alloy component API, UI, and support bundle.
A listener on host 127.0.0.1 can still be reached by every local user. Localhost is not per-user access control. Do not put a literal password in config.alloy or an environment variable even when the UI port is bound only to localhost.
Optional Validator Correlation
-e ALLOY_VALIDATOR_MASTER_KEY=<public-validator-master-key>
This opt-in value must be the public 52-character validator master key that starts with nH. The startup check validates only its structure, it does not validate the key’s checksum or ownership. Leave the variable unset or exactly empty to opt out. Never use an account address, signing key, private key, or seed.
The public master key is attached only to the Prometheus up metric. It is not attached to other metrics or any Loki log stream, and it does not replace the Basic Auth tenant as the trusted identity.
ALLOY_VALIDATOR_MASTER_KEY is for the public validator master key only. Never enter a private key or seed. This public value is visible through Docker inspection.
Changing the public key or opting out requires recreating the container with the new environment. Existing labeled series remain in the backend until normal retention removes them.
Optional Log Redaction
Set ALLOY_HOST_REDACTION to redact matching host or domain text from the debug and perf logs. Set ALLOY_PUBKEY_REDACTION to redact matching public keys from the debug log. Each value is a regex. Unset or empty values use ^$, which disables that extra redaction. The existing IP-address redaction in the debug log is unchanged.
Add either option to docker run before the image name:
-e 'ALLOY_HOST_REDACTION=validator[.]example[.]com' \
-e 'ALLOY_PUBKEY_REDACTION=n9ExamplePublicKey' \Replace the examples with narrow patterns for your host or public key. Single quotes preserve regex characters. Do not use broad patterns such as .*. Environment values are visible through Docker inspection, do not put passwords, private keys, or seeds in these fields. These settings do not change metric labels or ALLOY_VALIDATOR_MASTER_KEY.
Recreate the Alloy container after changing either value. Previously stored logs are not changed. An invalid regex causes a startup error, check the container logs. Check new log entries in Grafana to confirm the intended text is redacted.
Optional Host Metrics
Both docker run commands above enable host metrics with these options:
-e ALLOY_HOST_METRICS_ENABLED=true \
--mount type=bind,src=/,dst=/host/root,readonly,bind-propagation=rslave \
--mount type=bind,src=/proc,dst=/host/proc,readonly \
--mount type=bind,src=/sys,dst=/host/sys,readonly \Alloy collects a fixed basic set of CPU, memory, load, filesystem, disk, network, system-time, kernel, and virtual-memory metrics every 15 seconds. The metrics use job="node_exporter", service_name="node_exporter", and the configured node label for node and instance. They use the existing Mimir connection and monitoring tenant.
With either command above, node_network_* measures the container’s network traffic. These commands do not collect the host’s network interface counters. Host CPU, memory, and disk metrics are still collected.
The host pipeline does not add validator_master_key. It drops disk identity metrics and real hostname labels. View enabled host metrics in the XRPL Validator Resources dashboard. This option does not add host alerts.
The mounts are read-only, but they let the container read host files. The root mount uses rslave propagation so filesystem metrics follow the host mount tree. Omit the enable flag and all three mounts to keep the feature disabled. To opt out later, remove the flag and all three mounts, then recreate the container. Historical samples remain until backend retention removes them.
StatsD Port
-p 127.0.0.1:<host-port>:9125/udp
The Host node command uses this Docker port publish rule for StatsD:
127.0.0.1binds the port only on host localhost, so it is not opened to the network.<host-port>is the UDP port fromxrpld.cfg, for example9125or19125.9125/udpis the container port and protocol. Keep this as9125/udpbecause the image listens on0.0.0.0:9125inside the container in bridge mode.
xrpld sends UDP StatsD packets to host 127.0.0.1:<host-port>, Docker forwards them into the container, and Alloy receives them on container port 9125.
The 0.0.0.0 listener is container-internal in bridge mode. It is not opened to the host network because the Docker publish rule binds the host side to 127.0.0.1.
The Docker node command does not publish ports. Its StatsD listener shares the node’s localhost. ALLOY_STATSD_LISTEN sets where Alloy receives metrics. ALLOY_XRPLD_STATSD_ADDRESS sets the address Alloy checks against xrpld.cfg. Set both to the StatsD address in that file. For Host node, add ALLOY_XRPLD_STATSD_ADDRESS if you change the host StatsD port.
Alloy UI Port
-p 127.0.0.1:12345:12345
In the Host node command, this exposes the Alloy UI and API at http://127.0.0.1:12345 on the validator host. In the Docker node command, the UI listener uses --server.http.listen-addr=127.0.0.1:12345 and is available only inside the shared node network.
To access the UI from the host with a Docker node, follow these optional steps:
Adding the port requires recreating the xrpld container. Plan for a node interruption and keep its existing configuration, data mounts, and other settings.
- Add
-p 127.0.0.1:12345:12345to the xrpld container’s Docker command and recreate that container. - In the Alloy command, change
--server.http.listen-addr=127.0.0.1:12345to--server.http.listen-addr=0.0.0.0:12345, then recreate Alloy. - Open
http://127.0.0.1:12345on the validator host.
Publish the port on xrpld because Docker does not allow -p on Alloy when it shares another container’s network. The published host port is local only, but other containers on the node’s network can also reach the UI and API.
xrpld.cfg Mount
-v /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro
The entrypoint checks the telemetry settings in xrpld.cfg and reads the StatsD prefix from it. The :ro flag makes it read-only, so the container cannot modify this operator-owned file.
Log Directory Mount
-v /path/to/xrpld-log-directory:/xrpld-logs:ro
By default, Alloy reads /xrpld-logs/debug.log and /xrpld-logs/perf.log from this read-only directory mount. To select other filenames, add these options to docker run before the image name:
-e ALLOY_LOG_DEBUG=/xrpld-logs/node-debug.log \
-e ALLOY_LOG_PERF=/xrpld-logs/node-perf.log \
Both values are paths inside the container, not host paths. Unset or empty values keep the defaults. Preflight and collection use the same selected paths. These settings do not edit xrpld.cfg or create mounts. Use explicit readable file paths, not glob patterns.
For separate directories, replace the original log directory mount in the docker run command with these options:
-e ALLOY_LOG_DEBUG=/xrpld-logs/node-debug.log \
-e ALLOY_LOG_PERF=/xrpld-perf/node-perf.log \
-v /var/log/xrpld-debug:/xrpld-logs:ro \
-v /var/log/xrpld-perf:/xrpld-perf:ro \
Replace the example host directories and filenames with those used by your node. Recreate Alloy after changing paths or mounts.
Keep directory mounts even with custom names. They let Alloy open replacement files after rotation. An individual file bind mount stays attached to the old file and stops shipping new entries after rename/reopen rotation.
Alloy Data Volume
-v alloy-data:/var/lib/alloy/data
Docker creates the alloy-data volume if needed. Alloy stores queues and log read positions there. Keep this volume when recreating Alloy so it can resume from its saved state.
The Docker node command sets --storage.path=/var/lib/alloy/data explicitly to use this volume. The Host node command uses the same path by default.
Existing StatsD Collector
If xrpld already sends StatsD to another collector, Alloy can forward metrics to it. Add this environment option to your Alloy command:
-e ALLOY_STATSD_RELAY_ADDR=<collector-host>:<collector-port>
This must be the existing collector’s StatsD UDP listener, for example a statsd_exporter UDP port. It is not the Prometheus HTTP scrape port.
Keep xrpld pointed at Alloy’s StatsD listener. Alloy forwards the original StatsD packets to ALLOY_STATSD_RELAY_ADDR unchanged, while also sending mapped metrics to the XRPL monitoring platform.
Use a collector address reachable from Alloy. With the Docker node setup, 127.0.0.1 refers to the node container’s shared network. With the Host node command above, it refers to Alloy’s own container. If there is no existing collector, leave ALLOY_STATSD_RELAY_ADDR empty.
The examples below are for Host node only. They replace the main Alloy command and leave host metrics disabled. Add the options from Optional Host Metrics if you want those metrics.
For a host collector that is reachable from Docker, add a host gateway name and use it as the relay target:
docker run -d \
--name xrpl-monitoring-alloy \
--restart unless-stopped \
--add-host=host.docker.internal:host-gateway \
-p 127.0.0.1:9125:9125/udp \
-p 127.0.0.1:12345:12345 \
-e ALLOY_NODE=<node-label> \
-e ALLOY_PUSH_HOST=push.monitoring.xrplf.org \
-e ALLOY_USERNAME=<basic-auth-user> \
-e ALLOY_VALIDATOR_MASTER_KEY=<public-validator-master-key> \
-e ALLOY_STATSD_RELAY_ADDR=host.docker.internal:8125 \
--mount type=bind,src="$password_file",dst=/run/secrets/xrpl_monitoring_password,readonly \
-v /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro \
-v /var/log/xrpld:/xrpld-logs:ro \
-v alloy-data:/var/lib/alloy/data \
xrplf/xrpl-monitoring-alloy:latestThat only works if the existing collector listens on an address reachable from the Docker bridge. If it only listens on host 127.0.0.1, Docker bridge containers cannot reach it through host.docker.internal.
Host Network Relay
If the existing collector only listens on host localhost, use Docker host networking instead of bridge mode. In host networking, the container shares the host network namespace:
container 127.0.0.1 == host 127.0.0.1
That means ALLOY_STATSD_RELAY_ADDR=127.0.0.1:8125 can reach a collector bound to host localhost. It also means Docker port publishing is not used.
Example:
docker run -d \
--name xrpl-monitoring-alloy \
--restart unless-stopped \
--network host \
-e ALLOY_NODE=<node-label> \
-e ALLOY_PUSH_HOST=push.monitoring.xrplf.org \
-e ALLOY_USERNAME=<basic-auth-user> \
-e ALLOY_VALIDATOR_MASTER_KEY=<public-validator-master-key> \
-e ALLOY_STATSD_LISTEN=127.0.0.1:9125 \
--mount type=bind,src="$password_file",dst=/run/secrets/xrpl_monitoring_password,readonly \
-e ALLOY_STATSD_RELAY_ADDR=127.0.0.1:8125 \
-v /etc/xrpld/xrpld.cfg:/xrpld-config/xrpld.cfg:ro \
-v /var/log/xrpld:/xrpld-logs:ro \
-v alloy-data:/var/lib/alloy/data \
xrplf/xrpl-monitoring-alloy:latest \
run --server.http.listen-addr=127.0.0.1:12345 \
--storage.path=/var/lib/alloy/data \
/etc/alloy/config.alloyFor this mode, keep xrpld.cfg pointed at:
address=127.0.0.1:9125
There is no -p option because Docker is not translating ports. Alloy binds directly on the host network. Keep ALLOY_STATSD_LISTEN and --server.http.listen-addr on 127.0.0.1 unless you intentionally want those listeners reachable from outside the host.
Startup Checks
The container entrypoint checks:
ALLOY_HOST_METRICS_ENABLEDis exactlytrueorfalse.- Enabled host metrics have readable host root, procfs, and sysfs mounts.
- The optional validator master key is exactly empty or has the public 52-character
nHstructure, before checking files or other configuration. - Required environment variables are present and not placeholders.
- The password secret is mounted, readable, non-empty, and has no final newline.
xrpld.cfgis mounted and readable.- The selected debug and perf log files are mounted and readable.
- There is one
[insight]section, with no repeatedserver,address, orprefixkeys. Duplicates are rejected even when their values match, the error identifies the duplicate and its line number. Alloy does not rewrite the node configuration. [insight] serverisstatsd.[insight] addressmatches the configured StatsD destination.[insight] prefixexists.- The generated StatsD mapping can be read.
alloy validate /etc/alloy/config.alloypasses.
These checks validate the files and settings before Alloy starts. They do not confirm that listener ports are free or that live StatsD traffic is arriving.
StatsD is UDP. There is no connection handshake to check, and the entrypoint runs before Alloy starts receiving packets. xrpld also emits StatsD over time, not on demand. For that reason, the entrypoint cannot prove StatsD is working end to end.
Grafana Setup & Access
The XRPL Foundation provides Grafana account access. Open:
https://monitoring.xrplf.org
After Alloy starts, wait a few minutes, then open:
XRPL Validator HealthXRPL StatsD MetricsXRPL Logs & Triage
If you kept host metrics enabled, open XRPL Validator Resources to check them.
Use the dashboard filters:
validator: the monitoring tenant.node: the node label entered during install.- For logs:
file,level, andmodule.
If data does not appear:
Check Alloy:
docker ps -a --filter name=xrpl-monitoring-alloyCheck Alloy logs:
docker logs --tail 100 xrpl-monitoring-alloyConfirm the StatsD destination matches the published host UDP port in bridge mode, or Alloy’s listener in shared-container or host mode.
Confirm the selected debug and perf log paths are mounted and readable.
Confirm the push host and credentials with the XRPL Foundation.
Finding Errors
Check whether the container is running:
docker ps -a --filter name=xrpl-monitoring-alloyCheck startup errors:
docker logs xrpl-monitoring-alloyCommon entrypoint errors:
ALLOY_HOST_METRICS_ENABLED must be true or falsemeans the feature flag has another value.host procfs ...,host sysfs ..., orhost root filesystem ...means host metrics are enabled without all required read-only mounts.ALLOY_VALIDATOR_MASTER_KEY must be blank or ...means the optional value is not a structurally valid public validator master key. The rejected value is not printed.ALLOY_NODE is required.means an environment variable is missing.monitoring push password ...means the secret file is missing, unreadable, empty, or has a final newline.still contains a placeholder valuemeans a placeholder was not replaced.Cannot access ...means the path is missing, is not a file, or cannot be reached. Check the mount and parent directory permissions.Cannot read ...means the file exists but cannot be read. Check file permissions.[insight] address must be ...meansxrpld.cfgdoes not match the host loopback StatsD address passed to the container.alloy validateerrors mean the Alloy config did not pass validation.
Rootless Podman: If your host user can read logs through the node’s group but the container cannot, add
--runtime /usr/bin/crun --group-add keep-groupstopodman run(requirescrun). This preserves existing group access. Keep log mounts read-only, do not make the logs public to bypass permissions.
Common post-start symptoms:
401push errors usually mean the username or password is wrong.403push errors usually mean the username is not mapped to a monitoring tenant.- No
xrpld_*metrics usually means live StatsD packets are not arriving, the prefix does not match whatxrpldemits, orxrpldhas not emitted the metric yet. - No
node_*metrics means host metrics are disabled, a required host mount is absent, or the host scrape has not completed yet. - Missing logs usually means the selected container paths do not point at the node’s active debug and perf files. Check
ALLOY_LOG_DEBUG,ALLOY_LOG_PERF, and the read-only directory mounts.
Stop Or Remove
Stop monitoring:
docker stop xrpl-monitoring-alloyStart it again:
docker start xrpl-monitoring-alloyRemove the container:
docker rm xrpl-monitoring-alloyTo recreate Alloy after changing its settings or password file, stop and remove the container with the commands above, then repeat your updated command from Run With Docker. Keep the alloy-data volume. If you use a new terminal, first run password_file="$(realpath /path/to/xrpl-push)" with the path to your existing password file.
Remove the Alloy data volume only if you want to discard Alloy runtime state:
docker volume rm alloy-dataIf you changed xrpld.cfg and want to go back to a previous StatsD collector, restore the previous [insight] address yourself and restart xrpld using your normal process.