diff --git a/secrets.nix b/secrets.nix index 8042bf6..45783ee 100644 --- a/secrets.nix +++ b/secrets.nix @@ -34,7 +34,8 @@ in { ++ [ mcentire-host ]; "secrets/darwin-policies-json.age".publicKeys = system-administrators ++ [ corianne-host ]; + "secrets/freshrss.toml.age".publicKeys = system-administrators + ++ [ mcentire-host ]; "secrets/network-information.age".publicKeys = system-administrators ++ [ bosephus-host ]; - "secrets/pihole.age".publicKeys = system-administrators ++ [ bosephus-host ]; } diff --git a/secrets/freshrss.toml.age b/secrets/freshrss.toml.age new file mode 100644 index 0000000..9bfa06c Binary files /dev/null and b/secrets/freshrss.toml.age differ diff --git a/secrets/pihole.age b/secrets/pihole.age deleted file mode 100644 index 1b2bc25..0000000 Binary files a/secrets/pihole.age and /dev/null differ diff --git a/services/freshrss.nix b/services/freshrss.nix new file mode 100644 index 0000000..4832ebe --- /dev/null +++ b/services/freshrss.nix @@ -0,0 +1,136 @@ +{ config, pkgs, home-manager-quadlet-nix, ... }: + +let + user = "freshrss"; + port = "37374"; + stateDirectory = "/var/lib/freshrss"; + serviceContainer = "freshrss"; + stateSubDir = subDir: "${stateDirectory}/${subDir}"; + createTmpfilesRule = subDir: "d ${stateSubDir subDir} 1755 ${user} ${user}"; + volumeMount = subDir: bindDir: "${stateDirectory}/${subDir}:${bindDir}:U"; + + dbDirectories = [ "database" ]; + serviceDirectories = [ ]; +in { + age.secrets = { + "freshrss.toml" = { + file = ./../secrets/freshrss.toml.age; + owner = "${user}"; + }; + }; + + millironx.podman-secrets.freshrss = { + user = "${user}"; + secrets-files = [ config.age.secrets."freshrss.toml".path ]; + }; + + services.caddy.virtualHosts."feeds.millironx.com".extraConfig = '' + reverse_proxy http://127.0.0.1:${port} + ''; + + systemd.tmpfiles.rules = builtins.map createTmpfilesRule + ([ stateDirectory ] ++ dbDirectories ++ serviceDirectories); + + services.borgmatic.configurations."${config.networking.hostName}" = { + source_directories = builtins.map stateSubDir dbDirectories; + + name = serviceContainer; + psql_command = + "/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db psql --username=${user}"; + pg_dump_command = + "/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_dump --username=${user}"; + pg_restore_command = + "/run/wrappers/bin/sudo -iu ${user} ${pkgs.podman}/bin/podman exec ${serviceContainer}-db pg_restore --username=${user}"; + }; + + users.users."${user}" = { + group = "${user}"; + isNormalUser = true; + home = "${stateDirectory}"; + createHome = true; + linger = true; + autoSubUidGidRange = true; + }; + users.groups."${user}" = { }; + + home-manager.users."${user}" = { config, osConfig, ... }: { + imports = [ home-manager-quadlet-nix ]; + + home.stateVersion = "25.05"; + + virtualisation.quadlet = let + inherit (config.virtualisation.quadlet) containers; + inherit (config.virtualisation.quadlet) networks; + secrets = osConfig.millironx.podman-secrets.freshrss; + + in { + containers = { + "${serviceContainer}-db" = { + autoStart = true; + containerConfig = { + image = "docker.io/library/postgres:16"; + environments = { + POSTGRES_DB = "${user}"; + POSTGRES_USER = "${user}"; + }; + secrets = [ + "POSTGRES_PASSWORD,type=env" + "POSTGRES_PASSWORD,type=env,target=PGPASSWORD" + ]; + healthCmd = "pg_isready -d $\${POSTGRES_DB} -U $\${POSTGRES_USER}"; + healthInterval = "30s"; + healthRetries = 5; + healthStartPeriod = "20s"; + volumes = pkgs.lib.imap0 (i: sub: + volumeMount sub + (builtins.elemAt [ "/var/lib/postgresql/data" ] i)) dbDirectories; + networks = [ networks."${serviceContainer}".ref ]; + }; + unitConfig.Requires = [ secrets.ref ]; + unitConfig.After = [ secrets.ref ]; + }; + + "${serviceContainer}" = { + autoStart = true; + containerConfig = { + image = "docker.io/freshrss/freshrss:1"; + environments = { + TZ = osConfig.time.timeZone; + CRON_MIN = "2,32"; + LISTEN = "0.0.0.0:${port}"; + OIDC_ENABLED = "1"; + FRESHRSS_INSTALL = '' + --api-enabled + --base-url + --db-base $''${DB_BASE} + --db-host $''${DB_HOST} + --db-password $''${DB_PASSWORD} + --db-type pgsql + --db-user $''${DB_USER} + --default-user admin + --language en + ''; + }; + secrets = [ + "FRESHRSS_INSTALL,type=env" + "FRESHRSS_USER,type=env" + ]; + healthCmd = "cli/health.php"; + healthTimeout = "10s"; + healthStartPeriod = "60s"; + healthStartupInterval = "11s"; + healthInterval = "75s"; + healthRetries = 3; + networks = [networks."${serviceContainer}".ref]; + }; + unitConfig.Requires = [ containers."${serviceContainer}-db".ref ]; + unitConfig.After = [ containers."${serviceContainer}-db".ref ]; + }; + }; + + networks."${serviceContainer}" = {}; + + autoUpdate.enable = true; + }; + }; +}