main
1{lib, ...}: {
2 den.aspects.services.grafana = {
3 settings.host = {
4 domain = lib.mkOption {
5 type = lib.types.str;
6 };
7 address = lib.mkOption {
8 type = lib.types.str;
9 default = "127.0.0.1";
10 };
11 port = lib.mkOption {
12 type = lib.types.port;
13 default = 9251;
14 };
15 prometheus = lib.mkOption {
16 type = lib.types.submodule {
17 options.url = lib.mkOption {
18 type = lib.types.nullOr lib.types.str;
19 default = null;
20 };
21 };
22 default = {};
23 };
24 };
25
26 persist = {
27 directories = [
28 {
29 directory = "/var/lib/grafana";
30 user = "grafana";
31 group = "grafana";
32 mode = "0700";
33 }
34 ];
35 };
36
37 reverseProxy = {host, ...}: let
38 cfg = host.settings.services.grafana;
39 in {
40 ${cfg.domain} = {
41 port = cfg.port;
42 };
43 };
44
45 backup = {
46 pkgs,
47 lib,
48 ...
49 }: {
50 grafana = let
51 backupDir = "/tmp/backups/grafana";
52 in {
53 paths = [backupDir];
54
55 # See https://grafana.com/docs/grafana/latest/administration/back-up-grafana/
56 backupPrepareCommand = lib.getExe (pkgs.writeShellApplication {
57 name = "backup-grafana-prepare";
58 runtimeInputs = [
59 pkgs.sqlite
60 ];
61 text = ''
62 set -euo pipefail
63
64 DATA_DIR="/var/lib/grafana/data"
65
66 mkdir -p "${backupDir}"
67
68 sqlite3 "$DATA_DIR/grafana.db" ".backup '${backupDir}/grafana.db'"
69
70 if [ -d "$DATA_DIR/plugins" ]; then
71 cp -a "$DATA_DIR/plugins" "${backupDir}/"
72 fi
73 '';
74 });
75 backupCleanupCommand = ''
76 rm -r "${backupDir}"
77 '';
78 };
79 };
80
81 nixos = {
82 host,
83 config,
84 ...
85 }: let
86 cfg = host.settings.services.grafana;
87 in {
88 services.grafana = {
89 enable = true;
90 settings = {
91 server = {
92 http_addr = cfg.address;
93 http_port = cfg.port;
94 protocol = "http";
95 domain = cfg.domain;
96 serve_from_sub_path = false;
97 root_url = "%(protocol)s://%(domain)s:%(http_port)s/";
98 read_timeout = "180s";
99 enable_gzip = true;
100 };
101 security = {
102 secret_key = "$__file{${config.vaultix.secrets."grafana-security-key".path}}";
103 admin_user = "hpcesia";
104 admin_email = "me@hpcesia.com";
105 admin_password = "$__file{${config.vaultix.secrets."grafana-admin-password".path}}";
106 };
107 users = {
108 allow_sign_up = false;
109 default_theme = "system";
110 default_language = "detect";
111 };
112 analytics = {
113 reporting_enabled = false;
114 check_for_updates = false;
115 check_for_plugin_updates = false;
116 };
117 };
118 provision = {
119 enable = true;
120 datasources.settings.datasources = lib.optional (cfg.prometheus.url != null) {
121 name = "Prometheus";
122 type = "prometheus";
123 access = "proxy";
124 url = cfg.prometheus.url;
125 jsonData = {
126 httpMethod = "POST";
127 timeInterval = "30s";
128 manageAlerts = true;
129 prometheusType = "Prometheus";
130 prometheusVersion = "2.49.0";
131 cacheLevel = "High";
132 disableRecordingRules = false;
133 incrementalQueryOverlapWindow = "10m";
134 };
135 };
136 dashboards.settings.providers = [
137 {
138 name = "Nix";
139 type = "file";
140 options.path = ./dashboards;
141 }
142 ];
143 };
144 };
145
146 vaultix.secrets = {
147 grafana-admin-password = {
148 file = ./admin-password.age;
149 owner = "grafana";
150 group = "grafana";
151 mode = "0440";
152 };
153 grafana-security-key = {
154 file = ./security-key.age;
155 owner = "grafana";
156 group = "grafana";
157 mode = "0440";
158 };
159 };
160 };
161 };
162}