Grafana: Difference between revisions

From NixOS Wiki
imported>PaulGrandperrin
m fix proxyPath url, a slash was missing at the end causing redirection loop
Dander (talk | contribs)
m add recommended defaults (non-default for BC reasons)
 
(14 intermediate revisions by 9 users not shown)
Line 7: Line 7:
Grafana is available as NixOS module, it can be enabled using the following config:
Grafana is available as NixOS module, it can be enabled using the following config:


<syntaxhighlight lang=nix>
<syntaxhighlight lang="nix">
services.grafana = {
services.grafana = {
      enable = true;
  enable = true;
      # Listening address and TCP port
  settings = {
       addr = "127.0.0.1";
    server = {
       port = 3000;
       http_addr = "127.0.0.1";
       # Grafana needs to know on which domain and URL it's running:
       http_port = 3000;
       domain = "your.domain";
      enforce_domain = true;
       rootUrl = "https://your.domain/grafana/"; # Not needed if it is `https://your.domain/`
      enable_gzip = true;
      domain = "grafana.your.domain";
 
       # Alternatively, if you want to server Grafana from a subpath:
       # domain = "your.domain";
       # root_url = "https://your.domain/grafana/";
      # serve_from_sub_path = true;
    };
 
    # Prevents Grafana from phoning home   
    #analytics.reporting_enabled = false;
  };
};
};
</syntaxhighlight>
</syntaxhighlight>


This will make Grafana available only at localhost. On a server, it might be used through SSH tunnel or made publicly available using nginx with TLS. For example the follwing [[Nginx]] configuration can be used:
[https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/ Read Grafana's documentation for the options in <code>settings</code>.]   
 
== Usage ==
Grafana can be used through tunnels, like a SSH tunnel, or a VPN tunnel like Wireguard or Headscale. This way, Grafana can be completely shielded from the outside.
 
Another way is to make it publicly available, usually behind a reverse proxy.
 
==== Nginx ====
Here is how to setup [[Nginx]] such that it proxies <code>your.domain/grafana</code> to your Grafana instance:
<syntaxhighlight lang=nix>
<syntaxhighlight lang=nix>
  services.nginx.virtualHosts."your.domain" = {
services.nginx.virtualHosts."your.domain" = {
    addSSL = true;
  addSSL = true;
    enableACME = true;
  enableACME = true;
    locations."/grafana/" = {
  locations."/grafana/" = {
        proxyPass = "http://127.0.0.1:${toString config.services.grafana.port}/";
      proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
        proxyWebsockets = true;
      proxyWebsockets = true;
    };
      recommendedProxySettings = true;
   };
   };
};
</syntaxhighlight>
</syntaxhighlight>


== Usage ==
==== Traefik ====
[[Traefik]] is another common reverse proxy, for which the configuration relevant to Grafana would like this:<syntaxhighlight lang="nix" line="1">
services.traefik = {
    # ...
    dynamicConfigOptions = {
      http.routers."your.domain" = {
          rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
          service = "grafana";
      }
      http.services."grafana" = {
          loadBalancer.servers = [ {
              url = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
          } ]
      };
    # ...
};
</syntaxhighlight>Alternatively, to use Grafana on <code>grafana.your.domain</code> instead of <code>your.domain/grafana</code>, you could change line 5 above to:<syntaxhighlight lang="diff">
-rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
+rule = "Host(`grafana.your.domain`)";
</syntaxhighlight>
 
== Configuration ==
 
Everything else (data sources, users, dashboards, ...) can be configured either in the Web UI, or as code.
 
=== Via Web UI ===


Log into the Grafana web application (using default user: admin, password: admin). Everything else (data sources, users, dashboards, ...) is configured in the Web UI. Refer to the official documentation on how to do it:
Log into the Grafana web application (using default user: admin, password: admin). Refer to the official documentation on how to do it:


* [https://grafana.com/docs/grafana/latest/datasources/add-a-data-source/ Add a data source]
* [https://grafana.com/docs/grafana/latest/datasources/add-a-data-source/ Add a data source]
* [https://grafana.com/docs/grafana/latest/administration/manage-users-and-permissions/manage-server-users/add-user/ Add a user]
* [https://grafana.com/docs/grafana/latest/administration/manage-users-and-permissions/manage-server-users/add-user/ Add a user]
* [https://grafana.com/docs/grafana/latest/dashboards/dashboard-create/ Create dashboard]
* [https://grafana.com/docs/grafana/latest/dashboards/dashboard-create/ Create dashboard]
=== Declarative configuration ===
<syntaxhighlight lang="nix">
services.grafana = {
  declarativePlugins = with pkgs.grafanaPlugins; [ ... ];
  provision = {
    enable = true;
    dashboards.settings.providers = [{
      name = "my dashboards";
      options.path = "/etc/grafana-dashboards";
    }];
    datasources.settings.datasources = [
      # "Built-in" datasources can be provisioned - c.f. https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
      {
        name = "Prometheus";
        type = "prometheus";
        url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
      }
      # Some plugins also can - c.f. https://grafana.com/docs/plugins/yesoreyeram-infinity-datasource/latest/setup/provisioning/
      {
        name = "Infinity";
        type = "yesoreyeram-infinity-datasource";
      }
      # But not all - c.f. https://github.com/fr-ser/grafana-sqlite-datasource/issues/141
    ];
    # Note: removing attributes from the above `datasources.settings.datasources` is not enough for them to be deleted on `grafana`;
    # One needs to use the following option:
    # datasources.settings.deleteDatasources = [ { name = "foo"; orgId = 1; } { name = "bar"; orgId = 1; } ];
  };
};
environment.etc = [{
  source = ./. + "/grafana-dashboards/some-dashboard.json";
  group = "grafana";
  user = "grafana";
}];
</syntaxhighlight>


== External Links ==
== External Links ==
Line 44: Line 131:
* [https://grafana.com/ grafana.com]
* [https://grafana.com/ grafana.com]
* [https://xeiaso.net/blog/prometheus-grafana-loki-nixos-2020-11-20 How to Setup Prometheus, Grafana and Loki on NixOS]
* [https://xeiaso.net/blog/prometheus-grafana-loki-nixos-2020-11-20 How to Setup Prometheus, Grafana and Loki on NixOS]
[[Category:Server]]
[[Category:Web Applications]]

Latest revision as of 12:10, 23 October 2024

Grafana is an open-source, general purpose dashboarding tool, which runs as a web application. It can be used to create a variety of time-series graphs and also for displaying logs. It supports Prometheus, graphite, InfluxDB, opentsdb, Grafana Loki, PostgreSQL and many other data sources.

See Grafana options

Installation

Grafana is available as NixOS module, it can be enabled using the following config:

services.grafana = {
  enable = true;
  settings = {
    server = {
      http_addr = "127.0.0.1";
      http_port = 3000;
      enforce_domain = true;
      enable_gzip = true;
      domain = "grafana.your.domain";

      # Alternatively, if you want to server Grafana from a subpath:
      # domain = "your.domain";
      # root_url = "https://your.domain/grafana/";
      # serve_from_sub_path = true;
    };

    # Prevents Grafana from phoning home     
    #analytics.reporting_enabled = false;
  };
};

Read Grafana's documentation for the options in settings.

Usage

Grafana can be used through tunnels, like a SSH tunnel, or a VPN tunnel like Wireguard or Headscale. This way, Grafana can be completely shielded from the outside.

Another way is to make it publicly available, usually behind a reverse proxy.

Nginx

Here is how to setup Nginx such that it proxies your.domain/grafana to your Grafana instance:

services.nginx.virtualHosts."your.domain" = {
  addSSL = true;
  enableACME = true;
  locations."/grafana/" = {
      proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
      proxyWebsockets = true;
      recommendedProxySettings = true;
  };
};

Traefik

Traefik is another common reverse proxy, for which the configuration relevant to Grafana would like this:

services.traefik = {
     # ...
     dynamicConfigOptions = {
       http.routers."your.domain" = {
           rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
           service = "grafana";
       }
       http.services."grafana" = {
           loadBalancer.servers = [ { 
               url = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}";
           } ] 
       };
     # ...
};

Alternatively, to use Grafana on grafana.your.domain instead of your.domain/grafana, you could change line 5 above to:

-rule = "Host(`your.domain`) && PathPrefix(`/grafana`)";
+rule = "Host(`grafana.your.domain`)";

Configuration

Everything else (data sources, users, dashboards, ...) can be configured either in the Web UI, or as code.

Via Web UI

Log into the Grafana web application (using default user: admin, password: admin). Refer to the official documentation on how to do it:

Declarative configuration

services.grafana = {
  declarativePlugins = with pkgs.grafanaPlugins; [ ... ];

  provision = {
    enable = true;

    dashboards.settings.providers = [{
      name = "my dashboards";
      options.path = "/etc/grafana-dashboards";
    }];

    datasources.settings.datasources = [
      # "Built-in" datasources can be provisioned - c.f. https://grafana.com/docs/grafana/latest/administration/provisioning/#data-sources
      {
        name = "Prometheus";
        type = "prometheus";
        url = "http://${config.services.prometheus.listenAddress}:${toString config.services.prometheus.port}";
      }
      # Some plugins also can - c.f. https://grafana.com/docs/plugins/yesoreyeram-infinity-datasource/latest/setup/provisioning/
      {
        name = "Infinity";
        type = "yesoreyeram-infinity-datasource";
      }
      # But not all - c.f. https://github.com/fr-ser/grafana-sqlite-datasource/issues/141
    ];

    # Note: removing attributes from the above `datasources.settings.datasources` is not enough for them to be deleted on `grafana`;
    # One needs to use the following option:
    # datasources.settings.deleteDatasources = [ { name = "foo"; orgId = 1; } { name = "bar"; orgId = 1; } ];
  };
};

environment.etc = [{
  source = ./. + "/grafana-dashboards/some-dashboard.json";
  group = "grafana";
  user = "grafana";
}];

External Links