aboutsummaryrefslogtreecommitdiff
path: root/tw/services/grafana.scm
diff options
context:
space:
mode:
Diffstat (limited to 'tw/services/grafana.scm')
-rw-r--r--tw/services/grafana.scm68
1 files changed, 68 insertions, 0 deletions
diff --git a/tw/services/grafana.scm b/tw/services/grafana.scm
new file mode 100644
index 00000000..4a98ad38
--- /dev/null
+++ b/tw/services/grafana.scm
@@ -0,0 +1,68 @@
+(define-module (tw services grafana)
+ #:use-module (gnu)
+ #:use-module ((gnu packages admin) #:select (shadow))
+ #:use-module ((gnu packages docker) #:select (docker-cli))
+ #:use-module (gnu services)
+ #:use-module (gnu services configuration)
+ #:use-module (gnu services databases)
+ #:use-module (gnu services shepherd)
+ #:export (grafana-service-type
+ grafana-configuration))
+
+;; TODO: Mimir for long-term Prometheus metrics storage?
+;; TODO: Store Grafana data in Postgres instead of SQLite?
+;; TODO: Back up /var/lib/grafana, especially grafana.db
+
+(define %grafana-user "grafana")
+(define %grafana-uid 472) ; to match container
+
+;; TODO: reverse proxy to make it accessible at http://vin.wg/grafana?
+(define-configuration/no-serialization grafana-configuration
+ (container (string "docker.io/grafana/grafana-oss:9.5.2") "Container image to run.")
+ (bind-address (string "0.0.0.0") "The host IP to bind to.")
+ (host-port (integer 3000) "The port to bind to on the host.")
+ (data-path (string "/var/lib/grafana") "The path to store data in, on the host."))
+
+(define (grafana-accounts config)
+ (list (user-account
+ (name %grafana-user)
+ (uid %grafana-uid)
+ (group "nogroup")
+ (comment "Grafana server user")
+ (system? #t)
+ (home-directory (grafana-configuration-data-path config))
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define (grafana-shepherd-service config)
+ (list (shepherd-service
+ (provision '(grafana))
+ (requirement '(networking wireguard-wg0))
+ (documentation "Run a Grafana instance using Docker.")
+ (start #~(make-forkexec-constructor
+ ;; https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/
+ (list #$(file-append docker-cli "/bin/docker") "run" "--rm" "--network=host"
+ "--name" "grafana" "--user" '#$%grafana-user
+ "-v" '#$(format #f "~a:/var/lib/grafana" (grafana-configuration-data-path config))
+ ;; https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/
+ "-e" "GF_SERVER_PROTOCOL=http" ; use Wireguard for encryption
+ "-e" '#$(format #f "GF_SERVER_HTTP_ADDR=~a" (grafana-configuration-bind-address config))
+ "-e" '#$(format #f "GF_SERVER_HTTP_PORT=~a" (grafana-configuration-host-port config))
+ "-e" "GF_SERVER_ENABLE_GZIP=true" ; recommended by docs
+ "-e" "GF_ANALYTICS_REPORTING_ENABLED=false"
+ "-e" "GF_ANALYTICS_CHECK_FOR_UPDATES=false"
+ "-e" "GF_ANALYTICS_CHECK_FOR_PLUGIN_UPDATES=false"
+ "-e" "GF_SNAPSHOTS_ENABLED=false" ; disable publishing dashboard snapshots to the internet
+ "-e" "GF_DATE_FORMATS_INTERVAL_HOUR=DD.MM. HH:mm" ; use sensible date format
+ "-e" "GF_DATE_FORMATS_INTERVAL_DAY=DD.MM." ; use sensible date format
+ ;; TODO: https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#smtp
+ '#$(grafana-configuration-container config))))
+ (stop #~(make-kill-destructor)))))
+
+(define grafana-service-type
+ (service-type
+ (name 'grafana)
+ (extensions
+ (list (service-extension shepherd-root-service-type grafana-shepherd-service)
+ (service-extension account-service-type grafana-accounts)))
+ (default-value (grafana-configuration))
+ (description "Grafana server, running under Docker.")))