at 25.11-pre 7.1 kB view raw
1{ 2 pkgs, 3 config, 4 lib, 5 ... 6}: 7let 8 cfg = config.services.part-db; 9 pkg = cfg.package; 10 11 inherit (lib) 12 mkEnableOption 13 mkPackageOption 14 mkOption 15 types 16 mkIf 17 ; 18in 19{ 20 meta.maintainers = with lib.maintainers; [ felbinger ]; 21 22 options.services.part-db = { 23 enable = mkEnableOption "PartDB"; 24 25 package = mkPackageOption pkgs "part-db" { }; 26 27 phpPackage = mkPackageOption pkgs "php" { } // { 28 apply = 29 pkg: 30 pkg.buildEnv { 31 extraConfig = '' 32 memory_limit = 256M; 33 ''; 34 }; 35 }; 36 37 enableNginx = mkOption { 38 type = types.bool; 39 default = true; 40 description = '' 41 Whether to enable nginx or not. If enabled, an nginx virtual host will 42 be created for access to part-db. If not enabled, then you may use 43 `''${config.services.part-db.package}/public` as your document root in 44 whichever webserver you wish to setup. 45 ''; 46 }; 47 48 enablePostgresql = mkOption { 49 type = types.bool; 50 default = true; 51 description = '' 52 Whether to configure the postgresql database for part-db. If enabled, 53 a database and user will be created for part-db. 54 ''; 55 }; 56 57 virtualHost = mkOption { 58 type = types.str; 59 default = "localhost"; 60 description = '' 61 The virtualHost at which you wish part-db to be served. 62 ''; 63 }; 64 65 poolConfig = lib.mkOption { 66 type = lib.types.attrsOf ( 67 lib.types.oneOf [ 68 lib.types.str 69 lib.types.int 70 lib.types.bool 71 ] 72 ); 73 default = { }; 74 defaultText = '' 75 { 76 "pm" = "dynamic"; 77 "pm.max_children" = 32; 78 "pm.start_servers" = 2; 79 "pm.min_spare_servers" = 2; 80 "pm.max_spare_servers" = 4; 81 "pm.max_requests" = 500; 82 } 83 ''; 84 description = '' 85 Options for the PartDB PHP pool. See the documentation on <literal>php-fpm.conf</literal> 86 for details on configuration directives. 87 ''; 88 }; 89 90 settings = lib.mkOption { 91 default = { }; 92 description = '' 93 Options for part-db configuration. Refer to 94 <https://github.com/Part-DB/Part-DB-server/blob/master/.env> for 95 details on supported values. All <option>_FILE values supported by 96 upstream are supported here. 97 ''; 98 example = lib.literalExpression '' 99 { 100 DATABASE_URL = "postgresql://db_user@localhost/db_name?serverVersion=16.6&charset=utf8&host=/var/run/postgresql"; 101 } 102 ''; 103 type = lib.types.submodule { 104 freeformType = lib.types.attrsOf ( 105 with lib.types; 106 oneOf [ 107 str 108 int 109 bool 110 ] 111 ); 112 options = { 113 DATABASE_URL = lib.mkOption { 114 type = lib.types.str; 115 default = "postgresql://part-db@localhost/part-db?serverVersion=${config.services.postgresql.package.version}&host=/run/postgresql"; 116 defaultText = "postgresql://part-db@localhost/part-db?serverVersion=\${config.services.postgresql.package.version}&host=/run/postgresql"; 117 description = '' 118 The postgresql database server to connect to. 119 Defauls to local postgresql unix socket 120 ''; 121 }; 122 }; 123 }; 124 }; 125 }; 126 127 config = mkIf cfg.enable { 128 users.groups.part-db = { }; 129 users.users.part-db = { 130 group = "part-db"; 131 isSystemUser = true; 132 }; 133 134 services = { 135 phpfpm.pools.part-db = { 136 user = "part-db"; 137 group = "part-db"; 138 phpPackage = cfg.phpPackage; 139 phpOptions = '' 140 log_errors = on 141 ''; 142 settings = { 143 "listen.mode" = lib.mkDefault "0660"; 144 "listen.owner" = lib.mkDefault "part-db"; 145 "listen.group" = lib.mkDefault "part-db"; 146 "pm" = lib.mkDefault "dynamic"; 147 "pm.max_children" = lib.mkDefault 32; 148 "pm.start_servers" = lib.mkDefault 2; 149 "pm.min_spare_servers" = lib.mkDefault 2; 150 "pm.max_spare_servers" = lib.mkDefault 4; 151 "pm.max_requests" = lib.mkDefault 500; 152 } // cfg.poolConfig; 153 }; 154 155 postgresql = mkIf cfg.enablePostgresql { 156 enable = true; 157 ensureUsers = [ 158 { 159 name = "part-db"; 160 ensureDBOwnership = true; 161 } 162 ]; 163 ensureDatabases = [ "part-db" ]; 164 }; 165 166 nginx = mkIf cfg.enableNginx { 167 enable = true; 168 recommendedTlsSettings = lib.mkDefault true; 169 recommendedOptimisation = lib.mkDefault true; 170 recommendedGzipSettings = lib.mkDefault true; 171 virtualHosts.${cfg.virtualHost} = { 172 root = "${pkg}/public"; 173 locations = { 174 "/" = { 175 tryFiles = "$uri $uri/ /index.php"; 176 index = "index.php"; 177 extraConfig = '' 178 sendfile off; 179 ''; 180 }; 181 "~ \.php$" = { 182 extraConfig = '' 183 include ${config.services.nginx.package}/conf/fastcgi_params ; 184 fastcgi_param SCRIPT_FILENAME $request_filename; 185 fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice 186 fastcgi_pass unix:${config.services.phpfpm.pools.part-db.socket}; 187 ''; 188 }; 189 }; 190 }; 191 }; 192 }; 193 194 systemd = { 195 services = { 196 part-db-migrate = { 197 before = [ "phpfpm-part-db.service" ]; 198 after = [ "postgresql.service" ]; 199 requires = [ "postgresql.service" ]; 200 wantedBy = [ "multi-user.target" ]; 201 serviceConfig = { 202 Type = "oneshot"; 203 RemainAfterExit = true; 204 User = "part-db"; 205 }; 206 restartTriggers = [ 207 cfg.package 208 ]; 209 script = '' 210 set -euo pipefail 211 ${lib.getExe cfg.phpPackage} ${lib.getExe' cfg.package "console"} doctrine:migrations:migrate --no-interaction 212 ''; 213 }; 214 215 phpfpm-part-db = { 216 after = [ "part-db-migrate.service" ]; 217 requires = [ 218 "part-db-migrate.service" 219 "postgresql.service" 220 ]; 221 # ensure nginx can access the php-fpm socket 222 postStart = '' 223 ${lib.getExe' pkgs.acl "setfacl"} -m 'u:${config.services.nginx.user}:rw' ${config.services.phpfpm.pools.part-db.socket} 224 ''; 225 }; 226 }; 227 228 tmpfiles.settings."part-db" = { 229 "/var/cache/part-db/".d = { 230 mode = "0750"; 231 user = "part-db"; 232 group = "part-db"; 233 }; 234 "/var/lib/part-db/env.local"."L+" = { 235 argument = "${pkgs.writeText "part-db-env" ( 236 lib.concatStringsSep "\n" (lib.mapAttrsToList (key: value: "${key}=\"${value}\"") cfg.settings) 237 )}"; 238 }; 239 "/var/log/part-db/".d = { 240 mode = "0750"; 241 user = "part-db"; 242 group = "part-db"; 243 }; 244 }; 245 }; 246 }; 247}