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