1 { config, lib, pkgs, ... }:
6 cfg = config.services.grocy;
8 options.services.grocy = {
9 enable = mkEnableOption "grocy";
11 package = mkPackageOption pkgs "grocy" { };
16 FQDN for the grocy instance.
20 nginx.enableSSL = mkOption {
24 Whether or not to enable SSL (with ACME and let's encrypt)
29 phpfpm.settings = mkOption {
30 type = with types; attrsOf (oneOf [ int str bool ]);
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";
45 Options for grocy's PHPFPM pool.
51 default = "/var/lib/grocy";
53 Home directory of the `grocy` user which contains
54 the application's state.
64 ISO 4217 code for the currency to display.
69 type = types.enum [ "de" "en" "da" "en_GB" "es" "fr" "hu" "it" "nl" "no" "pl" "pt_BR" "ru" "sk_SK" "sv_SE" "tr" ];
72 Display language of the frontend.
77 showWeekNumber = mkOption {
81 Show the number of the weeks in the calendar views.
84 firstDayOfWeek = mkOption {
86 type = types.nullOr (types.enum (range 0 6));
88 Which day of the week (0=Sunday, 1=Monday etc.) should be the
96 config = mkIf cfg.enable {
97 environment.etc."grocy/config.php".text = ''
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});
105 users.users.grocy = {
112 systemd.tmpfiles.rules = map (
113 dirName: "d '${cfg.dataDir}/${dirName}' - grocy nginx - -"
114 ) [ "viewcache" "plugins" "settingoverrides" "storage" ];
116 services.phpfpm.pools.grocy = {
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;
124 inherit (cfg.phpfpm) settings;
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";
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" ];
141 rm -rf ${cfg.dataDir}/viewcache/*
147 virtualHosts."${cfg.hostName}" = mkMerge [
148 { root = "${cfg.package}/public";
149 locations."/".extraConfig = ''
150 rewrite ^ /index.php;
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;
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;
169 try_files $uri /index.php;
172 (mkIf cfg.nginx.enableSSL {
181 maintainers = with maintainers; [ n0emis ];