9 cfg = config.services.firefly-iii-data-importer;
14 defaultUser = "firefly-iii-data-importer";
15 defaultGroup = "firefly-iii-data-importer";
17 artisan = "${cfg.package}/artisan";
19 env-file-values = lib.attrsets.mapAttrs' (
20 n: v: lib.attrsets.nameValuePair (lib.strings.removeSuffix "_FILE" n) v
21 ) (lib.attrsets.filterAttrs (n: v: lib.strings.hasSuffix "_FILE" n) cfg.settings);
22 env-nonfile-values = lib.attrsets.filterAttrs (n: v: !lib.strings.hasSuffix "_FILE" n) cfg.settings;
24 data-importer-maintenance = pkgs.writeShellScript "data-importer-maintenance.sh" ''
26 ${lib.strings.toShellVars env-nonfile-values}
27 ${lib.strings.concatLines (
28 lib.attrsets.mapAttrsToList (n: v: "${n}=\"$(< ${v})\"") env-file-values
31 ${artisan} package:discover
32 ${artisan} cache:clear
33 ${artisan} config:cache
36 commonServiceConfig = {
40 StateDirectory = "firefly-iii-data-importer";
41 ReadWritePaths = [ cfg.dataDir ];
42 WorkingDirectory = cfg.package;
44 PrivateDevices = true;
45 CapabilityBoundingSet = "";
46 AmbientCapabilities = "";
47 ProtectSystem = "strict";
48 ProtectKernelTunables = true;
49 ProtectKernelModules = true;
50 ProtectControlGroups = true;
52 ProtectHostname = true;
53 ProtectHome = "tmpfs";
54 ProtectKernelLogs = true;
55 ProtectProc = "invisible";
57 PrivateNetwork = false;
58 RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
59 SystemCallArchitectures = "native";
61 "@system-service @resources"
62 "~@obsolete @privileged"
64 RestrictSUIDSGID = true;
66 NoNewPrivileges = true;
67 RestrictRealtime = true;
68 RestrictNamespaces = true;
69 LockPersonality = true;
76 options.services.firefly-iii-data-importer = {
77 enable = lib.mkEnableOption "Firefly III Data Importer";
81 default = defaultUser;
82 description = "User account under which firefly-iii-data-importer runs.";
85 group = lib.mkOption {
87 default = if cfg.enableNginx then "nginx" else defaultGroup;
88 defaultText = "If `services.firefly-iii-data-importer.enableNginx` is true then `nginx` else ${defaultGroup}";
90 Group under which firefly-iii-data-importer runs. It is best to set this to the group
91 of whatever webserver is being used as the frontend.
95 dataDir = lib.mkOption {
96 type = lib.types.path;
97 default = "/var/lib/firefly-iii-data-importer";
99 The place where firefly-iii data importer stores its state.
103 package = lib.mkOption {
104 type = lib.types.package;
105 default = pkgs.firefly-iii-data-importer;
106 defaultText = lib.literalExpression "pkgs.firefly-iii-data-importer";
108 The firefly-iii-data-importer package served by php-fpm and the webserver of choice.
109 This option can be used to point the webserver to the correct root. It
110 may also be used to set the package to a different version, say a
114 firefly-iii-data-importer:
115 firefly-iii-data-importer.override (prev: {
116 dataDir = cfg.dataDir;
120 enableNginx = lib.mkOption {
121 type = lib.types.bool;
124 Whether to enable nginx or not. If enabled, an nginx virtual host will
125 be created for access to firefly-iii data importer. If not enabled, then you may use
126 `''${config.services.firefly-iii-data-importer.package}` as your document root in
127 whichever webserver you wish to setup.
131 virtualHost = lib.mkOption {
132 type = lib.types.str;
133 default = "localhost";
135 The hostname at which you wish firefly-iii-data-importer to be served. If you have
136 enabled nginx using `services.firefly-iii-data-importer.enableNginx` then this will
141 poolConfig = lib.mkOption {
142 type = lib.types.attrsOf (
150 defaultText = lib.literalExpression ''
153 "pm.max_children" = 32;
154 "pm.start_servers" = 2;
155 "pm.min_spare_servers" = 2;
156 "pm.max_spare_servers" = 4;
157 "pm.max_requests" = 500;
161 Options for the Firefly III Data Importer PHP pool. See the documentation on <literal>php-fpm.conf</literal>
162 for details on configuration directives.
166 settings = lib.mkOption {
169 Options for firefly-iii data importer configuration. Refer to
170 <https://github.com/firefly-iii/data-importer/blob/main/.env.example> for
171 details on supported values. All <option>_FILE values supported by
172 upstream are supported here.
174 APP_URL will be the same as `services.firefly-iii-data-importer.virtualHost` if the
175 former is unset in `services.firefly-iii-data-importer.settings`.
177 example = lib.literalExpression ''
180 LOG_CHANNEL = "syslog";
181 FIREFLY_III_ACCESS_TOKEN= = "/var/secrets/firefly-iii-access-token.txt";
184 type = lib.types.submodule {
185 freeformType = lib.types.attrsOf (
196 config = lib.mkIf cfg.enable {
197 services.phpfpm.pools.firefly-iii-data-importer = {
199 phpPackage = cfg.package.phpPackage;
204 "listen.mode" = "0660";
205 "listen.owner" = user;
206 "listen.group" = group;
207 "pm" = lib.mkDefault "dynamic";
208 "pm.max_children" = lib.mkDefault 32;
209 "pm.start_servers" = lib.mkDefault 2;
210 "pm.min_spare_servers" = lib.mkDefault 2;
211 "pm.max_spare_servers" = lib.mkDefault 4;
212 "pm.max_requests" = lib.mkDefault 500;
216 systemd.services.firefly-iii-data-importer-setup = {
217 requiredBy = [ "phpfpm-firefly-iii-data-importer.service" ];
218 before = [ "phpfpm-firefly-iii-data-importer.service" ];
220 ExecStart = data-importer-maintenance;
221 RemainAfterExit = true;
222 } // commonServiceConfig;
223 unitConfig.JoinsNamespaceOf = "phpfpm-firefly-iii-data-importer.service";
224 restartTriggers = [ cfg.package ];
227 services.nginx = lib.mkIf cfg.enableNginx {
229 recommendedTlsSettings = lib.mkDefault true;
230 recommendedOptimisation = lib.mkDefault true;
231 recommendedGzipSettings = lib.mkDefault true;
232 virtualHosts.${cfg.virtualHost} = {
233 root = "${cfg.package}/public";
236 tryFiles = "$uri $uri/ /index.php?$query_string";
244 include ${config.services.nginx.package}/conf/fastcgi_params ;
245 fastcgi_param SCRIPT_FILENAME $request_filename;
246 fastcgi_param modHeadersAvailable true;
247 fastcgi_pass unix:${config.services.phpfpm.pools.firefly-iii-data-importer.socket};
254 systemd.tmpfiles.settings."10-firefly-iii-data-importer" =
255 lib.attrsets.genAttrs
257 "${cfg.dataDir}/storage"
258 "${cfg.dataDir}/storage/app"
259 "${cfg.dataDir}/storage/app/public"
260 "${cfg.dataDir}/storage/configurations"
261 "${cfg.dataDir}/storage/conversion-routines"
262 "${cfg.dataDir}/storage/debugbar"
263 "${cfg.dataDir}/storage/framework"
264 "${cfg.dataDir}/storage/framework/cache"
265 "${cfg.dataDir}/storage/framework/sessions"
266 "${cfg.dataDir}/storage/framework/testing"
267 "${cfg.dataDir}/storage/framework/views"
268 "${cfg.dataDir}/storage/jobs"
269 "${cfg.dataDir}/storage/logs"
270 "${cfg.dataDir}/storage/submission-routines"
271 "${cfg.dataDir}/storage/uploads"
272 "${cfg.dataDir}/cache"
282 "${cfg.dataDir}".d = {
290 users = lib.mkIf (user == defaultUser) {
292 description = "Firefly-iii Data Importer service user";
298 groups = lib.mkIf (group == defaultGroup) { ${defaultGroup} = { }; };