{ config, lib, pkgs, ... }: let inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption; inherit (lib) literalExample mapAttrs optional optionalString types; cfg = config.services.limesurvey-patched; fpm = config.services.phpfpm.pools.limesurvey; user = "limesurvey"; group = config.services.nginx.group; stateDir = cfg.stateDir; pkg = cfg.package; configType = with types; oneOf [ (attrsOf configType) str int bool ] // { description = "limesurvey config type (str, int, bool or attribute set thereof)"; }; limesurveyConfig = pkgs.writeText "config.php" '' ''; in { # interface options.services.limesurvey-patched = { enable = mkEnableOption "Limesurvey web application."; package = mkOption { type = types.package; default = pkgs.limesurvey; description = "The Limesurvey package to use"; }; domain = mkOption { type = types.str; default = ""; example = "example.org"; description = "the domain name of limesurvey"; }; poolConfig = mkOption { type = with types; attrsOf (oneOf [ str int bool ]); default = { "pm" = "dynamic"; "pm.max_children" = 32; "pm.start_servers" = 2; "pm.min_spare_servers" = 2; "pm.max_spare_servers" = 4; "pm.max_requests" = 500; }; description = '' Options for the LimeSurvey PHP pool. See the documentation on php-fpm.conf for details on configuration directives. ''; }; config = mkOption { type = configType; default = {}; description = '' LimeSurvey configuration. Refer to for details on supported values. ''; }; stateDir = mkOption { type = types.str; default = "/var/lib/limesurvey"; description = '' LimeSurvey keeps its state in here. For a variety of stupid php reasons, it will also keep a complete copy of itself in here. ''; }; }; # implementation config = mkIf cfg.enable { services.limesurvey-patched.config = mapAttrs (name: mkDefault) { runtimePath = "${stateDir}/tmp/runtime"; components = { assetManager.basePath = "${stateDir}/tmp/assets"; urlManager = { urlFormat = "path"; showScriptName = false; }; }; }; services.phpfpm.pools.limesurvey = { inherit user group; phpEnv.LIMESURVEY_CONFIG = "/var/lib/limesurvey/config/config.php"; settings = { "listen.owner" = config.services.nginx.user; "listen.group" = config.services.nginx.group; } // cfg.poolConfig; }; services.nginx = { enable = true; virtualHosts.${cfg.domain} = { root = stateDir; locations."/".tryFiles = "$uri /index.php?$args"; locations."~ [^/]\\.php(/|$)".extraConfig = '' fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } fastcgi_pass unix:${fpm.socket}; fastcgi_index index.php; ''; }; }; systemd.tmpfiles.rules = [ "C ${stateDir} 0750 ${user} ${group} - ${pkg}/share/limesurvey" "d ${stateDir}/tmp 0750 ${user} ${group} - -" "d ${stateDir}/tmp/assets 0750 ${user} ${group} - -" "d ${stateDir}/tmp/runtime 0750 ${user} ${group} - -" "d ${stateDir}/tmp/upload 0750 ${user} ${group} - -" ]; systemd.services.limesurvey-init = { wantedBy = [ "multi-user.target" ]; before = [ "phpfpm-limesurvey.service" ]; after = [ "postgresql.service" ]; environment.LIMESURVEY_CONFIG = "/var/lib/limesurvey/config/config.php"; script = '' chmod -R +w ${stateDir} mkdir -p ${stateDir}/config cp -f ${limesurveyConfig} ${stateDir}/config/config.php # update or install the database as required ${pkgs.php}/bin/php /var/lib/limesurvey/application/commands/console.php updatedb || \ ${pkgs.php}/bin/php /var/lib/limesurvey/application/commands/console.php install admin password admin admin@example.com verbose ''; serviceConfig = { User = user; Group = group; Type = "oneshot"; }; }; #systemd.services.httpd.after = [ "postgresql.service" ]; systemd.services.nginx.after = [ "postgresql.service" ]; users.users.${user} = { group = group; isSystemUser = true; }; }; }