{"id":50877689,"url":"https://github.com/dgshue/blackbox-ui","last_synced_at":"2026-06-15T11:32:42.871Z","repository":{"id":364144964,"uuid":"1266615179","full_name":"dgshue/blackbox-ui","owner":"dgshue","description":"Point-and-click web UI for configuring Prometheus Blackbox Exporter - sidecar container with live reload, automatic backups, and probe testing","archived":false,"fork":false,"pushed_at":"2026-06-11T19:44:20.000Z","size":95,"stargazers_count":0,"open_issues_count":9,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T21:16:02.593Z","etag":null,"topics":["blackbox-exporter","docker","monitoring","prometheus","sidecar","web-ui","yaml"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dgshue.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-11T19:39:37.000Z","updated_at":"2026-06-11T19:44:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dgshue/blackbox-ui","commit_stats":null,"previous_names":["dgshue/blackbox-ui"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dgshue/blackbox-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgshue%2Fblackbox-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgshue%2Fblackbox-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgshue%2Fblackbox-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgshue%2Fblackbox-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgshue","download_url":"https://codeload.github.com/dgshue/blackbox-ui/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgshue%2Fblackbox-ui/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34358781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-15T02:00:07.085Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blackbox-exporter","docker","monitoring","prometheus","sidecar","web-ui","yaml"],"created_at":"2026-06-15T11:32:41.109Z","updated_at":"2026-06-15T11:32:42.864Z","avatar_url":"https://github.com/dgshue.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# blackbox-ui\n\nA web UI sidecar for configuring the [Prometheus Blackbox Exporter](https://github.com/prometheus/blackbox_exporter).\n\nBuild probe modules with a point-and-click form builder or edit the raw YAML directly — blackbox-ui writes the config file the exporter reads, takes an automatic backup on every save, and live-reloads blackbox via its `/-/reload` endpoint. Then test any module against a real target without leaving the page.\n\n## Features\n\n- **Point-and-click module builder** for every blackbox prober: `http`, `tcp`, `dns`, `icmp`, `grpc`, and `unix` — every documented option of blackbox exporter v0.28.0, with inline help and defaults.\n- **Raw YAML editor** (CodeMirror) with live syntax checking, for hand-tuning or options the forms don't cover.\n- **Save \u0026 reload in one click** — writes the shared config file atomically and POSTs `/-/reload` to blackbox; reload errors from blackbox are surfaced verbatim.\n- **Automatic backups** before every save, with one-click restore (which also takes a backup, so restores are never destructive).\n- **Probe testing** — run any module against a target straight from the UI and see `probe_success`, duration, and the full debug log.\n- **Validation** — YAML syntax plus a structural check against the blackbox config schema (unknown options, wrong types, missing required fields).\n- **Safe by design** — unmodeled/hand-written YAML keys survive form edits; concurrent-edit detection prevents silently clobbering changes made outside the UI.\n\n## Quick start\n\n```yaml\n# docker-compose.yml\nservices:\n  blackbox:\n    image: prom/blackbox-exporter:v0.28.0\n    restart: unless-stopped\n    command:\n      - --config.file=/config/blackbox.yml\n    ports:\n      - \"9115:9115\"\n    cap_add:\n      - NET_RAW # ICMP probes\n    sysctls:\n      net.ipv4.ping_group_range: \"0 2147483647\"\n    volumes:\n      - blackbox-config:/config\n    depends_on:\n      blackbox-ui:\n        condition: service_healthy\n\n  blackbox-ui:\n    image: ghcr.io/dgshue/blackbox-ui:latest\n    restart: unless-stopped\n    environment:\n      CONFIG_PATH: /config/blackbox.yml\n      BLACKBOX_URL: http://blackbox:9115\n    ports:\n      - \"9116:8080\"\n    volumes:\n      - blackbox-config:/config\n\nvolumes:\n  blackbox-config:\n```\n\n```\ndocker compose up -d\n```\n\nOpen **http://localhost:9116** — blackbox-ui seeds a starter config (`http_2xx`, `tcp_connect`, `icmp`, …) on first run, which is why `blackbox` waits for the sidecar to be healthy before starting.\n\n## How it works\n\n```\n                 shared volume\n┌──────────────┐  /config/blackbox.yml  ┌────────────────────┐\n│  blackbox-ui │ ─────── writes ──────► │  blackbox exporter │\n│    :8080     │                        │       :9115        │\n│              │ ── POST /-/reload ───► │                    │\n└──────────────┘                        └────────────────────┘\n```\n\nblackbox-ui is a *sidecar*: it needs nothing more than (1) a volume shared with the exporter containing the config file and (2) HTTP access to the exporter for reloads, status, and probe tests. It works just as well alongside an existing blackbox deployment — mount your current config location and point `BLACKBOX_URL` at it.\n\n### Adding to an existing blackbox exporter\n\n```yaml\n  blackbox-ui:\n    image: ghcr.io/dgshue/blackbox-ui:latest\n    environment:\n      CONFIG_PATH: /config/blackbox.yml   # wherever your blackbox config lives\n      BLACKBOX_URL: http://blackbox:9115\n      SEED_DEFAULT_CONFIG: \"false\"        # don't create a file if yours is missing\n    volumes:\n      - /path/to/your/blackbox/config:/config\n    ports:\n      - \"9116:8080\"\n```\n\n## Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `PORT` | `8080` | HTTP port the UI listens on |\n| `CONFIG_PATH` | `/config/blackbox.yml` | Path of the blackbox config file to manage |\n| `BLACKBOX_URL` | `http://blackbox:9115` | Base URL of the blackbox exporter (reload/status/probe) |\n| `PUBLIC_BLACKBOX_URL` | – | Browser-reachable blackbox URL; adds an \"Open blackbox\" link |\n| `SEED_DEFAULT_CONFIG` | `true` | Write a starter config if `CONFIG_PATH` doesn't exist |\n| `BACKUP_DIR` | `\u003cconfig dir\u003e/.backups` | Where pre-save backups are stored |\n| `BACKUP_KEEP` | `20` | Number of backups to retain |\n| `BASIC_AUTH_USERNAME` / `BASIC_AUTH_PASSWORD` | – | Enable HTTP basic auth when both are set |\n| `READ_ONLY` | `false` | Disable all writes (view-only mode) |\n\n## HTTP API\n\nEverything the UI does is available as a small JSON API:\n\n| Method | Path | Description |\n|---|---|---|\n| `GET` | `/api/config` | Current file content + mtime |\n| `PUT` | `/api/config` | `{raw, reload?, baseMtime?, force?}` → validate, backup, write, reload |\n| `POST` | `/api/validate` | `{raw}` → syntax + structural validation results |\n| `POST` | `/api/reload` | Trigger a blackbox reload |\n| `GET` | `/api/backups` | List backups |\n| `POST` | `/api/backups/:name/restore` | Restore a backup (backs up current first) and reload |\n| `GET` | `/api/probe?module=\u0026target=` | Proxy a debug probe through blackbox |\n| `GET` | `/api/status` | App, config-file, and blackbox health/version status |\n| `GET` | `/api/schema` | The module schema driving the form builder |\n| `GET` | `/healthz` | Liveness (used by the container healthcheck) |\n\n## Scraping the probes with Prometheus\n\nblackbox-ui manages the *exporter's* config. Your Prometheus still scrapes blackbox as usual:\n\n```yaml\nscrape_configs:\n  - job_name: blackbox-http\n    metrics_path: /probe\n    params:\n      module: [http_2xx]   # any module you built in the UI\n    static_configs:\n      - targets: [\"https://example.com\", \"https://grafana.com\"]\n    relabel_configs:\n      - source_labels: [__address__]\n        target_label: __param_target\n      - source_labels: [__param_target]\n        target_label: instance\n      - target_label: __address__\n        replacement: blackbox:9115\n```\n\n## Security notes\n\n- The UI has **no authentication by default** — it is meant for trusted networks. Set `BASIC_AUTH_USERNAME`/`BASIC_AUTH_PASSWORD`, or put it behind your reverse proxy / SSO (Traefik, Authelia, etc.). `READ_ONLY=true` gives you a safe dashboard-only deployment.\n- Secrets typed into module forms (passwords, bearer tokens) are stored in the blackbox config file, exactly as if you had written the YAML by hand. Prefer `*_file` variants where possible.\n- The container runs as root by default so it can write config volumes that other images initialized (see below).\n\n### Permissions\n\nThe blackbox exporter image runs as `nobody` and only needs to *read* the config; blackbox-ui needs to *write* it. With a named volume this works out of the box (files are written world-readable, `0644`). If you bind-mount a host directory and want blackbox-ui to run unprivileged, align ownership yourself and run with `user: \"\u003cuid\u003e:\u003cgid\u003e\"`.\n\n## Development\n\n```bash\nnpm install\nCONFIG_PATH=./tmp/blackbox.yml BLACKBOX_URL=http://localhost:9115 npm run dev\n# UI on http://localhost:8080\nnpm test\n```\n\nNo build step — the frontend is plain HTML/CSS/JS served by Express; CodeMirror and js-yaml are served from `node_modules`.\n\n## Versioning \u0026 releases\n\nReleases follow [semver](https://semver.org) (`MAJOR.MINOR.PATCH`). Pushing a tag like `v0.1.0` builds and publishes multi-arch images (amd64/arm64) to GHCR:\n\n- `ghcr.io/dgshue/blackbox-ui:0.1.0` — exact version\n- `ghcr.io/dgshue/blackbox-ui:0.1` — latest patch of a minor\n- `ghcr.io/dgshue/blackbox-ui:latest` — latest release\n\nSee [CHANGELOG.md](CHANGELOG.md).\n\n## License\n\n[Apache-2.0](LICENSE) — same as the Prometheus ecosystem. Not affiliated with the Prometheus project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgshue%2Fblackbox-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgshue%2Fblackbox-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgshue%2Fblackbox-ui/lists"}