{ config, inputs, lib, this, ... }: with lib; let cfg = config.nixfiles.modules.plausible; in { options.nixfiles.modules.plausible = { enable = mkEnableOption "Plausible Analytics"; port = mkOption { description = "Port."; type = with types; port; default = 8000; }; domain = mkOption { description = "Domain name sans protocol scheme."; type = with types; nullOr str; default = "plausible.${config.networking.domain}"; }; }; config = let db = "plausible"; in mkIf cfg.enable { _module.args.libPlausible = { htmlPlausibleScript = { domain ? "$host", src ? "https://${cfg.domain}/js/script.js", }: ''''; }; secrets = { plausible-key.file = "${inputs.self}/secrets/plausible-key"; plausible-admin-password.file = "${inputs.self}/secrets/plausible-admin-password"; plausible-smtp-password.file = "${inputs.self}/secrets/smtp-password"; }; nixfiles.modules = { nginx = { enable = true; upstreams.plausible.servers."127.0.0.1:${toString cfg.port}" = { }; virtualHosts.${cfg.domain}.locations."/" = { proxyPass = "http://plausible"; proxyWebsockets = true; }; }; postgresql = { enable = true; extraPostStart = [ '' $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' $PSQL "${db}" -tAc 'CREATE EXTENSION IF NOT EXISTS citext' '' ]; }; clickhouse.enable = true; }; services.postgresql = { ensureDatabases = [ db ]; ensureUsers = [ { name = db; ensureDBOwnership = true; } ]; }; services.plausible = { enable = true; adminUser = { name = "admin"; email = "admin@${my.domain.shire}"; passwordFile = config.secrets.plausible-admin-password.path; activate = false; }; mail = { email = "admin+plausible@${my.domain.shire}"; smtp = { hostAddr = my.domain.shire; hostPort = 465; enableSSL = true; user = "azahi@${my.domain.shire}"; passwordFile = config.secrets.plausible-smtp-password.path; }; }; database = { clickhouse = { setup = false; url = "http://127.0.0.1:8123/default"; }; postgres = { setup = true; dbname = db; }; }; server = { baseUrl = "https://${cfg.domain}"; disableRegistration = true; listenAddress = "127.0.0.1"; inherit (cfg) port; secretKeybaseFile = config.secrets.plausible-key.path; }; }; systemd.services.plausible = rec { after = [ "postgresql.service" "clickhouse.service" ]; requires = after; }; topology = with cfg; { nodes.${this.hostname}.services.plausible = { name = "Plausible"; icon = "${inputs.homelab-svg-assets}/assets/plausible.svg"; info = domain; details.listen.text = "${config.services.plausible.server.listenAddress}:${toString port}"; }; }; }; }