Skip to content

Creating a Grafana Dashboard for NPM with GeoIP Data

I am going to set up the preconfigured npmGrafStats from https://github.com/smilebasti/npmGrafStats.

The docker-compose.yml file can be found here https://github.com/smilebasti/npmGrafStats/blob/main/docker-compose.yml.

I made some changes to match my current npm config. You'll want to follow along the wiki as well https://github.com/smilebasti/npmGrafStats/wiki.

docker-compose.yml
services:
  nginx_proxy_manager:
    image: "jc21/nginx-proxy-manager:latest"
    container_name: nginx_proxy_manager
    restart: unless-stopped
    network_mode: "host"
    ports:
      - "80:80"    # HTTP
      - "443:443"  # HTTPS
      - "81:81"    # Admin Panel
    volumes:
      - ./data/npm_data:/data
      - ./data/npm_letsencrypt:/etc/letsencrypt
      - ./data/npm_logs:/var/log/nginx  
    environment:
      DB_SQLITE_FILE: "/data/database.sqlite" # Using SQLite instead of MySQL for simplicity
      INITIAL_ADMIN_EMAIL: admin@example.com
      INITIAL_ADMIN_PASSWORD: changeme


  goaccess:
    image: justsky/goaccess-for-nginxproxymanager:latest
    container_name: goaccess
    restart: unless-stopped
    environment:
        - TZ=America/New_York
        #- SKIP_ARCHIVED_LOGS=False #optional   
        #- BASIC_AUTH=False #optional
        #- BASIC_AUTH_USERNAME=user #optional
        #- BASIC_AUTH_PASSWORD=pass #optional                
    ports:
        - '7880:7880'
    volumes:
        #- ./data/npm_data/logs:/opt/log
        - ./data/npm_data/logs:/opt/log

  npmgraf:
    image: smilebasti/npmgrafstats:latest # change to ghcr.io/smilebasti/npmgrafstats if you prefer Github Container Registry
    restart: unless-stopped
    environment:
      REDIRECTION_LOGS: 'TRUE' # TRUE or FALSE or ONLY
      INTERNAL_LOGS: 'TRUE' # see Github wiki for more information
      MONITORING_LOGS: 'TRUE' # see Github wiki for more information
      INFLUX_HOST: '192.168.4.173:8086' # use host IP
      INFLUX_BUCKET: 'npmgrafstats'
      INFLUX_ORG: 'npmgrafstats'
      INFLUX_TOKEN: '<create-token-in-UI>' # insert after first run and manual token creation
    volumes:
      - ./data/npm_data/logs:/logs
      - ./geolite:/geolite
      - ./monitoringips.txt:/monitoringips.txt # optional only mount if preexists and a wanted feature
    depends_on:
      - geoipupdate
      - nginx_proxy_manager

  influxdb:
    image: influxdb:2.7-alpine
    restart: unless-stopped
    environment:
      DOCKER_INFLUXDB_INIT_MODE: 'setup'
      DOCKER_INFLUXDB_INIT_USERNAME: 'thomas'
      DOCKER_INFLUXDB_INIT_PASSWORD: 'thomaswildetech' # atleast 8 characters
      DOCKER_INFLUXDB_INIT_ORG: 'npmgrafstats'
      DOCKER_INFLUXDB_INIT_BUCKET: 'npmgrafstats'
    volumes:
      # Mount for influxdb data directory and configuration
      - ./influxdbv2:/var/lib/influxdb2
    ports:
      - '8086:8086'

  geoipupdate:
    image: maxmindinc/geoipupdate
    restart: unless-stopped
    environment:
      GEOIPUPDATE_ACCOUNT_ID: '<get from web interface>'
      GEOIPUPDATE_LICENSE_KEY: '<get from web interface>'
      GEOIPUPDATE_EDITION_IDS: 'GeoLite2-City  GeoLite2-ASN'  #GeoLite2-ASN is optional
      GEOIPUPDATE_FREQUENCY: 24
    volumes:
      - ./geolite:/usr/share/GeoIP

  grafana:
    image: grafana/grafana-oss
    restart: unless-stopped
    ports:
      - '3000:3000'
    volumes:
      - ./grafana-storage:/var/lib/grafana

Set up MaxMind Account

MaxMind is used to fetch a geo-IP database. It is free to create an account at https://www.maxmind.com. After you create an account you can go to Account -> Manage License Keys and create a key. This will then show you your Account ID and License key that you can use in the docker compose file for geoipupdate.

Get API keys from InfluxDB

Go ahead and run the docker-compose file. Now log into InfluxDB with the credentials you added in docker compose at http://localhost:8086. On the menu on the left, click the up arrow, then click API Tokens. You should now see a button to Generate API Token on the right. Either create two tokens, one with read, one with write, or just create one token with read and write.

You can now put the token with write privileges into npmgraf in the docker compose file (the INFLUX_TOKEN parameter).

Go ahead and restart the docker compose stack.

Set Up InfluxDB as a data source in Grafana.

Make sure you run

sudo chown 472:472 grafana-storage

to set the permission on the bind mound. Grafana will not work unless you do this.

Let's now adda data source. In the menu on the left, go to Connections -> Data sources. Hi the Add new data source button.

Give it a name, i.e. influxdb. Set the query language to Flux. Set the URL to the IP and port of InfluxDB, i.e. http://192.168.4.173:8086.

Set the Organization and Default Bucket to the respective values in docker compose for DOCKER_INFLUXDB_INIT_ORG and DOCKER_INFLUXDB_INIT_BUCKET. The value in my compose file is npmgrafstats. Add the Token that we created in InfluxDB that has read access. Hit save and test.

Ok, now you can create a dashboard. Go to Dashboards -> New -> New dashboard. We can use the pre-configured dashboard with ID 18826.

You can easily resize the panels and move them around. If you want geo location with the IP infromation in the tables, make sure to add thiese fields to the group within the query: group(columns: ["IP", "Name", "State", "City"])

Comments