diff --git a/modules/nixos/services/actual/default.nix b/modules/nixos/services/actual/default.nix index e291c81..decb389 100644 --- a/modules/nixos/services/actual/default.nix +++ b/modules/nixos/services/actual/default.nix @@ -8,68 +8,40 @@ with lib; let cfg = config.${namespace}.services.actual; - dataDir = "/data"; - hostAddress = "10.0.1.3"; - actualUserId = config.users.users.nix-apps.uid; - actualGroupId = config.users.groups.jallen-nas.gid; actualConfig = { services.actual = { enable = true; openFirewall = true; settings = { - trustedProxies = [ hostAddress ]; + trustedProxies = [ "10.0.1.3" ]; port = cfg.port; - dataDir = dataDir; - serverFiles = "${dataDir}/server-files"; - userFiles = "${dataDir}/user-files"; + dataDir = cfg.dataDir; + serverFiles = "${cfg.dataDir}/server-files"; + userFiles = "${cfg.dataDir}/user-files"; }; }; - users.users.actual = { - isSystemUser = true; - uid = lib.mkForce actualUserId; - group = "actual"; - }; - - users.groups = { - actual = { - gid = lib.mkForce actualGroupId; - }; - }; - - # System packages - environment.systemPackages = with pkgs; [ - sqlite - ]; - - # Create and set permissions for required directories - system.activationScripts.actual-dirs = '' - mkdir -p ${dataDir} - chown -R actual:actual ${dataDir} - chmod -R 0700 ${dataDir} - ''; - systemd.services = { actual = { - environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json"; + environment.ACTUAL_CONFIG_PATH = lib.mkForce "${cfg.dataDir}/config.json"; serviceConfig = { - ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${dataDir}/config.json"; - WorkingDirectory = lib.mkForce dataDir; - StateDirectory = lib.mkForce dataDir; + ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${cfg.dataDir}/config.json"; + WorkingDirectory = lib.mkForce cfg.dataDir; + StateDirectory = lib.mkForce cfg.dataDir; StateDirectoryMode = lib.mkForce 700; DynamicUser = lib.mkForce false; ProtectSystem = lib.mkForce null; }; }; }; - }; - bindMounts = { - "${dataDir}" = { - hostPath = cfg.dataDir; - isReadOnly = false; + users.users.actual = { + isSystemUser = true; + group = "actual"; + home = cfg.dataDir; }; + users.groups.actual = {}; }; # Create reverse proxy configuration using mkReverseProxy @@ -80,22 +52,12 @@ let middlewares = cfg.reverseProxy.middlewares; }; - actualContainer = - (lib.${namespace}.mkContainer { - name = "actual"; - localAddress = cfg.localAddress; - ports = [ cfg.port ]; - bindMounts = bindMounts; - config = actualConfig; - }) - { inherit lib; }; - fullConfig = { "${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable { reverseProxies = [ reverseProxyConfig ]; }; } - // actualContainer; + // actualConfig; in { imports = [ ./options.nix ]; diff --git a/modules/nixos/services/actual/default.nix.container b/modules/nixos/services/actual/default.nix.container new file mode 100644 index 0000000..e291c81 --- /dev/null +++ b/modules/nixos/services/actual/default.nix.container @@ -0,0 +1,104 @@ +{ + config, + pkgs, + lib, + namespace, + ... +}: +with lib; +let + cfg = config.${namespace}.services.actual; + dataDir = "/data"; + hostAddress = "10.0.1.3"; + actualUserId = config.users.users.nix-apps.uid; + actualGroupId = config.users.groups.jallen-nas.gid; + + actualConfig = { + services.actual = { + enable = true; + openFirewall = true; + settings = { + trustedProxies = [ hostAddress ]; + port = cfg.port; + dataDir = dataDir; + serverFiles = "${dataDir}/server-files"; + userFiles = "${dataDir}/user-files"; + }; + }; + + users.users.actual = { + isSystemUser = true; + uid = lib.mkForce actualUserId; + group = "actual"; + }; + + users.groups = { + actual = { + gid = lib.mkForce actualGroupId; + }; + }; + + # System packages + environment.systemPackages = with pkgs; [ + sqlite + ]; + + # Create and set permissions for required directories + system.activationScripts.actual-dirs = '' + mkdir -p ${dataDir} + chown -R actual:actual ${dataDir} + chmod -R 0700 ${dataDir} + ''; + + systemd.services = { + actual = { + environment.ACTUAL_CONFIG_PATH = lib.mkForce "${dataDir}/config.json"; + serviceConfig = { + ExecStart = lib.mkForce "${lib.getExe pkgs.actual-server} --config ${dataDir}/config.json"; + WorkingDirectory = lib.mkForce dataDir; + StateDirectory = lib.mkForce dataDir; + StateDirectoryMode = lib.mkForce 700; + DynamicUser = lib.mkForce false; + ProtectSystem = lib.mkForce null; + }; + }; + }; + }; + + bindMounts = { + "${dataDir}" = { + hostPath = cfg.dataDir; + isReadOnly = false; + }; + }; + + # Create reverse proxy configuration using mkReverseProxy + reverseProxyConfig = lib.${namespace}.mkReverseProxy { + name = "actual"; + subdomain = cfg.reverseProxy.subdomain; + url = "http://${cfg.localAddress}:${toString cfg.port}"; + middlewares = cfg.reverseProxy.middlewares; + }; + + actualContainer = + (lib.${namespace}.mkContainer { + name = "actual"; + localAddress = cfg.localAddress; + ports = [ cfg.port ]; + bindMounts = bindMounts; + config = actualConfig; + }) + { inherit lib; }; + + fullConfig = { + "${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable { + reverseProxies = [ reverseProxyConfig ]; + }; + } + // actualContainer; +in +{ + imports = [ ./options.nix ]; + + config = mkIf cfg.enable fullConfig; +} diff --git a/modules/nixos/services/jellyseerr/default.nix b/modules/nixos/services/jellyseerr/default.nix old mode 100755 new mode 100644 index 067ec06..95c2f3c --- a/modules/nixos/services/jellyseerr/default.nix +++ b/modules/nixos/services/jellyseerr/default.nix @@ -6,78 +6,46 @@ }: with lib; let + inherit (lib.${namespace}) mkOpt mkReverseProxyOpt; cfg = config.${namespace}.services.jellyseerr; jellyseerrPort = 5055; - dataDir = "/var/lib/private/jellyseerr"; in { - imports = [ ./options.nix ]; + options.${namespace}.services.jellyseerr = { + enable = mkEnableOption "enable jellyseerr"; + + port = mkOpt types.int 5055 "jellyseerr port"; + + dataDir = mkOpt types.str "" "data dir"; + }; config = mkIf cfg.enable { - containers.jellyseerr = { - autoStart = true; - privateNetwork = true; - hostAddress = "10.0.1.3"; - localAddress = "10.0.1.52"; - hostAddress6 = "fc00::1"; - localAddress6 = "fc00::4"; + # Enable jellyseerr service + services.jellyseerr = { + enable = true; + port = cfg.port; + openFirewall = true; + configDir = cfg.dataDir; + }; - bindMounts = { - ${dataDir} = { - hostPath = "/media/nas/main/nix-app-data/jellyseerr"; - isReadOnly = false; + systemd.services = { + jellyseerr = { + serviceConfig = { + WorkingDirectory = lib.mkForce cfg.dataDir; + StateDirectory = lib.mkForce cfg.dataDir; + StateDirectoryMode = lib.mkForce 700; + DynamicUser = lib.mkForce false; + ProtectSystem = lib.mkForce null; }; }; - - config = - { - lib, - ... - }: - { - # Enable jellyseerr service - services.jellyseerr = { - enable = true; - port = jellyseerrPort; - # package = package; - openFirewall = true; - }; - - networking = { - firewall = { - enable = true; - allowedTCPPorts = [ jellyseerrPort ]; - }; - # Use systemd-resolved inside the container - # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686 - useHostResolvConf = lib.mkForce false; - }; - - # Create and set permissions for required directories - system.activationScripts.jellyseerr-dirs = '' - mkdir -p /var/lib/private/jellyseerr - - chown -R jellyseerr:jellyseerr /var/lib/private/jellyseerr - - chmod -R 775 /var/lib/private/jellyseerr - - ln -sf /var/lib/private/jellyseerr /var/lib/jellyfin - - ''; - - services.resolved.enable = true; - system.stateVersion = "23.11"; - }; }; - networking.nat = { - forwardPorts = [ - { - destination = "10.0.1.52:5055"; - sourcePort = jellyseerrPort; - } - ]; + users.users.jellyseerr = { + isSystemUser = true; + group = "jellyseerr"; + home = cfg.dataDir; }; + users.groups.jellyseerr = {}; }; } diff --git a/modules/nixos/services/jellyseerr/default.nix.container b/modules/nixos/services/jellyseerr/default.nix.container new file mode 100755 index 0000000..067ec06 --- /dev/null +++ b/modules/nixos/services/jellyseerr/default.nix.container @@ -0,0 +1,83 @@ +{ + config, + lib, + namespace, + ... +}: +with lib; +let + cfg = config.${namespace}.services.jellyseerr; + + jellyseerrPort = 5055; + dataDir = "/var/lib/private/jellyseerr"; +in +{ + imports = [ ./options.nix ]; + + config = mkIf cfg.enable { + containers.jellyseerr = { + autoStart = true; + privateNetwork = true; + hostAddress = "10.0.1.3"; + localAddress = "10.0.1.52"; + hostAddress6 = "fc00::1"; + localAddress6 = "fc00::4"; + + bindMounts = { + ${dataDir} = { + hostPath = "/media/nas/main/nix-app-data/jellyseerr"; + isReadOnly = false; + }; + }; + + config = + { + lib, + ... + }: + { + # Enable jellyseerr service + services.jellyseerr = { + enable = true; + port = jellyseerrPort; + # package = package; + openFirewall = true; + }; + + networking = { + firewall = { + enable = true; + allowedTCPPorts = [ jellyseerrPort ]; + }; + # Use systemd-resolved inside the container + # Workaround for bug https://github.com/NixOS/nixpkgs/issues/162686 + useHostResolvConf = lib.mkForce false; + }; + + # Create and set permissions for required directories + system.activationScripts.jellyseerr-dirs = '' + mkdir -p /var/lib/private/jellyseerr + + chown -R jellyseerr:jellyseerr /var/lib/private/jellyseerr + + chmod -R 775 /var/lib/private/jellyseerr + + ln -sf /var/lib/private/jellyseerr /var/lib/jellyfin + + ''; + + services.resolved.enable = true; + system.stateVersion = "23.11"; + }; + }; + + networking.nat = { + forwardPorts = [ + { + destination = "10.0.1.52:5055"; + sourcePort = jellyseerrPort; + } + ]; + }; + }; +} diff --git a/modules/nixos/services/ntfy/default.nix b/modules/nixos/services/ntfy/default.nix index 67b69fd..70a690a 100644 --- a/modules/nixos/services/ntfy/default.nix +++ b/modules/nixos/services/ntfy/default.nix @@ -19,62 +19,52 @@ let base-url = "https://${cfg.reverseProxy.subdomain}.mjallen.dev"; enable-login = true; listen-http = ":${toString cfg.port}"; - cache-file = "/var/lib/ntfy-sh/cache.db"; - attachment-cache-dir = "/var/lib/ntfy-sh/attachments"; + cache-file = "${cfg.dataDir}/cache.db"; + attachment-cache-dir = "/${cfg.dataDir}/attachments"; behind-proxy = true; auth-default-access = "deny-all"; - auth-file = "/var/lib/ntfy-sh/user.db"; + auth-file = "${cfg.dataDir}/user.db"; auth-users = [ "mjallen:$2a$10$g4TqI8UiKKVaKTmrwnXIw.wtajiLBM6oc3UCfJ//lPZFilJnBirn.:admin" ]; }; }; }; - # Create and set permissions for required directories - system.activationScripts.ntfy-dirs = '' - mkdir -p /var/lib/ntfy-sh - chown -R ntfy-sh:ntfy-sh /var/lib/ntfy-sh - - chmod -R 775 /var/lib/ntfy-sh - ''; - }; - - bindMounts = { - "/var/lib/ntfy-sh" = { - hostPath = cfg.dataDir; - isReadOnly = false; + systemd.services = { + ntfy-sh = { + serviceConfig = { + WorkingDirectory = lib.mkForce cfg.dataDir; + StateDirectory = lib.mkForce cfg.dataDir; + StateDirectoryMode = lib.mkForce 700; + DynamicUser = lib.mkForce false; + ProtectSystem = lib.mkForce null; + }; + }; }; - "/run/.env" = { - hostPath = ntfyEnvFile; - isReadOnly = true; + + users.users.ntfy-sh = { + isSystemUser = true; + group = "ntfy-sh"; + home = cfg.dataDir; }; + users.groups.ntfy-sh = {}; }; # Create reverse proxy configuration using mkReverseProxy reverseProxyConfig = lib.${namespace}.mkReverseProxy { name = "ntfy"; subdomain = cfg.reverseProxy.subdomain; - url = "http://${cfg.localAddress}:${toString cfg.port}"; + url = "http://10.0.1.3:${toString cfg.port}"; middlewares = cfg.reverseProxy.middlewares; }; - ntfyContainer = - (lib.${namespace}.mkContainer { - name = "ntfy"; - localAddress = cfg.localAddress; - ports = [ cfg.port ]; - bindMounts = bindMounts; - config = ntfyConfig; - }) - { inherit lib; }; - fullConfig = { - ${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable { + "${namespace}".services.traefik = lib.mkIf cfg.reverseProxy.enable { reverseProxies = [ reverseProxyConfig ]; }; } - // ntfyContainer; + // ntfyConfig; in with lib; { diff --git a/modules/nixos/services/ntfy/default.nix.container b/modules/nixos/services/ntfy/default.nix.container new file mode 100644 index 0000000..67b69fd --- /dev/null +++ b/modules/nixos/services/ntfy/default.nix.container @@ -0,0 +1,94 @@ +{ + config, + lib, + namespace, + ... +}: +let + inherit (lib.${namespace}) mkOpt mkReverseProxyOpt; + cfg = config.${namespace}.services.ntfy; + + ntfyEnvFile = config.sops.secrets."jallen-nas/ntfy/auth-users".path; + + ntfyConfig = { + services = { + ntfy-sh = { + enable = true; + # environmentFile = "/run/.env"; + settings = { + base-url = "https://${cfg.reverseProxy.subdomain}.mjallen.dev"; + enable-login = true; + listen-http = ":${toString cfg.port}"; + cache-file = "/var/lib/ntfy-sh/cache.db"; + attachment-cache-dir = "/var/lib/ntfy-sh/attachments"; + behind-proxy = true; + auth-default-access = "deny-all"; + auth-file = "/var/lib/ntfy-sh/user.db"; + auth-users = [ + "mjallen:$2a$10$g4TqI8UiKKVaKTmrwnXIw.wtajiLBM6oc3UCfJ//lPZFilJnBirn.:admin" + ]; + }; + }; + }; + # Create and set permissions for required directories + system.activationScripts.ntfy-dirs = '' + mkdir -p /var/lib/ntfy-sh + + chown -R ntfy-sh:ntfy-sh /var/lib/ntfy-sh + + chmod -R 775 /var/lib/ntfy-sh + ''; + }; + + bindMounts = { + "/var/lib/ntfy-sh" = { + hostPath = cfg.dataDir; + isReadOnly = false; + }; + "/run/.env" = { + hostPath = ntfyEnvFile; + isReadOnly = true; + }; + }; + + # Create reverse proxy configuration using mkReverseProxy + reverseProxyConfig = lib.${namespace}.mkReverseProxy { + name = "ntfy"; + subdomain = cfg.reverseProxy.subdomain; + url = "http://${cfg.localAddress}:${toString cfg.port}"; + middlewares = cfg.reverseProxy.middlewares; + }; + + ntfyContainer = + (lib.${namespace}.mkContainer { + name = "ntfy"; + localAddress = cfg.localAddress; + ports = [ cfg.port ]; + bindMounts = bindMounts; + config = ntfyConfig; + }) + { inherit lib; }; + + fullConfig = { + ${namespace}.services.traefik = lib.mkIf cfg.reverseProxy.enable { + reverseProxies = [ reverseProxyConfig ]; + }; + } + // ntfyContainer; +in +with lib; +{ + options.${namespace}.services.ntfy = { + enable = mkEnableOption "ntfy service"; + + port = mkOpt types.int 8008 "Port for ntfy to be hosted on"; + + localAddress = mkOpt types.str "127.0.0.1" "local address of the service"; + + dataDir = mkOpt types.str "" "Path to the data dir"; + + reverseProxy = mkReverseProxyOpt; + }; + + config = lib.mkIf cfg.enable fullConfig; +} diff --git a/modules/nixos/services/traefik/default.nix b/modules/nixos/services/traefik/default.nix index b103086..05deda6 100755 --- a/modules/nixos/services/traefik/default.nix +++ b/modules/nixos/services/traefik/default.nix @@ -66,7 +66,7 @@ let hassUrl = "http://10.0.1.4:8123"; immichUrl = "http://${serverIp}:${toString config.services.immich.port}"; jellyfinUrl = "http://${serverIp}:8096"; - jellyseerrUrl = "http://${config.containers.jellyseerr.localAddress}:${toString config.containers.jellyseerr.config.services.jellyseerr.port}"; + jellyseerrUrl = "http://10.0.1.3:${toString config.services.jellyseerr.port}"; lubeloggerUrl = "http://${serverIp}:6754"; onlyofficeUrl = "http://${config.containers.nextcloud.localAddress}:${toString config.containers.nextcloud.config.services.onlyoffice.port}"; openWebUIUrl = "http://${serverIp}:8888"; @@ -243,6 +243,22 @@ in }; dynamicConfigOptions = { + # udp = { + # services = { + # wireguard.loadBalancer.servers = [ + # { + # url = "localhost:51820"; + # } + # ]; + # }; + # routers = { + # wireguard = { + # entryPoints = [ "websecure" ]; + # service = "wireguard"; + # }; + # }; + # }; + http = { middlewares = { authentik = { @@ -330,6 +346,12 @@ in } ]; + actual.loadBalancer.servers = [ + { + url = "http://10.0.1.3:3333"; + } + ]; + authentik.loadBalancer.servers = [ { url = authentikUrl; @@ -413,6 +435,17 @@ in tls.certResolver = "letsencrypt"; }; + actual = { + entryPoints = [ "websecure" ]; + rule = "Host(`actual.${domain}`)"; + service = "actual"; + middlewares = [ + "crowdsec" + "whitelist-geoblock" + ]; + tls.certResolver = "letsencrypt"; + }; + authentik = { entryPoints = [ "websecure" ]; rule = "Host(`authentik.${domain}`)"; diff --git a/systems/x86_64-linux/jallen-nas/apps.nix b/systems/x86_64-linux/jallen-nas/apps.nix index d2f4f9a..80c170f 100755 --- a/systems/x86_64-linux/jallen-nas/apps.nix +++ b/systems/x86_64-linux/jallen-nas/apps.nix @@ -5,7 +5,10 @@ # Existing properly namespaced services immich.enable = true; jellyfin.enable = true; - jellyseerr.enable = true; + jellyseerr = { + enable = true; + dataDir = "/media/nas/main/nix-app-data/jellyseerr"; + }; lubelogger.enable = true; nextcloud.enable = true; ai.enable = true; diff --git a/systems/x86_64-linux/jallen-nas/services.nix b/systems/x86_64-linux/jallen-nas/services.nix index 82ed406..2707e73 100755 --- a/systems/x86_64-linux/jallen-nas/services.nix +++ b/systems/x86_64-linux/jallen-nas/services.nix @@ -24,12 +24,16 @@ enable = true; package = pkgs.postgresql_16; dataDir = "/media/nas/main/nix-app-data/postgresql"; - ensureDatabases = [ "authentik" ]; + ensureDatabases = [ "authentik" "homeassistant" ]; ensureUsers = [ { name = "authentik"; ensureDBOwnership = true; } + { + name = "homeassistant"; + ensureDBOwnership = true; + } ]; };