vuls: init at 0.27.0 (#348530)
[NixPkgs.git] / nixos / modules / services / web-apps / grocy.nix
blobeb4feb191aa590aed3ecab299320a2931750b80b
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.grocy;
7 in {
8   options.services.grocy = {
9     enable = mkEnableOption "grocy";
11     package = mkPackageOption pkgs "grocy" { };
13     hostName = mkOption {
14       type = types.str;
15       description = ''
16         FQDN for the grocy instance.
17       '';
18     };
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     };
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       };
44       description = ''
45         Options for grocy's PHPFPM pool.
46       '';
47     };
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     };
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       };
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       };
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   };
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     '';
105     users.users.grocy = {
106       isSystemUser = true;
107       createHome = true;
108       home = cfg.dataDir;
109       group = "nginx";
110     };
112     systemd.tmpfiles.rules = map (
113       dirName: "d '${cfg.dataDir}/${dirName}' - grocy nginx - -"
114     ) [ "viewcache" "plugins" "settingoverrides" "storage" ];
116     services.phpfpm.pools.grocy = {
117       user = "grocy";
118       group = "nginx";
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;
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     };
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     };
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   };
180   meta = {
181     maintainers = with maintainers; [ n0emis ];
182     doc = ./grocy.md;
183   };