From 2ffc6dd5fbe031ef19368022f6066c105bb9a773 Mon Sep 17 00:00:00 2001 From: Timo Wilken Date: Wed, 24 May 2023 23:17:50 +0200 Subject: Run Grafana using Docker --- tw/services/grafana.scm | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ tw/system/vin.scm | 10 +++++--- 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 tw/services/grafana.scm 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."))) diff --git a/tw/system/vin.scm b/tw/system/vin.scm index ae8a1d74..8dfbd2df 100644 --- a/tw/system/vin.scm +++ b/tw/system/vin.scm @@ -7,6 +7,7 @@ #:use-module (gnu system locale) #:use-module (gnu system nss) #:use-module (guix gexp) + #:use-module (tw services grafana) #:use-module (tw services restic) #:use-module (tw system)) @@ -103,9 +104,12 @@ (keep-monthly -1)))) ;; For running the Grafana docker container. - (service docker-service-type) - (service dbus-root-service-type) ; required by docker-service-type - (service elogind-service-type) ; required by docker-service-type + (service grafana-service-type + (grafana-configuration + (bind-address (server-wireguard-address host-name)))) + (service docker-service-type) ; required by `grafana-service-type' + (service dbus-root-service-type) ; required by `docker-service-type' + (service elogind-service-type) ; required by `docker-service-type' (server-base-services host-name))) -- cgit v1.2.3