at 24.11-pre 5.4 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.grocy; 7in { 8 options.services.grocy = { 9 enable = mkEnableOption "grocy"; 10 11 package = mkPackageOption pkgs "grocy" { }; 12 13 hostName = mkOption { 14 type = types.str; 15 description = '' 16 FQDN for the grocy instance. 17 ''; 18 }; 19 20 nginx.enableSSL = mkOption { 21 type = types.bool; 22 default = true; 23 description = '' 24 Whether or not to enable SSL (with ACME and let's encrypt) 25 for the grocy vhost. 26 ''; 27 }; 28 29 phpfpm.settings = mkOption { 30 type = with types; attrsOf (oneOf [ int str bool ]); 31 default = { 32 "pm" = "dynamic"; 33 "php_admin_value[error_log]" = "stderr"; 34 "php_admin_flag[log_errors]" = true; 35 "listen.owner" = "nginx"; 36 "catch_workers_output" = true; 37 "pm.max_children" = "32"; 38 "pm.start_servers" = "2"; 39 "pm.min_spare_servers" = "2"; 40 "pm.max_spare_servers" = "4"; 41 "pm.max_requests" = "500"; 42 }; 43 44 description = '' 45 Options for grocy's PHPFPM pool. 46 ''; 47 }; 48 49 dataDir = mkOption { 50 type = types.str; 51 default = "/var/lib/grocy"; 52 description = '' 53 Home directory of the `grocy` user which contains 54 the application's state. 55 ''; 56 }; 57 58 settings = { 59 currency = mkOption { 60 type = types.str; 61 default = "USD"; 62 example = "EUR"; 63 description = '' 64 ISO 4217 code for the currency to display. 65 ''; 66 }; 67 68 culture = mkOption { 69 type = types.enum [ "de" "en" "da" "en_GB" "es" "fr" "hu" "it" "nl" "no" "pl" "pt_BR" "ru" "sk_SK" "sv_SE" "tr" ]; 70 default = "en"; 71 description = '' 72 Display language of the frontend. 73 ''; 74 }; 75 76 calendar = { 77 showWeekNumber = mkOption { 78 default = true; 79 type = types.bool; 80 description = '' 81 Show the number of the weeks in the calendar views. 82 ''; 83 }; 84 firstDayOfWeek = mkOption { 85 default = null; 86 type = types.nullOr (types.enum (range 0 6)); 87 description = '' 88 Which day of the week (0=Sunday, 1=Monday etc.) should be the 89 first day. 90 ''; 91 }; 92 }; 93 }; 94 }; 95 96 config = mkIf cfg.enable { 97 environment.etc."grocy/config.php".text = '' 98 <?php 99 Setting('CULTURE', '${cfg.settings.culture}'); 100 Setting('CURRENCY', '${cfg.settings.currency}'); 101 Setting('CALENDAR_FIRST_DAY_OF_WEEK', '${toString cfg.settings.calendar.firstDayOfWeek}'); 102 Setting('CALENDAR_SHOW_WEEK_OF_YEAR', ${boolToString cfg.settings.calendar.showWeekNumber}); 103 ''; 104 105 users.users.grocy = { 106 isSystemUser = true; 107 createHome = true; 108 home = cfg.dataDir; 109 group = "nginx"; 110 }; 111 112 systemd.tmpfiles.rules = map ( 113 dirName: "d '${cfg.dataDir}/${dirName}' - grocy nginx - -" 114 ) [ "viewcache" "plugins" "settingoverrides" "storage" ]; 115 116 services.phpfpm.pools.grocy = { 117 user = "grocy"; 118 group = "nginx"; 119 120 # PHP 8.1 and 8.2 are the only version which are supported/tested by upstream: 121 # https://github.com/grocy/grocy/blob/v4.0.2/README.md#platform-support 122 phpPackage = pkgs.php82; 123 124 inherit (cfg.phpfpm) settings; 125 126 phpEnv = { 127 GROCY_CONFIG_FILE = "/etc/grocy/config.php"; 128 GROCY_DB_FILE = "${cfg.dataDir}/grocy.db"; 129 GROCY_STORAGE_DIR = "${cfg.dataDir}/storage"; 130 GROCY_PLUGIN_DIR = "${cfg.dataDir}/plugins"; 131 GROCY_CACHE_DIR = "${cfg.dataDir}/viewcache"; 132 }; 133 }; 134 135 # After an update of grocy, the viewcache needs to be deleted. Otherwise grocy will not work 136 # https://github.com/grocy/grocy#how-to-update 137 systemd.services.grocy-setup = { 138 wantedBy = [ "multi-user.target" ]; 139 before = [ "phpfpm-grocy.service" ]; 140 script = '' 141 rm -rf ${cfg.dataDir}/viewcache/* 142 ''; 143 }; 144 145 services.nginx = { 146 enable = true; 147 virtualHosts."${cfg.hostName}" = mkMerge [ 148 { root = "${cfg.package}/public"; 149 locations."/".extraConfig = '' 150 rewrite ^ /index.php; 151 ''; 152 locations."~ \\.php$".extraConfig = '' 153 fastcgi_split_path_info ^(.+\.php)(/.+)$; 154 fastcgi_pass unix:${config.services.phpfpm.pools.grocy.socket}; 155 include ${config.services.nginx.package}/conf/fastcgi.conf; 156 include ${config.services.nginx.package}/conf/fastcgi_params; 157 ''; 158 locations."~ \\.(js|css|ttf|woff2?|png|jpe?g|svg)$".extraConfig = '' 159 add_header Cache-Control "public, max-age=15778463"; 160 add_header X-Content-Type-Options nosniff; 161 add_header X-XSS-Protection "1; mode=block"; 162 add_header X-Robots-Tag none; 163 add_header X-Download-Options noopen; 164 add_header X-Permitted-Cross-Domain-Policies none; 165 add_header Referrer-Policy no-referrer; 166 access_log off; 167 ''; 168 extraConfig = '' 169 try_files $uri /index.php; 170 ''; 171 } 172 (mkIf cfg.nginx.enableSSL { 173 enableACME = true; 174 forceSSL = true; 175 }) 176 ]; 177 }; 178 }; 179 180 meta = { 181 maintainers = with maintainers; [ n0emis ]; 182 doc = ./grocy.md; 183 }; 184}