diff options
Diffstat (limited to 'nixos/modules/services/web-apps/dolibarr.nix')
-rw-r--r-- | nixos/modules/services/web-apps/dolibarr.nix | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/nixos/modules/services/web-apps/dolibarr.nix b/nixos/modules/services/web-apps/dolibarr.nix deleted file mode 100644 index 3f9f853e3b25..000000000000 --- a/nixos/modules/services/web-apps/dolibarr.nix +++ /dev/null @@ -1,325 +0,0 @@ -{ config, pkgs, lib, ... }: -let - inherit (lib) any boolToString concatStringsSep isBool isString mapAttrsToList mkDefault mkEnableOption mkIf mkMerge mkOption optionalAttrs types mkPackageOption; - - package = cfg.package.override { inherit (cfg) stateDir; }; - - cfg = config.services.dolibarr; - vhostCfg = lib.optionalAttrs (cfg.nginx != null) config.services.nginx.virtualHosts."${cfg.domain}"; - - mkConfigFile = filename: settings: - let - # hack in special logic for secrets so we read them from a separate file avoiding the nix store - secretKeys = [ "force_install_databasepass" "dolibarr_main_db_pass" "dolibarr_main_instance_unique_id" ]; - - toStr = k: v: - if (any (str: k == str) secretKeys) then v - else if isString v then "'${v}'" - else if isBool v then boolToString v - else if v == null then "null" - else toString v - ; - in - pkgs.writeText filename '' - <?php - ${concatStringsSep "\n" (mapAttrsToList (k: v: "\$${k} = ${toStr k v};") settings)} - ''; - - # see https://github.com/Dolibarr/dolibarr/blob/develop/htdocs/install/install.forced.sample.php for all possible values - install = { - force_install_noedit = 2; - force_install_main_data_root = "${cfg.stateDir}/documents"; - force_install_nophpinfo = true; - force_install_lockinstall = "444"; - force_install_distrib = "nixos"; - force_install_type = "mysqli"; - force_install_dbserver = cfg.database.host; - force_install_port = toString cfg.database.port; - force_install_database = cfg.database.name; - force_install_databaselogin = cfg.database.user; - - force_install_mainforcehttps = vhostCfg.forceSSL or false; - force_install_createuser = false; - force_install_dolibarrlogin = null; - } // optionalAttrs (cfg.database.passwordFile != null) { - force_install_databasepass = ''file_get_contents("${cfg.database.passwordFile}")''; - }; -in -{ - # interface - options.services.dolibarr = { - enable = mkEnableOption "dolibarr"; - - package = mkPackageOption pkgs "dolibarr" { }; - - domain = mkOption { - type = types.str; - default = "localhost"; - description = '' - Domain name of your server. - ''; - }; - - user = mkOption { - type = types.str; - default = "dolibarr"; - description = '' - User account under which dolibarr runs. - - ::: {.note} - If left as the default value this user will automatically be created - on system activation, otherwise you are responsible for - ensuring the user exists before the dolibarr application starts. - ::: - ''; - }; - - group = mkOption { - type = types.str; - default = "dolibarr"; - description = '' - Group account under which dolibarr runs. - - ::: {.note} - If left as the default value this group will automatically be created - on system activation, otherwise you are responsible for - ensuring the group exists before the dolibarr application starts. - ::: - ''; - }; - - stateDir = mkOption { - type = types.str; - default = "/var/lib/dolibarr"; - description = '' - State and configuration directory dolibarr will use. - ''; - }; - - database = { - host = mkOption { - type = types.str; - default = "localhost"; - description = "Database host address."; - }; - port = mkOption { - type = types.port; - default = 3306; - description = "Database host port."; - }; - name = mkOption { - type = types.str; - default = "dolibarr"; - description = "Database name."; - }; - user = mkOption { - type = types.str; - default = "dolibarr"; - description = "Database username."; - }; - passwordFile = mkOption { - type = with types; nullOr path; - default = null; - example = "/run/keys/dolibarr-dbpassword"; - description = "Database password file."; - }; - createLocally = mkOption { - type = types.bool; - default = true; - description = "Create the database and database user locally."; - }; - }; - - settings = mkOption { - type = with types; (attrsOf (oneOf [ bool int str ])); - default = { }; - description = "Dolibarr settings, see <https://github.com/Dolibarr/dolibarr/blob/develop/htdocs/conf/conf.php.example> for details."; - }; - - nginx = mkOption { - type = types.nullOr (types.submodule ( - lib.recursiveUpdate - (import ../web-servers/nginx/vhost-options.nix { inherit config lib; }) - { - # enable encryption by default, - # as sensitive login and Dolibarr (ERP) data should not be transmitted in clear text. - options.forceSSL.default = true; - options.enableACME.default = true; - } - )); - default = null; - example = lib.literalExpression '' - { - serverAliases = [ - "dolibarr.''${config.networking.domain}" - "erp.''${config.networking.domain}" - ]; - enableACME = false; - } - ''; - description = '' - With this option, you can customize an nginx virtual host which already has sensible defaults for Dolibarr. - Set to {} if you do not need any customization to the virtual host. - If enabled, then by default, the {option}`serverName` is - `''${domain}`, - SSL is active, and certificates are acquired via ACME. - If this is set to null (the default), no nginx virtualHost will be configured. - ''; - }; - - 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 Dolibarr PHP pool. See the documentation on [`php-fpm.conf`](https://www.php.net/manual/en/install.fpm.configuration.php) - for details on configuration directives. - ''; - }; - }; - - # implementation - config = mkIf cfg.enable (mkMerge [ - { - - assertions = [ - { assertion = cfg.database.createLocally -> cfg.database.user == cfg.user; - message = "services.dolibarr.database.user must match services.dolibarr.user if the database is to be automatically provisioned"; - } - ]; - - services.dolibarr.settings = { - dolibarr_main_url_root = "https://${cfg.domain}"; - dolibarr_main_document_root = "${package}/htdocs"; - dolibarr_main_url_root_alt = "/custom"; - dolibarr_main_data_root = "${cfg.stateDir}/documents"; - - dolibarr_main_db_host = cfg.database.host; - dolibarr_main_db_port = toString cfg.database.port; - dolibarr_main_db_name = cfg.database.name; - dolibarr_main_db_prefix = "llx_"; - dolibarr_main_db_user = cfg.database.user; - dolibarr_main_db_pass = mkIf (cfg.database.passwordFile != null) '' - file_get_contents("${cfg.database.passwordFile}") - ''; - dolibarr_main_db_type = "mysqli"; - dolibarr_main_db_character_set = mkDefault "utf8"; - dolibarr_main_db_collation = mkDefault "utf8_unicode_ci"; - - # Authentication settings - dolibarr_main_authentication = mkDefault "dolibarr"; - - # Security settings - dolibarr_main_prod = true; - dolibarr_main_force_https = vhostCfg.forceSSL or false; - dolibarr_main_restrict_os_commands = "${pkgs.mariadb}/bin/mysqldump, ${pkgs.mariadb}/bin/mysql"; - dolibarr_nocsrfcheck = false; - dolibarr_main_instance_unique_id = '' - file_get_contents("${cfg.stateDir}/dolibarr_main_instance_unique_id") - ''; - dolibarr_mailing_limit_sendbyweb = false; - }; - - systemd.tmpfiles.rules = [ - "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group}" - "d '${cfg.stateDir}/documents' 0750 ${cfg.user} ${cfg.group}" - "f '${cfg.stateDir}/conf.php' 0660 ${cfg.user} ${cfg.group}" - "L '${cfg.stateDir}/install.forced.php' - ${cfg.user} ${cfg.group} - ${mkConfigFile "install.forced.php" install}" - ]; - - services.mysql = mkIf cfg.database.createLocally { - enable = mkDefault true; - package = mkDefault pkgs.mariadb; - ensureDatabases = [ cfg.database.name ]; - ensureUsers = [ - { name = cfg.database.user; - ensurePermissions = { "${cfg.database.name}.*" = "ALL PRIVILEGES"; }; - } - ]; - }; - - services.nginx.enable = mkIf (cfg.nginx != null) true; - services.nginx.virtualHosts."${cfg.domain}" = mkIf (cfg.nginx != null) (lib.mkMerge [ - cfg.nginx - ({ - root = lib.mkForce "${package}/htdocs"; - locations."/".index = "index.php"; - locations."~ [^/]\\.php(/|$)" = { - extraConfig = '' - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - fastcgi_pass unix:${config.services.phpfpm.pools.dolibarr.socket}; - ''; - }; - }) - ]); - - systemd.services."phpfpm-dolibarr".after = mkIf cfg.database.createLocally [ "mysql.service" ]; - services.phpfpm.pools.dolibarr = { - inherit (cfg) user group; - phpPackage = pkgs.php.buildEnv { - extensions = { enabled, all }: enabled ++ [ all.calendar ]; - # recommended by dolibarr web application - extraConfig = '' - session.use_strict_mode = 1 - session.cookie_samesite = "Lax" - ; open_basedir = "${package}/htdocs, ${cfg.stateDir}" - allow_url_fopen = 0 - disable_functions = "pcntl_alarm, pcntl_fork, pcntl_waitpid, pcntl_wait, pcntl_wifexited, pcntl_wifstopped, pcntl_wifsignaled, pcntl_wifcontinued, pcntl_wexitstatus, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal, pcntl_signal_get_handler, pcntl_signal_dispatch, pcntl_get_last_error, pcntl_strerror, pcntl_sigprocmask, pcntl_sigwaitinfo, pcntl_sigtimedwait, pcntl_exec, pcntl_getpriority, pcntl_setpriority, pcntl_async_signals" - ''; - }; - - settings = { - "listen.mode" = "0660"; - "listen.owner" = cfg.user; - "listen.group" = cfg.group; - } // cfg.poolConfig; - }; - - # there are several challenges with dolibarr and NixOS which we can address here - # - the dolibarr installer cannot be entirely automated, though it can partially be by including a file called install.forced.php - # - the dolibarr installer requires write access to its config file during installation, though not afterwards - # - the dolibarr config file generally holds secrets generated by the installer, though the config file is a php file so we can read and write these secrets from an external file - systemd.services.dolibarr-config = { - description = "dolibarr configuration file management via NixOS"; - wantedBy = [ "multi-user.target" ]; - - script = '' - # extract the 'main instance unique id' secret that the dolibarr installer generated for us, store it in a file for use by our own NixOS generated configuration file - ${pkgs.php}/bin/php -r "include '${cfg.stateDir}/conf.php'; file_put_contents('${cfg.stateDir}/dolibarr_main_instance_unique_id', \$dolibarr_main_instance_unique_id);" - - # replace configuration file generated by installer with the NixOS generated configuration file - install -m 644 ${mkConfigFile "conf.php" cfg.settings} '${cfg.stateDir}/conf.php' - ''; - - serviceConfig = { - Type = "oneshot"; - User = cfg.user; - Group = cfg.group; - RemainAfterExit = "yes"; - }; - - unitConfig = { - ConditionFileNotEmpty = "${cfg.stateDir}/conf.php"; - }; - }; - - users.users.dolibarr = mkIf (cfg.user == "dolibarr" ) { - isSystemUser = true; - group = cfg.group; - }; - - users.groups = optionalAttrs (cfg.group == "dolibarr") { - dolibarr = { }; - }; - } - (mkIf (cfg.nginx != null) { - users.users."${config.services.nginx.group}".extraGroups = mkIf (cfg.nginx != null) [ cfg.group ]; - }) -]); -} |