firefly-iii-data-importer: init
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
# ../../services/llama-cpp.nix
|
# ../../services/llama-cpp.nix
|
||||||
../../services/trilium.nix
|
../../services/trilium.nix
|
||||||
../../services/firefly-iii.nix
|
../../services/firefly-iii.nix
|
||||||
|
../../services/firefly-iii-data-importer.nix
|
||||||
|
|
||||||
../../services/ups.nix
|
../../services/ups.nix
|
||||||
|
|
||||||
|
|||||||
@@ -340,6 +340,15 @@ rec {
|
|||||||
domain = "firefly.${site_config.domain}";
|
domain = "firefly.${site_config.domain}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
firefly_iii_data_importer = rec {
|
||||||
|
dataDir = services_dir + "/firefly-iii-data-importer";
|
||||||
|
domain = "firefly-import.${site_config.domain}";
|
||||||
|
# SimpleFIN config json the user uploads after first interactive setup.
|
||||||
|
# `JSON_CONFIGURATION_DIR` defaults to `<storage>/configurations` per the
|
||||||
|
# data-importer module's tmpfiles rules; we reuse that path.
|
||||||
|
simplefinConfigPath = "${dataDir}/storage/configurations/simplefin.json";
|
||||||
|
};
|
||||||
|
|
||||||
media = {
|
media = {
|
||||||
moviesDir = torrents_path + "/media/movies";
|
moviesDir = torrents_path + "/media/movies";
|
||||||
tvDir = torrents_path + "/media/tv";
|
tvDir = torrents_path + "/media/tv";
|
||||||
|
|||||||
@@ -199,5 +199,23 @@
|
|||||||
owner = "firefly-iii";
|
owner = "firefly-iii";
|
||||||
group = "caddy";
|
group = "caddy";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Firefly III Data Importer Laravel APP_KEY (base64:<32 random bytes>)
|
||||||
|
firefly-iii-data-importer-app-key = {
|
||||||
|
file = ../secrets/server/firefly-iii-data-importer-app-key.age;
|
||||||
|
mode = "0400";
|
||||||
|
owner = "firefly-iii-data-importer";
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
|
|
||||||
|
# Firefly III Personal Access Token used by the data importer (FIREFLY_III_ACCESS_TOKEN).
|
||||||
|
# First-deploy ciphertext is a placeholder string; rotate after creating
|
||||||
|
# the PAT in the Firefly UI (Profile → OAuth → Personal Access Tokens).
|
||||||
|
firefly-iii-fidi-token = {
|
||||||
|
file = ../secrets/server/firefly-iii-fidi-token.age;
|
||||||
|
mode = "0400";
|
||||||
|
owner = "firefly-iii-data-importer";
|
||||||
|
group = "caddy";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
BIN
secrets/server/firefly-iii-data-importer-app-key.age
Normal file
BIN
secrets/server/firefly-iii-data-importer-app-key.age
Normal file
Binary file not shown.
BIN
secrets/server/firefly-iii-fidi-token.age
Normal file
BIN
secrets/server/firefly-iii-fidi-token.age
Normal file
Binary file not shown.
128
services/firefly-iii-data-importer.nix
Normal file
128
services/firefly-iii-data-importer.nix
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
service_configs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
fidi = service_configs.firefly_iii_data_importer;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
# Same chicanery as services/firefly-iii.nix: the upstream module's
|
||||||
|
# actual systemd units are firefly-iii-data-importer-setup.service and
|
||||||
|
# phpfpm-firefly-iii-data-importer.service. Hook the zfs mount into the
|
||||||
|
# `-setup` unit; the upstream `requiredBy` chain pulls phpfpm forward.
|
||||||
|
(lib.serviceMountWithZpool "firefly-iii-data-importer-setup" service_configs.zpool_ssds [
|
||||||
|
fidi.dataDir
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
services.firefly-iii-data-importer = {
|
||||||
|
enable = true;
|
||||||
|
dataDir = fidi.dataDir;
|
||||||
|
# Same trick as firefly-iii: run as group caddy so caddy can read the
|
||||||
|
# php-fpm unix socket without us having to override `listen.group`.
|
||||||
|
group = "caddy";
|
||||||
|
virtualHost = fidi.domain;
|
||||||
|
settings = {
|
||||||
|
APP_ENV = "production";
|
||||||
|
APP_KEY_FILE = config.age.secrets.firefly-iii-data-importer-app-key.path;
|
||||||
|
LOG_CHANNEL = "syslog";
|
||||||
|
LOG_LEVEL = "info";
|
||||||
|
|
||||||
|
# Importer → Firefly III. The /etc/hosts override below pins this hostname
|
||||||
|
# to 127.0.0.1 on muffin so the importer's outbound HTTPS lands on the
|
||||||
|
# local Caddy without hairpinning through the WAN gateway. The TLS cert
|
||||||
|
# is the same wildcard Caddy serves externally, so verification works.
|
||||||
|
FIREFLY_III_URL = "https://${service_configs.firefly_iii.domain}";
|
||||||
|
FIREFLY_III_ACCESS_TOKEN_FILE = config.age.secrets.firefly-iii-fidi-token.path;
|
||||||
|
|
||||||
|
TRUSTED_PROXIES = "127.0.0.1,::1";
|
||||||
|
|
||||||
|
# SimpleFIN polls the last 90d every run; without this, every daily run
|
||||||
|
# logs hundreds of "duplicate transaction" warnings as Firefly's server-
|
||||||
|
# side dedup catches them. Firefly still rejects the duplicates; we just
|
||||||
|
# don't see the noise.
|
||||||
|
IGNORE_DUPLICATE_ERRORS = true;
|
||||||
|
|
||||||
|
# CLI-driven imports only. Leave the /autoimport HTTP endpoint disabled
|
||||||
|
# (default) — the systemd timer below uses `artisan importer:import`
|
||||||
|
# against a static config file, which avoids exposing another web-
|
||||||
|
# reachable surface that needs its own shared secret.
|
||||||
|
CAN_POST_AUTOIMPORT = false;
|
||||||
|
CAN_POST_FILES = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Pin the firefly-iii hostname to loopback on muffin so the importer's
|
||||||
|
# outbound API calls hit local Caddy directly. No effect on any other host.
|
||||||
|
networking.extraHosts = "127.0.0.1 ${service_configs.firefly_iii.domain}";
|
||||||
|
|
||||||
|
services.caddy.virtualHosts.${fidi.domain}.extraConfig = ''
|
||||||
|
encode zstd gzip
|
||||||
|
import ${config.age.secrets.caddy_auth.path}
|
||||||
|
|
||||||
|
root * ${config.services.firefly-iii-data-importer.package}/public
|
||||||
|
php_fastcgi unix/${config.services.phpfpm.pools.firefly-iii-data-importer.socket}
|
||||||
|
file_server
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Daily SimpleFIN import via the importer's CLI. The unit is gated by
|
||||||
|
# ConditionPathExists so it silently no-ops until the user has uploaded
|
||||||
|
# `simplefin.json` (per the post-deploy operational steps).
|
||||||
|
systemd.services.firefly-iii-data-importer-import = {
|
||||||
|
description = "Run scheduled Firefly III data importer config (SimpleFIN)";
|
||||||
|
after = [
|
||||||
|
"phpfpm-firefly-iii-data-importer.service"
|
||||||
|
"network-online.target"
|
||||||
|
];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
unitConfig.ConditionPathExists = fidi.simplefinConfigPath;
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
User = config.services.firefly-iii-data-importer.user;
|
||||||
|
Group = config.services.firefly-iii-data-importer.group;
|
||||||
|
WorkingDirectory = config.services.firefly-iii-data-importer.package;
|
||||||
|
ExecStart = "${config.services.firefly-iii-data-importer.package}/artisan importer:import ${fidi.simplefinConfigPath}";
|
||||||
|
# Same hardening posture as the upstream commonServiceConfig.
|
||||||
|
ReadWritePaths = [ fidi.dataDir ];
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
ProtectHome = "tmpfs";
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProcSubset = "pid";
|
||||||
|
RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX";
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
LockPersonality = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
RemoveIPC = true;
|
||||||
|
CapabilityBoundingSet = "";
|
||||||
|
AmbientCapabilities = "";
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service @resources"
|
||||||
|
"~@obsolete @privileged"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.timers.firefly-iii-data-importer-import = {
|
||||||
|
description = "Daily Firefly III SimpleFIN import";
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
RandomizedDelaySec = "1h";
|
||||||
|
Persistent = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user