Selemon Exporter is a Docker-based system monitoring solution that collects low-level hardware and system metrics and exposes them in Prometheus format.
The system is built using a two-container architecture:
- node_exporter — runs the official Prometheus Node Exporter image
- selemon-collector — runs custom collectors that gather additional system and hardware metrics
The exporter is split into two containers with clearly separated responsibilities:
- Based on the official
prom/node-exporterimage - Runs under the
nobodyuser (UID/GID 65534) - Exposes metrics via HTTP in Prometheus format
- Does not require elevated Linux capabilities
- Reads metrics produced by custom collectors via shared volumes
- Based on the Selemon Exporter custom image
- Runs custom collectors:
- dmesg log collector
- SMART disk health monitoring
- HDD / SSD / NVMe support
- Requires elevated privileges to access hardware and kernel interfaces
- Writes collected metrics into shared volumes, which are then read by node_exporter
The two containers exchange data using Docker volumes:
selemon_textfiles— metrics for the Node Exporter textfile collectorselemon_sslfiles— shared Node Exporter SSL / web configuration
Use the docker-compose.yml file already included in this repository as a reference or starting point.
volumes:
selemon_textfiles:
selemon_sslfiles:
services:
node-exporter:
image: prom/node-exporter:v1.10.2
container_name: selemon-node-exporter
restart: unless-stopped
#Settings
network_mode: host
pid: host
# nobody user
user: "65534:65534"
# Resources
deploy:
resources:
limits:
memory: 50m
cpus: '1.0'
volumes:
- selemon_textfiles:/var/lib/node_exporter/textfile_collector:rw
- selemon_sslfiles:/etc/node_exporter:rw
- "/:/host:ro,rslave"
- "/proc:/host/proc:ro"
- "/sys:/host/sys:ro"
security_opt:
- "no-new-privileges:true"
command:
- "--path.rootfs=/host"
- "--path.sysfs=/host/sys"
- "--path.procfs=/host/proc"
- "--path.udev.data=/host/run/udev/data"
- "--collector.filesystem.mount-points-exclude='^/(sys|proc|dev|host|etc|var/lib/docker|run|var/lib/lxcfs|var/lib/kubelet)($|/)'"
- "--web.disable-exporter-metrics"
- "--web.max-requests=40"
- "--collector.cpufreq"
- "--collector.ethtool"
- "--web.config.file=/etc/node_exporter/web-config.yml"
# Specify your custom port here, if needed
- "--web.listen-address=:9100"
- "--collector.textfile.directory=/var/lib/node_exporter/textfile_collector"
entrypoint: >
/bin/sh -c "
exec /bin/node_exporter \"\$@\""
depends_on:
- selemon-collector
selemon-collector:
image: ghcr.io/selectel/selemon-exporter:latest
container_name: selemon-collector
restart: unless-stopped
# Resources
deploy:
resources:
limits:
memory: 100m
cpus: '1.0'
# Settings
network_mode: "host"
pid: "host"
volumes:
- selemon_textfiles:/var/lib/node_exporter/textfile_collector:rw
- selemon_sslfiles:/etc/node_exporter:rw
- "/dev:/dev:ro"
- "/sys:/sys:ro"
# Privilegies
cap_add:
- CAP_SYS_RAWIO
- CAP_SYS_ADMIN
- CAP_SYSLOG
security_opt:
- "no-new-privileges:true"
# Device access
device_cgroup_rules:
- "b 259:* r" # NVMe devices
- "b 8:* r" # SCSI/SATA devices
- "b 3:* r" # IDE devicesStart the exporter:
docker-compose up -dThe container requires specific Linux capabilities to access hardware metrics:
| Capability | Description |
|---|---|
| CAP_SYS_RAWIO | Raw I/O operations to read SMART data for ATA/SATA/IDE devices |
| CAP_SYSLOG | Read system logs (e.g., dmesg) |
| CAP_SYS_ADMIN | NVMe monitoring via NVME_IOCTL_ADMIN_CMD ioctl calls |
Note:
CAP_SYS_ADMINis required for proper NVMe disk monitoring and cannot be replaced with more fine-grained permissions.
The node_exporter container itself runs without elevated privileges.
The image includes:
- Node Exporter (with SSL support)
- Custom collectors:
dmesglog collector- SMART disk health monitoring
- Support for HDD, SSD, and NVMe devices
- Host filesystem is mounted read-only (
/,/dev) - Privilege escalation is disabled (
no-new-privileges:true) - Resource limits are enforced via Docker
- Device access is restricted to storage controller block devices
If you prefer to expose node_exporter metrics via NGINX with SSL termination, you can run Node Exporter without its built-in HTTPS support and proxy it through NGINX.
- NGINX installed on the host
- Docker and Docker Compose
- Free TCP port on the host (example below uses
4431)
Use the docker-compose.yml example from above, but remove the following argument from the node-exporter service:
--web.config.file=/etc/node_exporter/web-config.yml
This disables Node Exporter’s built-in HTTPS support so that SSL can be handled by NGINX.
docker compose up -d
The SSL certificates are located inside the collector container. Copy them to the NGINX directory on the host:
docker cp selemon-collector:/etc/node_exporter/ssl /etc/nginx/
As a result, the certificates will be available at:
/etc/nginx/ssl/
Create a new configuration file:
/etc/nginx/conf.d/node_exporter.conf
With the following content:
server { listen 4431 ssl;
ssl_certificate /etc/nginx/ssl/node_exporter.crt;
ssl_certificate_key /etc/nginx/ssl/node_exporter.key;
location / {
proxy_pass http://127.0.0.1:9100;
}
}
If you plan to use a different port, update the listen directive accordingly.
nginx -t
ss -tulpn | grep :4431
nginx -s reload
After this, Node Exporter metrics will be available via HTTPS:
https://:4431/metrics