feat: add firefly-iii to winters

This commit is contained in:
Leon Schwarzäugl 2025-06-12 21:19:05 +02:00
parent 2386303317
commit 3efa748383
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
12 changed files with 817 additions and 373 deletions

View file

@ -371,19 +371,20 @@ In this section I am creating some attributes that define general concepts of my
in in
{ {
default = pkgs.mkShell { default = pkgs.mkShell {
# plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
# buildInputs = [pkgs.nixVersions.latest pkgs.boost];
# patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
# })}/lib/nix/plugins
NIX_CONFIG = '' NIX_CONFIG = ''
plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: { plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
buildInputs = [pkgs.nixVersions.latest pkgs.boost];
patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
})}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix} extra-builtins-file = ${self + /nix/extra-builtins.nix}
''; '';
inherit (checks.pre-commit-check) shellHook; inherit (checks.pre-commit-check) shellHook;
buildInputs = checks.pre-commit-check.enabledPackages; buildInputs = checks.pre-commit-check.enabledPackages;
nativeBuildInputs = [ nativeBuildInputs = [
# (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions. (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
pkgs.nix # pkgs.nix
pkgs.home-manager pkgs.home-manager
pkgs.git pkgs.git
pkgs.just pkgs.just
@ -1275,7 +1276,7 @@ This machine mainly acts as an external sync helper. It manages the following th
All of these are processes that use little cpu but can take a lot of storage. For this I use a free Ampere instance from OCI with 50G of space. In case my account gets terminated, all of this data is easily replaceable or backed up regularly anyways. All of these are processes that use little cpu but can take a lot of storage. For this I use a free Ampere instance from OCI with 50G of space. In case my account gets terminated, all of this data is easily replaceable or backed up regularly anyways.
#+begin_src nix :tangle hosts/nixos/sync/default.nix #+begin_src nix :tangle hosts/nixos/sync/default.nix
{ lib, primaryUser, ... }: { lib, config, primaryUser, ... }:
let let
sharedOptions = { sharedOptions = {
isBtrfs = false; isBtrfs = false;
@ -1327,6 +1328,8 @@ This machine mainly acts as an external sync helper. It manages the following th
system.stateVersion = "23.11"; system.stateVersion = "23.11";
node.secretsDir = ./secrets;
services = { services = {
nginx = { nginx = {
virtualHosts = { virtualHosts = {
@ -4274,6 +4277,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a
freshrss = lib.mkDefault true; freshrss = lib.mkDefault true;
jenkins = lib.mkDefault false; jenkins = lib.mkDefault false;
kanidm = lib.mkDefault true; kanidm = lib.mkDefault true;
firefly = lib.mkDefault true;
}; };
}; };
}; };
@ -4293,7 +4297,7 @@ Modules that need to be loaded on the NixOS level. Note that these will not be a
modules = { modules = {
general = lib.mkDefault true; general = lib.mkDefault true;
nix-ld = lib.mkDefault true; nix-ld = lib.mkDefault true;
pii = lib.mkDefault true; pii = lib.mkDefault true;
home-manager = lib.mkDefault true; home-manager = lib.mkDefault true;
home-managerExtra = lib.mkDefault true; home-managerExtra = lib.mkDefault true;
xserver = lib.mkDefault true; xserver = lib.mkDefault true;
@ -4576,6 +4580,15 @@ TODO
} }
); );
# mkUser = name: {
# config.users.users.${name} = {
# group = name;
# isSystemUser = true;
# };
# config.users.groups.${name} = {};
# };
mkTrueOption = lib.mkOption { mkTrueOption = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;
@ -4849,29 +4862,30 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne
#+begin_src nix :tangle modules/nixos/common/sharedsetup.nix #+begin_src nix :tangle modules/nixos/common/sharedsetup.nix
{ lib, ... }: { lib, ... }:
{ {
options.swarselsystems = { options = {
withHomeManager = lib.mkOption { swarselsystems = {
type = lib.types.bool; withHomeManager = lib.mkOption {
default = true; type = lib.types.bool;
}; default = true;
isSwap = lib.mkOption { };
type = lib.types.bool; isSwap = lib.mkOption {
default = true; type = lib.types.bool;
}; default = true;
swapSize = lib.mkOption { };
type = lib.types.str; swapSize = lib.mkOption {
default = "8G"; type = lib.types.str;
}; default = "8G";
rootDisk = lib.mkOption { };
type = lib.types.str; rootDisk = lib.mkOption {
default = ""; type = lib.types.str;
}; default = "";
isCrypted = lib.mkEnableOption "uses full disk encryption"; };
initialSetup = lib.mkEnableOption "initial setup (no sops keys available)"; isCrypted = lib.mkEnableOption "uses full disk encryption";
initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
isImpermanence = lib.mkEnableOption "use impermanence on this system";
isSecureBoot = lib.mkEnableOption "use secure boot on this system";
isImpermanence = lib.mkEnableOption "use impermanence on this system";
isSecureBoot = lib.mkEnableOption "use secure boot on this system";
};
globals = lib.mkOption { globals = lib.mkOption {
default = { }; default = { };
type = lib.types.submodule { type = lib.types.submodule {
@ -4895,10 +4909,15 @@ I usually use =mutableUsers = false= in my NixOS configuration. However, on a ne
description = "My main domain."; description = "My main domain.";
}; };
}; };
}; };
}; };
}; };
# _globalsDefs = lib.mkOption {
# type = lib.types.unspecified;
# default = options.globals.definitions;
# readOnly = true;
# internal = true;
# };
}; };
} }
#+end_src #+end_src
@ -7919,11 +7938,15 @@ Also I install Tika and Gotenberg, which are needed to create PDFs out of =.eml=
gotenberg = { gotenberg = {
enable = true; enable = true;
package = pkgs.stable.gotenberg;
port = 3002; port = 3002;
bindIP = "127.0.0.1"; bindIP = "127.0.0.1";
timeout = "600s";
chromium.package = pkgs.stable.chromium;
}; };
}; };
# Add secret to PAPERLESS_SOCIALACCOUNT_PROVIDERS # Add secret to PAPERLESS_SOCIALACCOUNT_PROVIDERS
systemd.services.paperless-web.script = lib.mkBefore '' systemd.services.paperless-web.script = lib.mkBefore ''
oidcSecret=$(< ${config.sops.secrets.kanidm-paperless-client.path}) oidcSecret=$(< ${config.sops.secrets.kanidm-paperless-client.path})
@ -8623,7 +8646,7 @@ I am using this with CapyReader on my phone, set it up as a FreshRSS account wit
enable = true; enable = true;
virtualHost = "signpost.swarsel.win"; virtualHost = "signpost.swarsel.win";
baseUrl = "https://signpost.swarsel.win"; baseUrl = "https://signpost.swarsel.win";
authType = "none"; authType = "form";
dataDir = "/Vault/data/tt-rss"; dataDir = "/Vault/data/tt-rss";
defaultUser = "Swarsel"; defaultUser = "Swarsel";
passwordFile = config.sops.secrets.fresh.path; passwordFile = config.sops.secrets.fresh.path;
@ -8647,11 +8670,15 @@ I am using this with CapyReader on my phone, set it up as a FreshRSS account wit
# pass information via X-User and X-Email headers to backend, # pass information via X-User and X-Email headers to backend,
# requires running with --set-xauthrequest flag (done by NixOS) # requires running with --set-xauthrequest flag (done by NixOS)
auth_request_set $user $upstream_http_x_auth_request_preferred_username; auth_request_set $user $upstream_http_x_auth_request_user;
# Set the email to our own domain in case user change their mail auth_request_set $email $upstream_http_x_auth_request_email;
auth_request_set $email "''${upstream_http_x_auth_request_preferred_username}@swarsel.win";
proxy_set_header X-User $user; proxy_set_header X-User $user;
proxy_set_header X-Email $email; proxy_set_header X-Email $email;
proxy_set_header Remote-User $user;
# if you enabled --pass-access-token, this will pass the token to the backend
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
# if you enabled --cookie-refresh, this is needed for it to work with auth_request # if you enabled --cookie-refresh, this is needed for it to work with auth_request
auth_request_set $auth_cookie $upstream_http_set_cookie; auth_request_set $auth_cookie $upstream_http_set_cookie;
@ -8980,6 +9007,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
"nextcloud.admins" = { }; "nextcloud.admins" = { };
"navidrome.access" = { }; "navidrome.access" = { };
"freshrss.access" = { }; "freshrss.access" = { };
"firefly.access" = { };
}; };
persons = { persons = {
swarsel = { swarsel = {
@ -8994,6 +9022,7 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
"nextcloud.access" "nextcloud.access"
"freshrss.access" "freshrss.access"
"navidrome.access" "navidrome.access"
"firefly.access"
]; ];
displayName = "Swarsel"; displayName = "Swarsel";
}; };
@ -9106,21 +9135,31 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback"; originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
originLanding = "https://${oauth2ProxyDomain}/"; originLanding = "https://${oauth2ProxyDomain}/";
basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path; basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path;
scopeMaps."freshrss.access" = [ scopeMaps = {
"openid" "freshrss.access" = [
"email" "openid"
"profile" "email"
]; "profile"
scopeMaps."navidrome.access" = [ ];
"openid" "navidrome.access" = [
"email" "openid"
"profile" "email"
]; "profile"
];
"firefly.access" = [
"openid"
"email"
"profile"
];
};
preferShortUsername = true; preferShortUsername = true;
claimMaps.groups = { claimMaps.groups = {
joinType = "array"; joinType = "array";
valuesByGroup."freshrss.access" = [ "ttrss_access" ]; valuesByGroup = {
valuesByGroup."navidrome.access" = [ "navidrome_access" ]; "freshrss.access" = [ "ttrss_access" ];
"navidrome.access" = [ "navidrome_access" ];
"firefly.access" = [ "firefly_access" ];
};
}; };
}; };
}; };
@ -9223,6 +9262,117 @@ To get other URLs (token, etc.), use https://<kanidmDomain>/oauth2/openid/<clien
} }
#+end_src #+end_src
**** Firefly-III
#+begin_src nix :tangle modules/nixos/server/firefly-iii.nix
{ lib, config, ... }:
let
cfg = config.services.firefly-iii;
fireflyDomain = "stonks.swarsel.win";
fireflyUser = "firefly-iii";
in
{
options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
config = lib.mkIf config.swarselsystems.modules.server.firefly {
users.users.firefly-iii = {
group = "nginx";
isSystemUser = true;
};
sops = {
secrets = {
"firefly-iii-app-key" = { owner = fireflyUser; group = "nginx"; mode = "0440"; };
};
};
services = {
firefly-iii = {
enable = true;
user = fireflyUser;
group = if cfg.enableNginx then "nginx" else fireflyUser;
dataDir = "/Vault/data/firefly-iii";
settings = {
TZ = config.repo.secrets.common.location.timezone;
APP_URL = "https://${fireflyDomain}";
APP_KEY_FILE = config.sops.secrets.firefly-iii-app-key.path;
APP_ENV = "local";
DB_CONNECTION = "sqlite";
# AUTHENTICATION_GUARD = "remote_user_guard";
# AUTHENTICATION_GUARD_HEADER = "X-User";
# AUTHENTICATION_GUARD_EMAIL = "X-Email";
};
enableNginx = true;
virtualHost = fireflyDomain;
};
nginx = {
virtualHosts = {
"${fireflyDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
# main config is automatically added by nixos firefly config.
# hence, only provide certificate
locations = {
"/" = {
extraConfig = ''
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
# pass information via X-User and X-Email headers to backend,
# requires running with --set-xauthrequest flag (done by NixOS)
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
# if you enabled --pass-access-token, this will pass the token to the backend
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
'';
};
"/oauth2/" = {
proxyPass = "http://oauth2-proxy";
extraConfig = ''
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
'';
};
"= /oauth2/auth" = {
proxyPass = "http://oauth2-proxy/oauth2/auth";
extraConfig = ''
internal;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
'';
};
"/api" = {
extraConfig = ''
index index.php;
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
proxy_set_header X-User "";
proxy_set_header X-Email "";
'';
};
};
};
};
};
};
};
}
#+end_src
*** Darwin *** Darwin
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: h:ac0cd8b3-06cf-4dca-ba73-6100c8fedb47 :CUSTOM_ID: h:ac0cd8b3-06cf-4dca-ba73-6100c8fedb47

View file

@ -128,19 +128,20 @@
in in
{ {
default = pkgs.mkShell { default = pkgs.mkShell {
# plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: {
# buildInputs = [pkgs.nixVersions.latest pkgs.boost];
# patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
# })}/lib/nix/plugins
NIX_CONFIG = '' NIX_CONFIG = ''
plugin-files = ${pkgs.nix-plugins.overrideAttrs (o: { plugin-files = ${pkgs.nix-plugins}/lib/nix/plugins
buildInputs = [pkgs.nixVersions.latest pkgs.boost];
patches = (o.patches or []) ++ [ "${self}/nix/nix-plugins.patch" ];
})}/lib/nix/plugins
extra-builtins-file = ${self + /nix/extra-builtins.nix} extra-builtins-file = ${self + /nix/extra-builtins.nix}
''; '';
inherit (checks.pre-commit-check) shellHook; inherit (checks.pre-commit-check) shellHook;
buildInputs = checks.pre-commit-check.enabledPackages; buildInputs = checks.pre-commit-check.enabledPackages;
nativeBuildInputs = [ nativeBuildInputs = [
# (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions. (builtins.trace "alarm: we pinned nix_2_24 because of https://github.com/shlevy/nix-plugins/issues/20" pkgs.nixVersions.nix_2_24) # Always use the nix version from this flake's nixpkgs version, so that nix-plugins (below) doesn't fail because of different nix versions.
pkgs.nix # pkgs.nix
pkgs.home-manager pkgs.home-manager
pkgs.git pkgs.git
pkgs.just pkgs.just

View file

@ -1,4 +1,4 @@
{ lib, primaryUser, ... }: { lib, config, primaryUser, ... }:
let let
sharedOptions = { sharedOptions = {
isBtrfs = false; isBtrfs = false;
@ -50,6 +50,8 @@ in
system.stateVersion = "23.11"; system.stateVersion = "23.11";
node.secretsDir = ./secrets;
services = { services = {
nginx = { nginx = {
virtualHosts = { virtualHosts = {

File diff suppressed because it is too large Load diff

View file

@ -26,6 +26,15 @@ in
} }
); );
# mkUser = name: {
# config.users.users.${name} = {
# group = name;
# isSystemUser = true;
# };
# config.users.groups.${name} = {};
# };
mkTrueOption = lib.mkOption { mkTrueOption = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = true; default = true;

View file

@ -1,28 +1,29 @@
{ lib, ... }: { lib, ... }:
{ {
options.swarselsystems = { options = {
withHomeManager = lib.mkOption { swarselsystems = {
type = lib.types.bool; withHomeManager = lib.mkOption {
default = true; type = lib.types.bool;
}; default = true;
isSwap = lib.mkOption { };
type = lib.types.bool; isSwap = lib.mkOption {
default = true; type = lib.types.bool;
}; default = true;
swapSize = lib.mkOption { };
type = lib.types.str; swapSize = lib.mkOption {
default = "8G"; type = lib.types.str;
}; default = "8G";
rootDisk = lib.mkOption { };
type = lib.types.str; rootDisk = lib.mkOption {
default = ""; type = lib.types.str;
}; default = "";
isCrypted = lib.mkEnableOption "uses full disk encryption"; };
initialSetup = lib.mkEnableOption "initial setup (no sops keys available)"; isCrypted = lib.mkEnableOption "uses full disk encryption";
initialSetup = lib.mkEnableOption "initial setup (no sops keys available)";
isImpermanence = lib.mkEnableOption "use impermanence on this system";
isSecureBoot = lib.mkEnableOption "use secure boot on this system";
isImpermanence = lib.mkEnableOption "use impermanence on this system";
isSecureBoot = lib.mkEnableOption "use secure boot on this system";
};
globals = lib.mkOption { globals = lib.mkOption {
default = { }; default = { };
type = lib.types.submodule { type = lib.types.submodule {
@ -46,9 +47,14 @@
description = "My main domain."; description = "My main domain.";
}; };
}; };
}; };
}; };
}; };
# _globalsDefs = lib.mkOption {
# type = lib.types.unspecified;
# default = options.globals.definitions;
# readOnly = true;
# internal = true;
# };
}; };
} }

View file

@ -0,0 +1,106 @@
{ lib, config, ... }:
let
cfg = config.services.firefly-iii;
fireflyDomain = "stonks.swarsel.win";
fireflyUser = "firefly-iii";
in
{
options.swarselsystems.modules.server.firefly = lib.mkEnableOption "enable firefly-iii on server";
config = lib.mkIf config.swarselsystems.modules.server.firefly {
users.users.firefly-iii = {
group = "nginx";
isSystemUser = true;
};
sops = {
secrets = {
"firefly-iii-app-key" = { owner = fireflyUser; group = "nginx"; mode = "0440"; };
};
};
services = {
firefly-iii = {
enable = true;
user = fireflyUser;
group = if cfg.enableNginx then "nginx" else fireflyUser;
dataDir = "/Vault/data/firefly-iii";
settings = {
TZ = config.repo.secrets.common.location.timezone;
APP_URL = "https://${fireflyDomain}";
APP_KEY_FILE = config.sops.secrets.firefly-iii-app-key.path;
APP_ENV = "local";
DB_CONNECTION = "sqlite";
# AUTHENTICATION_GUARD = "remote_user_guard";
# AUTHENTICATION_GUARD_HEADER = "X-User";
# AUTHENTICATION_GUARD_EMAIL = "X-Email";
};
enableNginx = true;
virtualHost = fireflyDomain;
};
nginx = {
virtualHosts = {
"${fireflyDomain}" = {
enableACME = true;
forceSSL = true;
acmeRoot = null;
# main config is automatically added by nixos firefly config.
# hence, only provide certificate
locations = {
"/" = {
extraConfig = ''
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
# pass information via X-User and X-Email headers to backend,
# requires running with --set-xauthrequest flag (done by NixOS)
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
proxy_set_header X-User $user;
proxy_set_header X-Email $email;
# if you enabled --pass-access-token, this will pass the token to the backend
auth_request_set $token $upstream_http_x_auth_request_access_token;
proxy_set_header X-Access-Token $token;
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
auth_request_set $auth_cookie $upstream_http_set_cookie;
add_header Set-Cookie $auth_cookie;
'';
};
"/oauth2/" = {
proxyPass = "http://oauth2-proxy";
extraConfig = ''
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
'';
};
"= /oauth2/auth" = {
proxyPass = "http://oauth2-proxy/oauth2/auth";
extraConfig = ''
internal;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
'';
};
"/api" = {
extraConfig = ''
index index.php;
try_files $uri $uri/ /index.php?$query_string;
add_header Access-Control-Allow-Methods 'GET, POST, HEAD, OPTIONS';
proxy_set_header X-User "";
proxy_set_header X-Email "";
'';
};
};
};
};
};
};
};
}

View file

@ -82,6 +82,7 @@ in
"nextcloud.admins" = { }; "nextcloud.admins" = { };
"navidrome.access" = { }; "navidrome.access" = { };
"freshrss.access" = { }; "freshrss.access" = { };
"firefly.access" = { };
}; };
persons = { persons = {
swarsel = { swarsel = {
@ -96,6 +97,7 @@ in
"nextcloud.access" "nextcloud.access"
"freshrss.access" "freshrss.access"
"navidrome.access" "navidrome.access"
"firefly.access"
]; ];
displayName = "Swarsel"; displayName = "Swarsel";
}; };
@ -208,21 +210,31 @@ in
originUrl = "https://${oauth2ProxyDomain}/oauth2/callback"; originUrl = "https://${oauth2ProxyDomain}/oauth2/callback";
originLanding = "https://${oauth2ProxyDomain}/"; originLanding = "https://${oauth2ProxyDomain}/";
basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path; basicSecretFile = config.sops.secrets.kanidm-oauth2-proxy.path;
scopeMaps."freshrss.access" = [ scopeMaps = {
"openid" "freshrss.access" = [
"email" "openid"
"profile" "email"
]; "profile"
scopeMaps."navidrome.access" = [ ];
"openid" "navidrome.access" = [
"email" "openid"
"profile" "email"
]; "profile"
];
"firefly.access" = [
"openid"
"email"
"profile"
];
};
preferShortUsername = true; preferShortUsername = true;
claimMaps.groups = { claimMaps.groups = {
joinType = "array"; joinType = "array";
valuesByGroup."freshrss.access" = [ "ttrss_access" ]; valuesByGroup = {
valuesByGroup."navidrome.access" = [ "navidrome_access" ]; "freshrss.access" = [ "ttrss_access" ];
"navidrome.access" = [ "navidrome_access" ];
"firefly.access" = [ "firefly_access" ];
};
}; };
}; };
}; };

View file

@ -65,11 +65,15 @@
gotenberg = { gotenberg = {
enable = true; enable = true;
package = pkgs.stable.gotenberg;
port = 3002; port = 3002;
bindIP = "127.0.0.1"; bindIP = "127.0.0.1";
timeout = "600s";
chromium.package = pkgs.stable.chromium;
}; };
}; };
# Add secret to PAPERLESS_SOCIALACCOUNT_PROVIDERS # Add secret to PAPERLESS_SOCIALACCOUNT_PROVIDERS
systemd.services.paperless-web.script = lib.mkBefore '' systemd.services.paperless-web.script = lib.mkBefore ''
oidcSecret=$(< ${config.sops.secrets.kanidm-paperless-client.path}) oidcSecret=$(< ${config.sops.secrets.kanidm-paperless-client.path})

View file

@ -36,6 +36,7 @@
freshrss = lib.mkDefault true; freshrss = lib.mkDefault true;
jenkins = lib.mkDefault false; jenkins = lib.mkDefault false;
kanidm = lib.mkDefault true; kanidm = lib.mkDefault true;
firefly = lib.mkDefault true;
}; };
}; };
}; };

View file

@ -1,5 +1,5 @@
{ {
"data": "ENC[AES256_GCM,data:t46tqCQNV0Anyt3ZhfoFA6HnSC7ECCjbsdMAGQ+Xno4BjBFXBJdhcKuEdfqqKylBberfQ5zpS7PI9TWUrhjJdQJq8uC7pMcLK652OjAJAdxHaHAt2eBPq2+UXAHvwzXwEauEZ78m7iv0VuFvN9pLbUBVDGFRdWLrt32DD2xVASLSscn/wpYnXhBrd+fi9nKtt41mhe8UvAEIxdYtIEh4/ylL3PjvCEJBBEci7Fe/UuokNxhlMNc2xV0AVo25aM3mQbXny8LPF5++PVteVr4RWHm9R1qtRR8cKmJI/j2ObwS5WSsnRAJHgO6b6Wq9F4SNdEFscqW7d8/WWBPTvv+H3VSQ3K0xxaOrbnJYxBbSAboTDZogkbYSrY41SXqXh1Gorvh92eCvYCSxTFLnbkKVx3F35+3NKYK8RQ0OYsIl+k8qE9kK35kNjXrm3gl7p/WjyDXJ2mhHmt5ZQSleseh4meOhg73kJFC+VeUlI5no+kDeaYwn5EM/pi/ZzsAQwq/wGqVrPgSVnTbyfBAD1FRqeUxNCo2ceTGW12ZvOvm+XxUJ8tVef2PvUuqKvg1Xx4TN3hRQUcYhXwZWzKgseiAonRA4Euzs/BKA5K233uP22t8klCy23Ngti0LJt5tbmsNeBBwb2f5Wcs4oDn2YIFTm9Bg9QLbfkYyZf/ZkbA0U7HfbvhlIKANmzy1G8+MYlpS4ZED36wT1fEDcEBVygzyHVx9sXEZuj6Nm1ekxSGgJciVL,iv:PBwZiNQjDguQF/GFegm1oVYHF0lG6fjK0vxBuQN1HFo=,tag:VH2pH+rKgyBSIzGo8py6bw==,type:str]", "data": "ENC[AES256_GCM,data:lLLUOryVRlriVc94mUX486tGhdg3yO6MkVf43hQIfo9mmYks0NbvCb05VeN/zzVP5fZU4kX/KKA5gfpK8lPKnnE0eN0Tv98hfkAExH1zTowUaj+XcXOPmCyRydeKm04sITDPsuhH7c6jkk2RNXBF/3ER8VZ3uho0K1gqokJlQUcA3QPCDFh6t5jlJakB2AX0rQYBtlG/QfLMf1YqU+hMsOFSrEXkPL7B1FwTkOHlU3oefpia1h4OJBJEjXQW+e57zgPRqc7z9lT8sOsXKRldWXgb1bhQM6MTDbSnEkSE44EtsFefkrmU34riu0KjQMcDbDFH3NpNibtKammlHBaKEWrxyFsgEEnFtqpMrr/ageW+DIttHIEbO170PHyaExo2pw1if0x/kRMe9/aPdDbG4oXtoZ9WqqB/ziBVTy+rau/aeuBU5XOEF+iQGwlkdQcjaUv55VVaCrT1DLSLdfWj5bmlls2pgu3SRkqhRFa+QveFu8i80rLQT9KcELuGpx7AB8U7gz8Oz4pU0iZkH3A1Cw9sO2vjwPd2AnPi8YQsqCIGQtZp/Y/OJa/7GfPFmmJlWZFiFbKGUfZg6sPsLPyTqTzES0erf67dwpXaBtuz7iS1yS58HQwhT0ZdrRJdMsrg0j+rejYHdIbZeeRVRLoPastyHjVKTarrYtAeT3MuqKbqjQRTdoaNlOQovG8WBlPNRJ93qOWh0wLVYuD2ou3epDlwGbwIuJ8D/DbW5mWNw5gpbI50LC1+SM6/flb3iG7bJ5DmkA1c2+fm8Jm5me5SCCE=,iv:8VSsznbOJyV/ZYCP9hKuAprtjssYTQEjW0Z/P5fgYqw=,tag:Tc/N0KgF9sNHuTXjWKksUw==,type:str]",
"sops": { "sops": {
"age": [ "age": [
{ {
@ -23,8 +23,8 @@
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4bFIrQjZ5cUFBQUp4dTRW\ndEdaZys0OHE5L3BPaVNic3ZZRDQ5N09SaGdZCllhWnY4T2lLZzVUMlp5VjMvQ2lP\ndGFNSTBqbjNMaUcwbVRaWFVCazU3OEUKLS0tIHBIWUZCYjFDVDgzbUUxMC9TNzdp\naFdiWmV6TGIva0RNUDNHWmdJZGgzNHMKiIzjo6sH/SP12cAXTvXiP0X9EE/A8Qw1\nIfgZfyEHdf/Mxd/iNzlWb2Nb0MLerYYw/qZ/+L5eDpUr4Vl051qOXA==\n-----END AGE ENCRYPTED FILE-----\n" "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4bFIrQjZ5cUFBQUp4dTRW\ndEdaZys0OHE5L3BPaVNic3ZZRDQ5N09SaGdZCllhWnY4T2lLZzVUMlp5VjMvQ2lP\ndGFNSTBqbjNMaUcwbVRaWFVCazU3OEUKLS0tIHBIWUZCYjFDVDgzbUUxMC9TNzdp\naFdiWmV6TGIva0RNUDNHWmdJZGgzNHMKiIzjo6sH/SP12cAXTvXiP0X9EE/A8Qw1\nIfgZfyEHdf/Mxd/iNzlWb2Nb0MLerYYw/qZ/+L5eDpUr4Vl051qOXA==\n-----END AGE ENCRYPTED FILE-----\n"
} }
], ],
"lastmodified": "2025-06-11T12:35:26Z", "lastmodified": "2025-06-12T22:56:18Z",
"mac": "ENC[AES256_GCM,data:qySqNhw1CPbilUmJPSOsLGG3mbLrvPMXzkzUGIj5l1EBLl//BVfAqvkgc06AhjDexr708CyUU5tiW0JydFBkEcByxDK21JhnZGVTdiTidBUl5lS392bCxdnrWgNCm6BnIznLsF3UpuqStsztOgjRJa2pawC2b5i6VCm4asif2lQ=,iv:M0JEy5+8g2wesVMpfhl0OZOKh4MFnh6RwUm9tteSYJ4=,tag:2zxRZLab6Z5XDsh9MMHSlg==,type:str]", "mac": "ENC[AES256_GCM,data:KnewBjWIibq08JjmotKuJWJS6zqBWH7akh7a5nI3Sq6ae+QINN8M7ueTjdpbq1PqK9leiubbdECT4F/qHwpwmIKEB2vKY8eSsDsmjSmbtVFdYEv4UaOPEJAGr/8u3t7q97m+Ad2P+tLH/jIDc0BXGXYfQYogSiaHqKqytJK9cQo=,iv:8U6m1+00n1Aip08kO2Q0cdX/TnRy7Bpig7b23H6Plgg=,tag:UPskdkeO/qO7RkninZ4jow==,type:str]",
"pgp": [ "pgp": [
{ {
"created_at": "2025-06-11T01:05:00Z", "created_at": "2025-06-11T01:05:00Z",

View file

@ -63,6 +63,8 @@ kanidm-freshrss: ENC[AES256_GCM,data:4y0X3sSOfs5pKNCmZGJhxlAKH7GD1UACdw==,iv:LuQ
#ENC[AES256_GCM,data:8eDo+FQoBEKMTRY2,iv:ZSrV+Z+1S5AoW+jq49LBFzSwd/NJl3aZYHe7oUvGriU=,tag:3cw3hUigrPViQ+XsuMiksg==,type:comment] #ENC[AES256_GCM,data:8eDo+FQoBEKMTRY2,iv:ZSrV+Z+1S5AoW+jq49LBFzSwd/NJl3aZYHe7oUvGriU=,tag:3cw3hUigrPViQ+XsuMiksg==,type:comment]
oauth2-cookie-secret: ENC[AES256_GCM,data:l8BPYA7t9NG9MPFs/LDlFHqwbnwsvie7FM5v613358E+jLf2wD+tipyUb6c=,iv:1kZ6G6Z0cSQS53kc/hygh/1Ke491agWDlYHR9Yq0jT0=,tag:mi7Un2JBnrq1dnP3jZX4ng==,type:str] oauth2-cookie-secret: ENC[AES256_GCM,data:l8BPYA7t9NG9MPFs/LDlFHqwbnwsvie7FM5v613358E+jLf2wD+tipyUb6c=,iv:1kZ6G6Z0cSQS53kc/hygh/1Ke491agWDlYHR9Yq0jT0=,tag:mi7Un2JBnrq1dnP3jZX4ng==,type:str]
kanidm-oauth2-proxy-client: ENC[AES256_GCM,data:+mcA/sz3AZuw+I44iIdOEfDmtjEVdxi2fg==,iv:m4NpieUicS7xsR+F5AgPqkcUFRF+CGOA8IK6GeS9tgM=,tag:1wypxpiHPdQBD8Td/PSdMw==,type:str] kanidm-oauth2-proxy-client: ENC[AES256_GCM,data:+mcA/sz3AZuw+I44iIdOEfDmtjEVdxi2fg==,iv:m4NpieUicS7xsR+F5AgPqkcUFRF+CGOA8IK6GeS9tgM=,tag:1wypxpiHPdQBD8Td/PSdMw==,type:str]
#ENC[AES256_GCM,data:Y1BVSKrxqnK/8yk=,iv:Bg8OSExGPV9kwkuDb/69BXMyDnzbr1TAnVZEOxNWljo=,tag:Cq76DQ1g26pFLHwZP3pqYQ==,type:comment]
firefly-iii-app-key: ENC[AES256_GCM,data:hzgl8eRL0irNRP5TO7G1rNtNM7fXCkmbcaX4QoTsM0xA1rgyKwiy6a4lYDjoXZyOMy5p,iv:q5eepIELwIecyQ56A6THUOu+rebK3irKVYb7/gNHlU8=,tag:+M/KTX1JzPzXeK4TRzW42w==,type:str]
sops: sops:
age: age:
- recipient: age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63 - recipient: age1h72072slm2pthn9m2qwjsyy2dsazc6hz97kpzh4gksvv0r2jqecqul8w63
@ -74,8 +76,8 @@ sops:
MEZ1UWw3alF1WnJZMFZvMFBpbDFJZlUKGRnoEEgjgJ9SSblmldtY6d8MdAy01yxl MEZ1UWw3alF1WnJZMFZvMFBpbDFJZlUKGRnoEEgjgJ9SSblmldtY6d8MdAy01yxl
qkvEIoXbL+ky2ira7EgjD0legThzCnmlXUlcSn3SpwbkAGgcfd2kWA== qkvEIoXbL+ky2ira7EgjD0legThzCnmlXUlcSn3SpwbkAGgcfd2kWA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-06-09T19:50:17Z" lastmodified: "2025-06-12T18:54:27Z"
mac: ENC[AES256_GCM,data:Cx7bI5HRkVVmZTcs/Q3uPtLZaaGd28ZqUsyPRcqd8yEaRxNN0JU6EcQ2ZjU5Zi9jLRLDiR/PxuWsWcmDWH8vW0UZGh6ao75Cw3UO7QhKZHfM5cHqnleo/RIIl5d/Q0hnS9EQmcEPA3qKLQUIrOa+MAgMCkti50ZuNcZnkywLn54=,iv:QPDj4K22G6Go6RDE5ZGbCntmC+mn/5mMyH6ohyQYNuY=,tag:NJ3mjmo2LRmJRXKrYIJZKg==,type:str] mac: ENC[AES256_GCM,data:5SPDEOz+PBoavltKbVCAAFOexS3In1+jOUdP3V59ssWevKnxX09ALENfwQW4DkL/U4wrryKp9zQ1qmg43SPK2cWrbswsIhzupYE+VvhR3pORiCk/k3GhtE9jnQPD3W7WvNz29rMthgyo5AY/QERfd+YiuMLGmKofoqaWWpKnhRA=,iv:FTDBDKlRgUja5zRIzpO8d6IfCjvmMq1RDRSi3AfmB3A=,tag:zV0boAnx98PxgK1H3jRWOA==,type:str]
pgp: pgp:
- created_at: "2024-12-17T16:24:32Z" - created_at: "2024-12-17T16:24:32Z"
enc: |- enc: |-