about summary refs log tree commit diff
path: root/nixos/modules/services/web-apps/flarum.nix
diff options
context:
space:
mode:
authorFlorian Agbuya <fa@m-labs.ph>2024-05-14 17:00:40 +0800
committerFlorian Agbuya <fa@m-labs.ph>2024-05-20 11:20:07 +0800
commit7ad171b5add5ad362febb7fbb7de12dd0b0ddaed (patch)
tree852a477f97256e71c1c6db8b387ba6cea0a7c4a8 /nixos/modules/services/web-apps/flarum.nix
parentaf487fbf3927678ffb00045e3f0094e18a149e91 (diff)
nixos/flarum: init module
Diffstat (limited to 'nixos/modules/services/web-apps/flarum.nix')
-rw-r--r--nixos/modules/services/web-apps/flarum.nix210
1 files changed, 210 insertions, 0 deletions
diff --git a/nixos/modules/services/web-apps/flarum.nix b/nixos/modules/services/web-apps/flarum.nix
new file mode 100644
index 0000000000000..a967c3b121bd6
--- /dev/null
+++ b/nixos/modules/services/web-apps/flarum.nix
@@ -0,0 +1,210 @@
+{ pkgs, lib, config, ... }:
+
+with lib;
+
+let
+  cfg = config.services.flarum;
+
+  flarumInstallConfig = pkgs.writeText "config.json" (builtins.toJSON {
+    debug = false;
+    offline = false;
+
+    baseUrl = cfg.baseUrl;
+    databaseConfiguration = cfg.database;
+    adminUser = {
+      username = cfg.adminUser;
+      password = cfg.initialAdminPassword;
+      email = cfg.adminEmail;
+    };
+    settings = {
+      forum_title = cfg.forumTitle;
+    };
+  });
+in {
+  options.services.flarum = {
+    enable = mkEnableOption "Flarum discussion platform";
+
+    package = mkPackageOption pkgs "flarum" { };
+
+    forumTitle = mkOption {
+      type = types.str;
+      default = "A Flarum Forum on NixOS";
+      description = "Title of the forum.";
+    };
+
+    domain = mkOption {
+      type = types.str;
+      default = "localhost";
+      example = "forum.example.com";
+      description = "Domain to serve on.";
+    };
+
+    baseUrl = mkOption {
+      type = types.str;
+      default = "http://localhost";
+      example = "https://forum.example.com";
+      description = "Change `domain` instead.";
+    };
+
+    adminUser = mkOption {
+      type = types.str;
+      default = "flarum";
+      description = "Username for first web application administrator";
+    };
+
+    adminEmail = mkOption {
+      type = types.str;
+      default = "admin@example.com";
+      description = "Email for first web application administrator";
+    };
+
+    initialAdminPassword = mkOption {
+      type = types.str;
+      default = "flarum";
+      description = "Initial password for the adminUser";
+    };
+
+    user = mkOption {
+      type = types.str;
+      default = "flarum";
+      description = "System user to run Flarum";
+    };
+
+    group = mkOption {
+      type = types.str;
+      default = "flarum";
+      description = "System group to run Flarum";
+    };
+
+    stateDir = mkOption {
+      type = types.path;
+      default = "/var/lib/flarum";
+      description = "Home directory for writable storage";
+    };
+
+    database = mkOption rec {
+      type = with types; attrsOf (oneOf [str bool int]);
+      description = "MySQL database parameters";
+      default = {
+        # the database driver; i.e. MySQL; MariaDB...
+        driver = "mysql";
+        # the host of the connection; localhost in most cases unless using an external service
+        host = "localhost";
+        # the name of the database in the instance
+        database = "flarum";
+        # database username
+        username = "flarum";
+        # database password
+        password = "";
+        # the prefix for the tables; useful if you are sharing the same database with another service
+        prefix = "";
+        # the port of the connection; defaults to 3306 with MySQL
+        port = 3306;
+        strict = false;
+      };
+    };
+
+    createDatabaseLocally = mkOption {
+      type = types.bool;
+      default = true;
+      description = "Create the database and database user locally, and run installation.";
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.users.${cfg.user} = {
+      isSystemUser = true;
+      home = cfg.stateDir;
+      createHome = true;
+      group = cfg.group;
+    };
+    users.groups.${cfg.group} = {};
+
+    services.phpfpm.pools.flarum = {
+      user = cfg.user;
+      settings = {
+        "listen.owner" = config.services.nginx.user;
+        "listen.group" = config.services.nginx.group;
+        "listen.mode" = "0600";
+        "pm" = mkDefault "dynamic";
+        "pm.max_children" = mkDefault 10;
+        "pm.max_requests" = mkDefault 500;
+        "pm.start_servers" = mkDefault 2;
+        "pm.min_spare_servers" = mkDefault 1;
+        "pm.max_spare_servers" = mkDefault 3;
+      };
+      phpOptions = ''
+        error_log = syslog
+        log_errors = on
+      '';
+    };
+
+    services.nginx = {
+      enable = true;
+      virtualHosts."${cfg.domain}" = {
+        root = "${cfg.stateDir}/public";
+        locations."~ \.php$".extraConfig = ''
+          fastcgi_pass unix:${config.services.phpfpm.pools.flarum.socket};
+          fastcgi_index site.php;
+        '';
+        extraConfig = ''
+          index index.php;
+          include ${cfg.package}/share/php/flarum/.nginx.conf;
+        '';
+      };
+    };
+
+    services.mysql = mkIf cfg.enable {
+      enable = true;
+      package = pkgs.mysql;
+      ensureDatabases = [cfg.database.database];
+      ensureUsers = [
+        {
+          name = cfg.database.username;
+          ensurePermissions = {
+            "${cfg.database.database}.*" = "ALL PRIVILEGES";
+          };
+        }
+      ];
+    };
+
+    assertions = [
+      {
+        assertion = !cfg.createDatabaseLocally || cfg.database.driver == "mysql";
+        message = "Flarum can only be automatically installed in MySQL/MariaDB.";
+      }
+    ];
+
+    systemd.services.flarum-install = {
+      description = "Flarum installation";
+      requiredBy = ["phpfpm-flarum.service"];
+      before = ["phpfpm-flarum.service"];
+      requires = ["mysql.service"];
+      after = ["mysql.service"];
+      serviceConfig = {
+        Type = "oneshot";
+        User = cfg.user;
+        Group = cfg.group;
+      };
+      path = [config.services.phpfpm.phpPackage];
+      script = ''
+        mkdir -p ${cfg.stateDir}/{extensions,public/assets/avatars}
+        mkdir -p ${cfg.stateDir}/storage/{cache,formatter,sessions,views}
+        cd ${cfg.stateDir}
+        cp -f ${cfg.package}/share/php/flarum/{extend.php,site.php,flarum} .
+        ln -sf ${cfg.package}/share/php/flarum/vendor .
+        ln -sf ${cfg.package}/share/php/flarum/public/index.php public/
+        chmod a+x . public
+        chmod +x site.php extend.php flarum
+      '' + optionalString (cfg.createDatabaseLocally && cfg.database.driver == "mysql") ''
+        if [ ! -f config.php ]; then
+            php flarum install --file=${flarumInstallConfig}
+        fi
+        php flarum migrate
+        php flarum cache:clear
+      '';
+    };
+  };
+
+  meta.maintainers = with lib.maintainers; [ fsagbuya jasonodoom ];
+}