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.cfg wherever this guide says xrpld.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.log and perf.log are 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 curl for the setup commands.
  • A readable xrpld.cfg.
  • Optionally, the validator’s public 52-character nH master key for correlation with public XRPL network statistics. This is not an account address, signing key, private key, or seed.
  • StatsD metrics, debug.log, and perf.log available from xrpld.
  • Outbound HTTPS access to push.monitoring.xrplf.org and 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/health

curl 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.

WarningBefore you start

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.

NoteLog paths are examples

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:latest

Run 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:latest

For 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-push

From that directory, check the file and start Alloy:

docker compose config --quiet
docker compose pull
docker compose up -d

View 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.alloy

For 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-push

From that directory, check the file and start Alloy:

docker compose config --quiet
docker compose pull
docker compose up -d

View 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.

NoteNetwork metrics

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.1 binds the port only on host localhost, so it is not opened to the network.
  • <host-port> is the UDP port from xrpld.cfg, for example 9125 or 19125.
  • 9125/udp is the container port and protocol. Keep this as 9125/udp because the image listens on 0.0.0.0:9125 inside 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:

WarningNode restart required

Adding the port requires recreating the xrpld container. Plan for a node interruption and keep its existing configuration, data mounts, and other settings.

  1. Add -p 127.0.0.1:12345:12345 to the xrpld container’s Docker command and recreate that container.
  2. In the Alloy command, change --server.http.listen-addr=127.0.0.1:12345 to --server.http.listen-addr=0.0.0.0:12345, then recreate Alloy.
  3. Open http://127.0.0.1:12345 on 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:latest

That 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.alloy

For 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_ENABLED is exactly true or false.
  • 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 nH structure, 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.cfg is mounted and readable.
  • The selected debug and perf log files are mounted and readable.
  • There is one [insight] section, with no repeated server, address, or prefix keys. 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] server is statsd.
  • [insight] address matches the configured StatsD destination.
  • [insight] prefix exists.
  • The generated StatsD mapping can be read.
  • alloy validate /etc/alloy/config.alloy passes.

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 Health
  • XRPL StatsD Metrics
  • XRPL 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, and module.

If data does not appear:

  • Check Alloy:

    docker ps -a --filter name=xrpl-monitoring-alloy
  • Check Alloy logs:

    docker logs --tail 100 xrpl-monitoring-alloy
  • Confirm 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-alloy

Check startup errors:

docker logs xrpl-monitoring-alloy

Common entrypoint errors:

  • ALLOY_HOST_METRICS_ENABLED must be true or false means the feature flag has another value.
  • host procfs ..., host sysfs ..., or host 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 value means 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 ... means xrpld.cfg does not match the host loopback StatsD address passed to the container.
  • alloy validate errors 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-groups to podman run (requires crun). This preserves existing group access. Keep log mounts read-only, do not make the logs public to bypass permissions.

Common post-start symptoms:

  • 401 push errors usually mean the username or password is wrong.
  • 403 push 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 what xrpld emits, or xrpld has 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-alloy

Start it again:

docker start xrpl-monitoring-alloy

Remove the container:

docker rm xrpl-monitoring-alloy

To 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-data

If 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.

Back to top