Docker Deployment
nsr_exporter ships as a minimal Alpine-based Docker image (non-root USER 10001).
Use the compose stacks for a complete observability environment, or pull the image
standalone for integration into an existing stack.
Image locations
| Use case | Image |
|---|---|
| Local build (dev) | Built by docker compose up --build from ./Dockerfile |
| Published release | ghcr.io/fjacquet/nsr_exporter:<tag> |
Quick start — build from source
# Clone and copy quickstart credentials
git clone https://github.com/fjacquet/nsr_exporter.git
cd nsr_exporter
cp .env.example .env
# Edit .env: set NSR1_USERNAME, NSR1_PASSWORD, and optionally GF_ADMIN_PASSWORD.
docker compose up --build
Open Grafana at http://localhost:3000 (default admin/admin). Prometheus UI is at http://localhost:9090. The exporter metrics endpoint is at http://localhost:9447/metrics.
Quick start — published image (no build)
cp .env.example .env
# Edit .env with real credentials, then:
NSR1_PASSWORD='your-password' docker compose -f docker-compose.ghcr.yml up -d
Pin a specific release:
NSR_TAG=0.2.0 NSR1_PASSWORD='...' docker compose -f docker-compose.ghcr.yml up -d
Configuration
The exporter reads /etc/nsr_exporter/config.yaml inside the container. The compose
stacks mount ./config.demo.yaml there (so the exporter scrapes the bundled mock);
mount your own ./config.yaml for a real target. See config.yaml for the full schema; key fields:
| Field | Default | Purpose |
|---|---|---|
server.port |
9447 |
/metrics listen port |
collection.interval |
5m |
Background poll frequency |
collection.timeout |
60s |
Per-system API deadline |
collection.backupWindow |
24h |
Bound for /backups queries (ADR-0010) |
systems[].insecureSkipVerify |
false |
Skip TLS verification (dev only) |
${ENV_VAR} references in host, username, and password expand at load time;
an unset variable causes a fail-fast startup error. Use passwordFile to supply
secrets out-of-band without embedding them in the compose environment.
OTLP push export (optional)
The compose stacks include an otel-collector service. The collector exposes two ports:
| Port | Protocol | Purpose |
|---|---|---|
4317 |
gRPC | Receives OTLP metrics pushed by the exporter |
8889 |
HTTP | Prometheus scrape endpoint — the collector re-exposes pushed metrics here |
config.demo.yaml ships with the OTLP endpoint pre-configured so the bundled
docker compose up stack automatically pushes metrics to the collector.
To enable OTLP in your own config.yaml:
opentelemetry:
endpoint: "otel-collector:4317"
insecure: true # use false and configure TLS for production collectors
pushInterval: "30s" # how often to push; default is 30s
Or set the standard OTEL env var (takes precedence over the config file):
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
Once running, verify the collector is receiving metrics:
curl -s http://localhost:8889/metrics | grep '^nsr_'
The nsr_otlp_export_errors_total counter on the exporter's own /metrics increments
whenever a push fails — use it to alert on OTLP outages:
increase(nsr_otlp_export_errors_total[5m]) > 0
Health check
curl -s http://localhost:9447/metrics | grep '^nsr_up'
A 1 means the NetWorker system responded in the last collection cycle.
Production notes
- Change
GF_ADMIN_PASSWORDbefore exposing Grafana externally. - Set
GF_SERVER_ROOT_URLin.envso share links resolve correctly. - Pin
NSR_TAGto a release version instead of:latestfor reproducible deploys. - Run behind a TLS-terminating reverse proxy (nginx, Caddy, Traefik) for external access.
- Never commit
.envorconfig.yamlcontaining real credentials to version control.