HugoTrentesaux

Run an indexer🔗

Some tasks are difficult to perform by interacting directly with the blockchain. For example getting the list of transactions emitted and received by an account. The indexer is a piece of software that makes these tasks way easier for the clients. We aim to have about 3-4 indexers for each country using Ğ1 to provide enough redundancy in case some of them fail.

schema

components of the indexer visible in the README

Table of contents

  1. Requirements
  2. Docker compose file
  3. Running
  4. Nginx config
    1. Hasura on port 8080
    2. Playground on port 3000

Requirements🔗

You need a Duniter archive node running on the same server as the indexer.

Docker compose file🔗

This is an example docker-compose.yml file:

# Duniter indexer

services:
  # postgres database
  postgres:
    image: postgres:12
    restart: always
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword

  # hasura
  graphql-engine:
    image: duniter/hasura-indexer:latest
    depends_on:
      - postgres
    restart: always
    ports:
      - 127.0.0.1:8080:8080 # <--- hasura console will listen on port 8080
    environment:
      # postgres database
      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      # enable the console served by server
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
      # dev mode
      HASURA_GRAPHQL_DEV_MODE: "false"
      # logging
      # HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup
      # admin password
      HASURA_GRAPHQL_ADMIN_SECRET: hasura_password # <--- you can customize the hasura password here
      # Name of role when the Authorization header is absent in JWT
      HASURA_GRAPHQL_UNAUTHORIZED_ROLE: public
      # telemetry
      HASURA_GRAPHQL_ENABLE_TELEMETRY: "false"

  # indexer (must have duniter in archive mode listening on ws://localhost:9944)
  indexer:
    image: duniter/duniter-indexer:latest
    environment:
      - POSTGRES_HOST=postgres
      - INDEXER_DUNITER_WS_ENDPOINT=ws://duniter-archive:9944 # <--- needs an archive node
      - INDEXER_DUNITER_WS_ENDPOINT_GRAPHIQL=wss://gdev.example.org/ws # <--- customize the ws endpoint the app will be using
      - INDEXER_HASURA_GRAPHQL_ENDPOINT_GRAPHIQL=https://hasura.gdev.example.org # <--- customize the public graphql endpoint
    restart: unless-stopped
    ports:
      - 127.0.0.1:3000:3000
    depends_on:
      # - duniter-archive # depends on archive node through network
      - postgres
      - graphql-engine
    volumes:
      - logs:/logs
      - resources:/resources
    # allows to connect to duniter node
    networks:
      - duniter

# define volumes
volumes:
  postgres-data:
  logs:
  resources:

# define duniter external network to allow connect to duniter archive node
networks:
  duniter:
    name: duniter_default # <--- you can tell here the name of the network where lies the duniter-archive node
    external: true

As you can see, there are multiple things to configure:

By splitting the indexer and the archive node, you will be able to keep the archive node running while updating the indexer and possibly re-indexing.

Running🔗

You can start the indexer with

# start the indexer
docker compose up -d
# follow the logs
docker compose logs -f

In the logs, you will see the following steps:

There might be some errors passing because the indexer is under development and has some bugs. Go to https://hasura.gdev.example.org/ and enter your password to see the GraphQL API explorer and the SQL Data.

Nginx config🔗

Here is an example of nginx reverse proxy config files (very basic configuration):

Hasura on port 8080🔗

# https redirection
server {
  listen 80 ;
  listen [::]:80 ;

  server_name hasura.gdev.example.org;

  return 301 https://$host$request_uri;
}

# https configuration
server {
  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_certificate /etc/letsencrypt/live/hasura.gdev.example.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/hasura.gdev.example.org/privkey.pem;

  server_name hasura.gdev.example.org;

  access_log /var/log/nginx/hasura.gdev.example.org_access.log;
  error_log /var/log/nginx/hasura.gdev.example.org_error.log;

  root /var/www/hasura.gdev.example.org;

  location / {
    add_header X-Robots-Tag "noindex";
    proxy_pass http://localhost:8080;
    proxy_redirect http://localhost:8080 https://hasura.gdev.example.org;
  }
}

Playground on port 3000🔗

# https redirection
server {
  listen 80 ;
  listen [::]:80 ;

  server_name indexer.gdev.example.org;

  return 301 https://$host$request_uri;
}

# https configuration
server {
  listen 443 ssl;
  listen [::]:443 ssl;

  ssl_certificate /etc/letsencrypt/live/indexer.gdev.example.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/indexer.gdev.example.org/privkey.pem;

  server_name indexer.gdev.example.org;

  access_log /var/log/nginx/indexer.gdev.example.org_access.log;
  error_log /var/log/nginx/indexer.gdev.example.org_error.log;

  root /var/www/indexer.gdev.example.org;

  location / {
    add_header X-Robots-Tag "noindex";
    proxy_pass http://localhost:3000;
    proxy_redirect http://localhost:3000 https://indexer.gdev.example.org;
  }
}

When you are happy with your config and want to share your endpoint, publish it on the forum!