mdawar / nats-dashboard

Web dashboard for monitoring NATS servers.
https://natsdashboard.com
MIT License
111 stars 14 forks source link
dashboard monitoring nats

NATS Web Dashboard

A web dashboard to display live NATS server monitoring metrics.

Live demo monitoring the demo NATS server at https://demo.nats.io:8222.

About

This is a static web app that was inspired by nats-top, it fetches and displays the monitoring stats of a NATS server but in the browser instead of the CLI.

Since this is a static web app, it can be deployed anywhere and can also run locally on your machine.

This is also a PWA (Progressive Web App) so it's installable and usable offline, but of course you need access to the NATS server, for example you can monitor a local NATS server while being offline.

There's no backend involved, the requests are made directly from the browser, so you can monitor a local NATS server (http://localhost:8222) even when the app is not running locally.

There's no data retention, so no historical stats can be displayed, you will only be able to view the live server stats, if you need this feature you should use a Prometheus exporter with Grafana and set an appropriate data retention policy.

Using the App

PWA

The app is deployed on Cloudflare Pages at:

https://natsdashboard.com

The app can be installed on your device for offline use (Desktop or mobile).

Docker Image

docker run --rm -it -p 8000:80 mdawar/nats-dashboard

The image uses Caddy server and exposes port 80.

In the example above we map the image port 80 to port 8000 on localhost.

Note: You can use a custom server configuration (Caddyfile) and mount it at /etc/caddy/Caddyfile.

Build Files

The build files are available on the releases page in a build.zip file.

You can serve the app locally using any HTTP server.

Serving using Python's HTTP server:

cd ./dist && python -m http.server

Serving using Caddy server:

docker run --rm -it -p 8000:80 -v ./dist:/usr/share/caddy caddy

Configuration

The app uses a runtime JSON config file served at /config.json.

You can run the Docker image and mount the config.json file at /srv/config.json.

Configuration Options

Name Type Description
server Server Default NATS server to monitor.
servers Server[] List of NATS servers to suggest in the app.
hideServerInput boolean Hide the server URL input.

The Server type definition:

interface Server {
  /** Server display name (Optional). */
  name?: string;
  /** Server URL. */
  url: string;
}

Example Config File

{
  "server": {
    "name": "My NATS Server",
    "url": "http://nats:8222"
  },
  "servers": [
    {
      "name": "localhost",
      "url": "http://localhost:8222"
    },
    {
      "name": "demo.nats.io",
      "url": "https://demo.nats.io:8222"
    }
  ],
  "hideServerInput": false
}

Single Server Config Example

This configuration is suitable for monitoring a single NATS server.

{
  "server": {
    "name": "My NATS Server",
    "url": "http://nats:8222"
  },
  "hideServerInput": true
}

Internal NATS Servers

The app can monitor NATS servers accessible to the user only, so any NATS servers accessible on your network can be monitored.

To monitor NATS servers on a private network, you can run your own instance of the app using the Docker image and configure a reverse proxy to the NATS monitoring server.

Example Docker compose configuration:

services:
  # Internal NATS server.
  server:
    image: nats:2.10
    command: -n internal-server -m 8222 -js

  # NATS dashboard instance running on the same private network.
  dashboard:
    image: mdawar/nats-dashboard
    environment:
      # The NATS monitoring server will be proxied on /proxy/* on the frontend.
      # See: config/Caddyfile for the reverse proxy configuration.
      REVERSE_PROXY_UPSTREAM: 'server:8222'
    volumes:
      # Optional config file.
      - ./config.json:/srv/config.json
    ports:
      - target: 80
        published: 8000
        protocol: tcp

Now when using the app you can monitor this private NATS server using the path /proxy/ on the same domain.

This is an example config.json file to set the default URL and disable the URL input:

{
  "server": {
    "name": "Internal Server",
    "url": "https://natsdashboard.example.com/proxy/"
  },
  "hideServerInput": true
}

Replace the server url with the actual NATS dashboard URL.

Warning: Your NATS monitoring server will be exposed to the public, you will have to make sure that you secure your NATS dashboard instance.

Limitations

Mixed Content

An HTTPS page that includes content fetched using cleartext HTTP is called a mixed content page.

If the app is served over HTTPS you won't be able to monitor NATS servers served over HTTP (Most browsers block mixed content).

This is the case when using the app hosted on https://natsdashboard.com.

Note: This does not affect NATS servers running on localhost.

Solutions:

  1. Serve the NATS monitoring server over HTTPS.
  2. Reverse proxy the monitoring server on localhost (Browsers allow locally delivered mixed content).

For example:

# Reverse proxy a NATS monitoring server on localhost:8222.
# Now http://localhost:8222 can be used to monitor the server without it being blocked by the browser.
docker run --rm -it --net host caddy caddy reverse-proxy --from http://localhost:8222 --to http://example.com:8222

Development

Requirements

Install the required packages:

npm i

Run the web app in dev mode

npm start

Run a local NATS server

# Start a local NATS server using Docker compose
just server
# Or
make server
# Remove containers and volumes
just clean
# Or
make clean

Run the tests

There are a few tests for a couple of functions for now, more tests will be added later.

npm test
# Run the tests and watch for changes
npm run test:watch

Build the App

Build the Web App

# Build a static web app to ./dist
npm run build

To build a sitemap and to have proper URL meta tags, the SITE_DOMAIN environment variable must be set.

# The SITE_DOMAIN env variable sets the Astro.site config.
SITE_DOMAIN=https://example.com npm run build

Build Docker Image

Build using Docker compose:

just build
# Or
make build
# Or
docker compose build

The environment variable SITE_DOMAIN will be passed as a build argument if set.

Or using the Docker CLI:

docker build -t nats-dashboard .
# The site domain can be passed as a build arg.
docker build -t nats-dashboard --build-arg SITE_DOMAIN=https://example.com .

Build and Preview

Build the Docker image and run the server on http://localhost:8000 with a NATS server running on port 4222.

This is useful for testing SSG and the PWA config (eg: service worker).

just preview
# Or
make preview
# Or
docker compose build && docker compose up

The environment variable SITE_DOMAIN will be passed as a build argument if set.

Cleanup:

# Remove containers and volumes
just clean
# Or
make clean
# Or
docker compose down -v

Data Fetching

By default the data is fetched using the Fetch API since NATS server started supporting CORS in v2.9.22.

For NATS servers < v2.9.22 there's an option to use JSONP requests that fetch the data by injecting a <script> tag that executes and calls a JavaScript function that receives the data.

This option must be explicitly enabled in the app settings.

Service Worker

The service worker is generated after the site is built, it's available at src/sw.ts, it's built by vite using the script scripts/build-sw.mjs and then the Workbox precache manifest is injected by the scripts/workbox.mjs script.

The service worker is registered only in production mode by the script src/sw-register.ts that's imported by the base layout at src/layouts/Base.astro.

To test locally, use just preview to build the Docker container and run a Caddy server similar to a production environment.

Generate the Service Worker

# This is automatically run after the build script.
npm run generateSW

GitHub Actions Requirements

Repository Variables

Variable Name Description
DOCKERHUB_USER Required to push the Docker image to Docker Hub.
SITE_DOMAIN Needed to generate a sitemap and the URL meta tags (Optional).

Repository Secrets

Secret Name Description
CLOUDFLARE_ACCOUNT_ID Required for uploading the assets to Cloudflare Pages.
CLOUDFLARE_ZONE_ID Required for purging the zone cache.
CLOUDFLARE_API_TOKEN Required for Clouflare Pages and for purging the zone cache.
DOCKERHUB_TOKEN Required to push the Docker image to Docker Hub.

Required Permissions

Alternatives

Credits