diff --git a/hosts/miniserver/configuration.nix b/hosts/miniserver/configuration.nix index db80054..755f990 100644 --- a/hosts/miniserver/configuration.nix +++ b/hosts/miniserver/configuration.nix @@ -1,6 +1,5 @@ { pkgs, ... }: { - imports = - [ ./servers.nix ./docker.nix ./hardware-configuration.nix ../../base.nix ]; + imports = [ ./hardware-configuration.nix ../../base.nix ]; my = { emacs.enable = true; apps.dictionaries.enable = true; @@ -29,15 +28,35 @@ servers = { jellyfin = { enable = true; - enableCron = false; + enableCron = true; }; nextcloud = { - enable = false; - enableCron = false; + enable = true; + enableCron = true; }; - collabora.enable = false; - go-vod.enable = false; + adguardhome.enable = true; + audiobookshelf.enable = true; + bazarr.enable = true; + collabora.enable = true; + flame.enable = true; + flameSecret.enable = true; + go-vod.enable = true; + kavita.enable = true; + lidarr.enable = true; + maloja.enable = true; + mealie.enable = true; + metube.enable = true; microbin.enable = true; + multi-scrobbler.enable = true; + paperless.enable = true; + postgres.enable = true; + prowlarr.enable = true; + qbittorrent.enable = true; + radarr.enable = true; + ryot.enable = true; + shiori.enable = true; + sonarr.enable = true; + vaultwarden.enable = true; }; }; fonts.fontconfig.enable = true; @@ -119,48 +138,4 @@ # }; # }; }; - systemd = { - packages = [ pkgs.qbittorrent-nox ]; - services = { - "qbittorrent-nox@jawz" = { - enable = true; - overrideStrategy = "asDropin"; - wantedBy = [ "multi-user.target" ]; - }; - }; - user = { - services = { - # unpackerr = { - # enable = true; - # restartIfChanged = true; - # description = "Run unpackerr"; - # wantedBy = [ "default.target" ]; - # serviceConfig = { - # Restart = "on-failure"; - # RestartSec = 30; - # ExecStart = "${pkgs.unpackerr}/bin/unpackerr -c /home/jawz/.config/unpackerr.conf"; - # }; - # }; - qbit_manage = let qbit_dir = "/home/jawz/Development/Git/qbit_manage"; - in { - restartIfChanged = true; - description = "Tidy up my torrents"; - wantedBy = [ "default.target" ]; - path = [ pkgs.python3 pkgs.pipenv ]; - serviceConfig = { - Restart = "on-failure"; - RestartSec = 30; - ExecStart = - "${qbit_dir}/venv/bin/python3 ${qbit_dir}/qbit_manage.py -r -c ${qbit_dir}/config.yml"; - }; - }; - }; - timers.qbit_manage = { - enable = true; - description = "Tidy up my torrents"; - wantedBy = [ "timers.target" ]; - timerConfig = { OnCalendar = "*:0/10"; }; - }; - }; - }; } diff --git a/hosts/miniserver/docker.nix b/hosts/miniserver/docker.nix deleted file mode 100644 index 8c83f43..0000000 --- a/hosts/miniserver/docker.nix +++ /dev/null @@ -1,165 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - environment.systemPackages = with pkgs; [ docker-compose ]; - virtualisation = let postgresSocket = "/run/postgresql"; - in { - docker = { - enable = true; - enableNvidia = true; - autoPrune = { - enable = true; - flags = [ "--all" ]; - dates = "weekly"; - }; - }; - oci-containers = { - containers = { - # metube = { - # image = "ghcr.io/alexta69/metube"; - # ports = [ "8881:8081" ]; - # volumes = [ - # "/var/lib/docker-configs/metube:/downloads" - # "/home/jawz/.local/share/cookies.txt:/cookies.txt" - # ]; - # environment = { - # TZ = "America/Mexico_City"; - # YTDL_OPTIONS = ''{"cookiefile":"/cookies.txt"}''; - # }; - # }; - vocechat = { - image = "privoce/vocechat-server:latest"; - ports = [ "3001:3000" ]; - volumes = - [ "/var/lib/docker-configs/vocechat:/home/vocechat-server/data" ]; - environment = { TZ = "America/Mexico_City"; }; - }; - # ryot = { - # image = "ghcr.io/ignisda/ryot:v5.5.0"; - # ports = [ "8765:8000" ]; - # environment = { - # TZ = "America/Mexico_City"; - # DATABASE_URL = "postgres:///ryot?host=${postgresSocket}"; - # # FRONTEND_INSECURE_COOKIES = "true"; - # VIDEO_GAMES_TWITCH_CLIENT_ID = "tfu0hw0zbdbu4lco4h72nqkb8krxp9"; - # VIDEO_GAMES_TWITCH_CLIENT_SECRET = "582ecfb01ihv6wnt8zbc9pf3hs9p54"; - # }; - # volumes = [ "${postgresSocket}:${postgresSocket}" ]; - # labels = { - # "flame.type" = "application"; - # "flame.name" = "Ryot"; - # "flame.url" = "tracker.servidos.lat"; - # "flame.icon" = "radar"; - # }; - # }; - multi-scrobbler = { - image = "foxxmd/multi-scrobbler"; - ports = [ "9078:9078" ]; - environment = { - TZ = "America/Mexico_City"; - PUID = "1000"; - PGID = "100"; - BASE_URL = "https://scrobble.servidos.lat"; - # JELLYFIN_USER = "jawz"; - # JELLYFIN_SERVER = "DaniloFlix"; - DEEZER_CLIENT_ID = "657431"; - DEEZER_CLIENT_SECRET = "cb2ad03682dd5a55dfef857388ef181e"; - DEEZER_REDIRECT_URI = "http://192.168.1.69:9078/deezer/callback"; - MALOJA_URL = "https://maloja.servidos.lat"; - MALOJA_API_KEY = - "LsnY2Ed484JlzUmF6EwhpGJ0gUCjJ2G5s1oJTwALJN8w1N3K6eXpfjBQp3raNPLA"; - WS_ENABLE = "true"; - }; - volumes = [ "/var/lib/docker-configs/multi-scrobbler:/config" ]; - labels = { - "flame.type" = "application"; - "flame.name" = "Multi-scrobbler"; - "flame.url" = "scrobble.servidos.lat"; - "flame.icon" = "broadcast"; - }; - }; - maloja = { - image = "krateng/maloja"; - ports = [ "42010:42010" ]; - environment = { - TZ = "America/Mexico_City"; - MALOJA_TIMEZONE = "-6"; - PUID = "1000"; - PGID = "100"; - MALOJA_DATA_DIRECTORY = "/mljdata"; - MALOJA_SKIP_SETUP = "true"; - MALOJA_FORCE_PASSWORD = "chichis"; - }; - volumes = [ "/var/lib/docker-configs/maloja:/mljdata" ]; - labels = { - "flame.type" = "application"; - "flame.name" = "Maloja"; - "flame.url" = "maloja.servidos.lat"; - "flame.icon" = "bookmark-music"; - }; - }; - # flaresolverr = { - # autoStart = true; - # image = "ghcr.io/flaresolverr/flaresolverr:latest"; - # ports = [ "8191:8191" ]; - # }; - flame = { - autoStart = true; - image = "pawelmalak/flame"; - ports = [ "5005:5005" ]; - volumes = [ - "/var/lib/docker-configs/flame:/app/data" - "/var/run/docker.sock:/var/run/docker.sock" - ]; - environment = { - TZ = "America/Mexico_City"; - PUID = "1000"; - PGID = "100"; - PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; - }; - }; - mealie = { - autoStart = true; - image = "ghcr.io/mealie-recipes/mealie:v1.4.0"; - ports = [ "9925:9000" ]; - volumes = [ "/var/lib/docker-configs/mealie:/app/data/" ]; - environment = { - TZ = "America/Mexico_City"; - ALLOW_SIGNUP = "true"; - PUID = "1000"; - PGID = "100"; - MAX_WORKERS = "1"; - WEB_CONCURRENCY = "1"; - BASE_URL = "https://mealie.servidos.lat"; - SMTP_HOST = "smtp.gmail.com"; - SMTP_PORT = "587"; - SMTP_FROM_EMAIL = "stunner6399@gmail.com"; - SMTP_USER = "stunner6399@gmail.com"; - SMTP_PASSWORD = "ywofhisexfawslob"; - }; - extraOptions = [ - "--memory=1g" # VA-API (omit for NVENC) - ]; - labels = { - "flame.type" = "application"; - "flame.name" = "Mealie"; - "flame.url" = "mealie.servidos.lat"; - "flame.icon" = "fridge"; - }; - }; - flame-nsfw = { - autoStart = true; - image = "pawelmalak/flame"; - ports = [ "5007:5005" ]; - volumes = [ "/var/lib/docker-configs/flame-nsfw:/app/data" ]; - environment = { - TZ = "America/Mexico_City"; - PUID = "1000"; - PGID = "100"; - PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; - }; - }; - }; - }; - }; -} diff --git a/hosts/miniserver/nginx.nix b/hosts/miniserver/nginx.nix deleted file mode 100644 index 33f97e4..0000000 --- a/hosts/miniserver/nginx.nix +++ /dev/null @@ -1,117 +0,0 @@ -# Do not modify this file! It was generated by ‘nixos-generate-config’ - -# and may be overwritten by future invocations. Please make changes -# to /etc/nixos/configuration.nix instead. -{ config, ... }: -let - localhost = "127.0.0.1"; - # workstation = "192.168.1.64"; - domain = "servidos.lat"; - shioriPort = 4368; - flamePort = 5005; - secretFlamePort = 5007; - qbitPort = 9091; - mealiePort = 9925; - ryotPort = 8765; - scrobblePort = 9078; - malojaPort = 42010; - darkwirePort = 3001; - metatubePort = 8881; - # kavitaPort = config.services.kavita.port; - vaultPort = config.services.vaultwarden.config.ROCKET_PORT; - audiobookPort = config.services.audiobookshelf.port; -in { - services.nginx = { - enable = true; - clientMaxBodySize = "4096m"; - # recommendedTlsSettings = true; - # recommendedGzipSettings = true; - # recommendedOptimisation = true; - sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; - virtualHosts = let - base = locations: { - inherit locations; - forceSSL = true; - enableACME = true; - http2 = true; - }; - proxy = port: - base { "/".proxyPass = "http://${localhost}:${toString port}/"; }; - # proxyArr = port: - # proxy port // { - # extraConfig = '' - # proxy_set_header Host $host; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Host $host; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Upgrade $http_upgrade; - # proxy_set_header Connection $http_connection; - - # proxy_redirect off; - # proxy_http_version 1.1; - # ''; - # }; - in { - # "library.${domain}" = proxy kavitaPort // { }; - "start.${domain}" = proxy flamePort // { }; - "vault.${domain}" = proxy vaultPort // { }; - "mealie.${domain}" = proxy mealiePort // { }; - "tracker.${domain}" = proxy ryotPort // { }; - "scrobble.${domain}" = proxy scrobblePort // { }; - "maloja.${domain}" = proxy malojaPort // { }; - "bookmarks.${domain}" = proxy shioriPort // { }; - "bajameesta.${domain}" = proxy metatubePort // { }; - "qampqwn4wprhqny8h8zj.${domain}" = proxy secretFlamePort // { }; - "xfwmrle6h6skqujbeizw.${domain}" = proxy qbitPort // { }; - "audiobooks.${domain}" = base { - "/" = { - proxyPass = "http://${localhost}:${toString audiobookPort}"; - extraConfig = '' - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header Host $host; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - - proxy_http_version 1.1; - - proxy_redirect http:// https://; - ''; - }; - }; - "dontcancelmeplz.${domain}" = base { - "/" = { - proxyPass = "http://${localhost}:${toString darkwirePort}"; - proxyWebsockets = true; - extraConfig = '' - # Ensuring it can use websockets - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto http; - proxy_redirect http:// $scheme://; - - # The proxy must preserve the host because gotify verifies the host with the origin - # for WebSocket connections - proxy_set_header Host $host; - - # These sets the timeout so that the websocket can stay alive - proxy_connect_timeout 1m; - proxy_send_timeout 1m; - proxy_read_timeout 1m; - ''; - }; - }; - - }; - }; - networking = { - firewall = let open_firewall_ports = [ 80 443 ]; - in { - enable = true; - allowedTCPPorts = open_firewall_ports; - allowedUDPPorts = open_firewall_ports; - }; - }; -} diff --git a/hosts/miniserver/servers.nix b/hosts/miniserver/servers.nix deleted file mode 100644 index 641f0a1..0000000 --- a/hosts/miniserver/servers.nix +++ /dev/null @@ -1,130 +0,0 @@ -{ config, pkgs, ... }: -let - localhost = "127.0.0.1"; - postgresSocket = "/run/postgresql"; -in { - imports = [ ./nginx.nix ]; - environment.systemPackages = [ - # Upgrades postgres - (let - # XXX specify the postgresql package you'd like to upgrade to. - # Do not forget to list the extensions you need. - newPostgres = pkgs.postgresql_16.withPackages (pp: - [ - # pp.plv8 - ]); - in pkgs.writeScriptBin "upgrade-pg-cluster" '' - set -eux - # XXX it's perhaps advisable to stop all services that depend on postgresql - systemctl stop postgresql - - export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}" - - export NEWBIN="${newPostgres}/bin" - - export OLDDATA="${config.services.postgresql.dataDir}" - export OLDBIN="${config.services.postgresql.package}/bin" - - install -d -m 0700 -o postgres -g postgres "$NEWDATA" - cd "$NEWDATA" - sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" - - sudo -u postgres $NEWBIN/pg_upgrade \ - --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ - --old-bindir $OLDBIN --new-bindir $NEWBIN \ - "$@" - '') - ]; - users.users = let base = { isSystemUser = true; }; - in { - # kavita = base // { - # group = "kavita"; - # extraGroups = [ "piracy" ]; - # }; - }; - services = let - base = { - enable = true; - group = "piracy"; - }; - in { - # jira.enable = true; - # adguardhome = { - # enable = true; - # mutableSettings = true; - # openFirewall = true; - # }; - # audiobookshelf = { - # enable = true; - # group = "piracy"; - # port = 5687; - # }; - paperless = { - enable = true; - address = "0.0.0.0"; - consumptionDirIsPublic = true; - consumptionDir = "/mnt/pool/scans/"; - settings = { - PAPERLESS_DBENGINE = "postgress"; - PAPERLESS_DBNAME = "paperless"; - PAPERLESS_DBHOST = postgresSocket; - PAPERLESS_CONSUMER_IGNORE_PATTERN = - builtins.toJSON [ ".DS_STORE/*" "desktop.ini" ]; - PAPERLESS_TIME_ZONE = "America/Mexico_City"; - PAPERLESS_OCR_USER_ARGS = builtins.toJSON { - optimize = 1; - pdfa_image_compression = "lossless"; - }; - }; - }; - vaultwarden = { - enable = true; - dbBackend = "postgresql"; - package = pkgs.vaultwarden; - environmentFile = "/var/lib/vaultwarden.env"; - config = { - ROCKET_ADDRESS = "${localhost}"; - ROCKET_PORT = 8222; - WEBSOCKET_PORT = 8333; - DATABASE_URL = "postgresql:///vaultwarden?host=${postgresSocket}"; - ENABLE_DB_WAL = false; - WEBSOCKET_ENABLED = true; - SHOW_PASSWORD_HINT = false; - SIGNUPS_ALLOWED = false; - EXTENDED_LOGGING = true; - LOG_LEVEL = "warn"; - }; - }; - # kavita = { - # enable = true; - # tokenKeyFile = "${pkgs.writeText "kavitaToken" - # "Au002BRkRxBjlQrmWSuXWTGUcpXZjzMo2nJ0Z4g4OZ1S4c2zp6oaesGUXzKp2mhvOwjju002BNoURG3CRIE2qnGybvOgAlDxAZCPBzSNRcx6RJ1lFRgvI8wQR6Nd5ivYX0RMo4S8yOH8XIDhzN6vNo31rCjyv2IycX0JqiJPIovfbvXn9Y="}"; - # }; - postgresql = let - dbNames = - [ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" "shiori" ]; - in { - enable = true; - ensureDatabases = dbNames; - package = pkgs.postgresql_16; - ensureUsers = map (name: { - name = name; - ensureDBOwnership = true; - }) dbNames; - authentication = pkgs.lib.mkOverride 10 '' - local all all trust - host all all ${localhost}/32 trust - host all all ::1/128 trust - ''; - }; - }; - - networking = { - firewall = let open_firewall_ports = [ config.services.paperless.port ]; - in { - enable = true; - allowedTCPPorts = open_firewall_ports; - allowedUDPPorts = open_firewall_ports; - }; - }; -} diff --git a/modules/servers.nix b/modules/servers.nix index bd36dc0..c21e473 100644 --- a/modules/servers.nix +++ b/modules/servers.nix @@ -15,7 +15,7 @@ let "/".proxyPass = "http://${config.my.localhost}:${toString port}/"; }; proxyReverseArr = port: - proxy port // { + proxyReverse port // { extraConfig = '' proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -23,32 +23,51 @@ let proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; - proxy_redirect off; proxy_http_version 1.1; ''; }; enableDocker = lib.any (opt: opt) [ config.my.servers.collabora.enable + config.my.servers.ryot.enable + config.my.servers.lidarr.enable + config.my.servers.prowlarr.enable + config.my.servers.maloja.enable + config.my.servers.multi-scrobbler.enable + config.my.servers.flame.enable + config.my.servers.metube.enable config.my.servers.go-vod.enable ]; in { imports = [ + ./servers/adguardhome.nix + ./servers/paperless.nix + ./servers/postgres.nix + (import ./servers/audiobookshelf.nix { inherit lib config proxy; }) + (import ./servers/bazarr.nix { + inherit lib config serviceBase proxyReverse; + }) + (import ./servers/flame.nix { inherit lib config proxyReverse; }) (import ./servers/jellyfin.nix { inherit lib config pkgs serviceBase; }) - (import ./servers/nextcloud.nix { inherit lib config pkgs serviceBase; }) + (import ./servers/kavita.nix { inherit lib config pkgs proxyReverse; }) + (import ./servers/lidarr.nix { inherit lib config proxyReverseArr; }) + (import ./servers/maloja.nix { inherit lib config proxyReverse; }) + (import ./servers/mealie.nix { inherit lib config proxyReverse; }) + (import ./servers/metube.nix { inherit lib config proxyReverse; }) (import ./servers/microbin.nix { inherit lib config proxyReverse; }) + (import ./servers/multi-scrobbler.nix { inherit lib config proxyReverse; }) + (import ./servers/nextcloud.nix { inherit lib config pkgs serviceBase; }) + (import ./servers/prowlarr.nix { inherit lib config proxyReverseArr; }) + (import ./servers/qbittorrent.nix { inherit lib config pkgs proxyReverse; }) + (import ./servers/radarr.nix { + inherit lib config serviceBase proxyReverseArr; + }) + (import ./servers/ryot.nix { inherit lib config proxyReverse; }) (import ./servers/shiori.nix { inherit lib config pkgs proxyReverse; }) (import ./servers/sonarr.nix { inherit lib config serviceBase proxyReverse; }) - (import ./servers/bazarr.nix { - inherit lib config serviceBase proxyReverse; - }) - (import ./servers/radarr.nix { - inherit lib config serviceBase proxyReverseArr; - }) - (import ./servers/prowlarr.nix { inherit lib config proxyReverseArr; }) - (import ./servers/lidarr.nix { inherit lib config proxyReverseArr; }) + (import ./servers/vaultwarden.nix { inherit lib config pkgs proxyReverse; }) ]; options.my = { localhost = lib.mkOption { @@ -66,6 +85,16 @@ in { default = "/run/postgresql"; description = "The PostgreSQL socket path."; }; + containerSocket = lib.mkOption { + type = lib.types.str; + default = "/var/run/docker.sock"; + description = "The docker/podman socket path."; + }; + containerData = lib.mkOption { + type = lib.types.str; + default = "/var/lib/docker-configs"; + description = "The docker/podman socket path."; + }; }; config = { my.servers = { @@ -77,15 +106,29 @@ in { enable = lib.mkDefault false; enableCron = lib.mkDefault false; }; + adguardhome.enable = lib.mkDefault false; + audiobookshelf.enable = lib.mkDefault false; + bazarr.enable = lib.mkDefault false; collabora.enable = lib.mkDefault false; + flame.enable = lib.mkDefault false; + flameSecret.enable = lib.mkDefault false; go-vod.enable = lib.mkDefault false; + kavita.enable = lib.mkDefault false; + lidarr.enable = lib.mkDefault false; + maloja.enable = lib.mkDefault false; + mealie.enable = lib.mkDefault false; + metube.enable = lib.mkDefault false; microbin.enable = lib.mkDefault false; + multi-scrobbler.enable = lib.mkDefault false; + paperless.enable = lib.mkDefault false; + postgres.enable = lib.mkDefault false; + prowlarr.enable = lib.mkDefault false; + qbittorrent.enable = lib.mkDefault false; + radarr.enable = lib.mkDefault false; + ryot.enable = lib.mkDefault false; shiori.enable = lib.mkDefault false; sonarr.enable = lib.mkDefault false; - bazarr.enable = lib.mkDefault false; - radarr.enable = lib.mkDefault false; - lidarr.enable = lib.mkDefault false; - prowlarr.enable = lib.mkDefault false; + vaultwarden.enable = lib.mkDefault false; }; virtualisation.docker = lib.mkIf enableDocker { enable = true; @@ -96,5 +139,18 @@ in { dates = "weekly"; }; }; + services.nginx = { + clientMaxBodySize = "4096m"; + # recommendedTlsSettings = true; + # recommendedGzipSettings = true; + # recommendedOptimisation = true; + sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL"; + }; + networking.firewall = let ports = [ 80 443 ]; + in { + enable = true; + allowedTCPPorts = ports; + allowedUDPPorts = ports; + }; }; } diff --git a/modules/servers/adguardhome.nix b/modules/servers/adguardhome.nix new file mode 100644 index 0000000..9e1e3f2 --- /dev/null +++ b/modules/servers/adguardhome.nix @@ -0,0 +1,10 @@ +{ lib, config, ... }: { + options.my.servers.adguardhome.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.adguardhome.enable { + services.adguardhome = { + enable = true; + mutableSettings = true; + openFirewall = true; + }; + }; +} diff --git a/modules/servers/audiobookshelf.nix b/modules/servers/audiobookshelf.nix new file mode 100644 index 0000000..9a5d2f3 --- /dev/null +++ b/modules/servers/audiobookshelf.nix @@ -0,0 +1,31 @@ +{ lib, config, proxy, ... }: { + options.my.servers.audiobookshelf.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.audiobookshelf.enable { + services = { + audiobookshelf = { + enable = true; + group = "piracy"; + port = 5687; + }; + nginx = { + enable = true; + virtualHosts."audiobooks.${config.my.domain}" = proxy { + "/" = { + proxyPass = "http://${config.my.localhost}:${ + toString config.services.audiobookshelf.port + }"; + extraConfig = '' + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_http_version 1.1; + proxy_redirect http:// https://; + ''; + }; + }; + }; + }; + }; +} diff --git a/modules/servers/flame.nix b/modules/servers/flame.nix new file mode 100644 index 0000000..0715172 --- /dev/null +++ b/modules/servers/flame.nix @@ -0,0 +1,50 @@ +{ lib, config, proxyReverse, ... }: +let + port = 5005; + portSecret = 5007; +in { + options.my.servers = { + flame.enable = lib.mkEnableOption "enable"; + flameSecret.enable = lib.mkEnableOption "enable"; + }; + config = lib.mkIf config.my.servers.flame.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers = { + flame = { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "${toString port}:${toString port}" ]; + volumes = [ + "${config.my.containerData}/flame:/app/data" + "${config.my.containerSocket}:${config.my.containerSocket}" + ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; + }; + }; + flame-nsfw = { + autoStart = true; + image = "pawelmalak/flame"; + ports = [ "${toString portSecret}:${toString port}" ]; + volumes = [ "${config.my.containerData}/flame-nsfw:/app/data" ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + PASSWORD = "RkawpqMc8lR56QyU7JSfiLhG"; + }; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."start.${config.my.domain}" = proxyReverse port // { }; + virtualHosts."qampqwn4wprhqny8h8zj.${config.my.domain}" = + proxyReverse portSecret // { }; + }; + }; +} diff --git a/modules/servers/kavita.nix b/modules/servers/kavita.nix new file mode 100644 index 0000000..daa247c --- /dev/null +++ b/modules/servers/kavita.nix @@ -0,0 +1,22 @@ +{ lib, config, pkgs, proxyReverse, ... }: { + options.my.servers.kavita.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.kavita.enable { + users.users.kavita = { + isSystemUser = true; + group = "kavita"; + extraGroups = [ "piracy" ]; + }; + services = { + kavita = { + enable = true; + tokenKeyFile = "${pkgs.writeText "kavitaToken" + "Au002BRkRxBjlQrmWSuXWTGUcpXZjzMo2nJ0Z4g4OZ1S4c2zp6oaesGUXzKp2mhvOwjju002BNoURG3CRIE2qnGybvOgAlDxAZCPBzSNRcx6RJ1lFRgvI8wQR6Nd5ivYX0RMo4S8yOH8XIDhzN6vNo31rCjyv2IycX0JqiJPIovfbvXn9Y="}"; + }; + nginx = { + enable = true; + virtualHosts."library.${config.my.domain}" = + proxyReverse config.services.kavita.port // { }; + }; + }; + }; +} diff --git a/modules/servers/lidarr.nix b/modules/servers/lidarr.nix index 47e2998..70f2732 100644 --- a/modules/servers/lidarr.nix +++ b/modules/servers/lidarr.nix @@ -1,4 +1,8 @@ -{ lib, config, proxyReverseArr, ... }: { +{ lib, config, proxyReverseArr, ... }: +let + port = 8686; + url = "music.${config.my.domain}"; +in { options.my.servers.lidarr.enable = lib.mkEnableOption "enable"; config = lib.mkIf config.my.servers.lidarr.enable { virtualisation.oci-containers = { @@ -6,7 +10,7 @@ containers.lidarr = { autoStart = true; image = "lscr.io/linuxserver/lidarr:latest"; - ports = [ "8686:8686" ]; + ports = [ "${toString port}:${toString port}" ]; environment = { TZ = "America/Mexico_City"; PUID = "1000"; @@ -16,14 +20,14 @@ "/mnt/pool/multimedia:/data" "/mnt/pool/multimedia/media/Music:/music" "/mnt/pool/multimedia/media/MusicVideos:/music-videos" - "/var/lib/docker-configs/lidarr/files:/config" - "/var/lib/docker-configs/lidarr/custom-services.d:/custom-services.d" - "/var/lib/docker-configs/lidarr/custom-cont-init.d:/custom-cont-init.d" + "${config.my.containerData}/lidarr/files:/config" + "${config.my.containerData}/lidarr/custom-services.d:/custom-services.d" + "${config.my.containerData}/lidarr/custom-cont-init.d:/custom-cont-init.d" ]; labels = { "flame.type" = "application"; "flame.name" = "Lidarr"; - "flame.url" = "music.servidos.lat"; + "flame.url" = url; "flame.icon" = "music"; }; }; @@ -32,7 +36,7 @@ lidarr.enable = true; nginx = { enable = true; - virtualHosts."music.${config.my.domain}" = proxyReverseArr 8686 // { }; + virtualHosts."${url}" = proxyReverseArr port // { }; }; }; }; diff --git a/modules/servers/maloja.nix b/modules/servers/maloja.nix new file mode 100644 index 0000000..9352c37 --- /dev/null +++ b/modules/servers/maloja.nix @@ -0,0 +1,36 @@ +{ lib, config, proxyReverse, ... }: +let + port = 42010; + url = "maloja.${config.my.domain}"; +in { + options.my.servers.maloja.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.maloja.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers.maloja = { + image = "krateng/maloja"; + ports = [ "${toString port}:${toString port}" ]; + environment = { + TZ = "America/Mexico_City"; + MALOJA_TIMEZONE = "-6"; + PUID = "1000"; + PGID = "100"; + MALOJA_DATA_DIRECTORY = "/mljdata"; + MALOJA_SKIP_SETUP = "true"; + MALOJA_FORCE_PASSWORD = "chichis"; + }; + volumes = [ "${config.my.containerData}/maloja:/mljdata" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Maloja"; + "flame.url" = url; + "flame.icon" = "bookmark-music"; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."${url}" = proxyReverse port // { }; + }; + }; +} diff --git a/modules/servers/mealie.nix b/modules/servers/mealie.nix new file mode 100644 index 0000000..a8fad37 --- /dev/null +++ b/modules/servers/mealie.nix @@ -0,0 +1,46 @@ +{ lib, config, proxyReverse, ... }: +let + port = 9925; + domain = "mealie.${config.my.domain}"; + url = "https://${domain}"; +in { + options.my.servers.mealie.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.mealie.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers.mealie = { + autoStart = true; + image = "ghcr.io/mealie-recipes/mealie:v1.4.0"; + ports = [ "${toString port}:9000" ]; + volumes = [ "${config.my.containerData}/mealie:/app/data/" ]; + environment = { + TZ = "America/Mexico_City"; + ALLOW_SIGNUP = "true"; + PUID = "1000"; + PGID = "100"; + MAX_WORKERS = "1"; + WEB_CONCURRENCY = "1"; + BASE_URL = url; + SMTP_HOST = "smtp.gmail.com"; + SMTP_PORT = "587"; + SMTP_FROM_EMAIL = "stunner6399@gmail.com"; + SMTP_USER = "stunner6399@gmail.com"; + SMTP_PASSWORD = "ywofhisexfawslob"; + }; + extraOptions = [ + "--memory=1g" # VA-API (omit for NVENC) + ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Mealie"; + "flame.url" = url; + "flame.icon" = "fridge"; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."${domain}" = proxyReverse port // { }; + }; + }; +} diff --git a/modules/servers/metube.nix b/modules/servers/metube.nix new file mode 100644 index 0000000..7a7c6ce --- /dev/null +++ b/modules/servers/metube.nix @@ -0,0 +1,26 @@ +{ lib, config, proxyReverse, ... }: +let port = 8881; +in { + options.my.servers.metube.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.metube.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers.metube = { + image = "ghcr.io/alexta69/metube"; + ports = [ "${toString port}:8081" ]; + volumes = [ + "${config.my.containerData}/metube:/downloads" + "/home/jawz/.local/share/cookies.txt:/cookies.txt" + ]; + environment = { + TZ = "America/Mexico_City"; + YTDL_OPTIONS = ''{"cookiefile":"/cookies.txt"}''; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."bajameesta.${config.my.domain}" = proxyReverse port // { }; + }; + }; +} diff --git a/modules/servers/multi-scrobbler.nix b/modules/servers/multi-scrobbler.nix new file mode 100644 index 0000000..c17b7da --- /dev/null +++ b/modules/servers/multi-scrobbler.nix @@ -0,0 +1,43 @@ +{ lib, config, proxyReverse, ... }: +let + port = 9078; + domain = "scrobble.${config.my.domain}"; + url = "https://${domain}"; +in { + options.my.servers.multi-scrobbler.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.multi-scrobbler.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers.multi-scrobbler = { + image = "foxxmd/multi-scrobbler"; + ports = [ "${toString port}:${toString port}" ]; + environment = { + TZ = "America/Mexico_City"; + PUID = "1000"; + PGID = "100"; + BASE_URL = url; + # JELLYFIN_USER = "jawz"; + # JELLYFIN_SERVER = "DaniloFlix"; + DEEZER_CLIENT_ID = "657431"; + DEEZER_CLIENT_SECRET = "cb2ad03682dd5a55dfef857388ef181e"; + DEEZER_REDIRECT_URI = "http://192.168.1.69:9078/deezer/callback"; + MALOJA_URL = url; + MALOJA_API_KEY = + "LsnY2Ed484JlzUmF6EwhpGJ0gUCjJ2G5s1oJTwALJN8w1N3K6eXpfjBQp3raNPLA"; + WS_ENABLE = "true"; + }; + volumes = [ "${config.my.containerData}/multi-scrobbler:/config" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Multi-scrobbler"; + "flame.url" = url; + "flame.icon" = "broadcast"; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."${domain}" = proxyReverse port // { }; + }; + }; +} diff --git a/modules/servers/nextcloud.nix b/modules/servers/nextcloud.nix index 4028ade..70765c3 100644 --- a/modules/servers/nextcloud.nix +++ b/modules/servers/nextcloud.nix @@ -1,7 +1,18 @@ -{ lib, config, pkgs, serviceBase, ... }: +{ lib, config, pkgs, ... }: let localhost = config.my.localhost; collaboraPort = 9980; + url = "cloud.${config.my.domain}"; + collaboraProxy = "http://${localhost}:${toString collaboraPort}"; + commonProxyConfig = '' + proxy_set_header Host $host; + ''; + commonWebsocketConfig = '' + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_read_timeout 36000s; + ''; in { options.my.servers = { nextcloud = { @@ -55,7 +66,7 @@ in { extraAppsEnable = true; enableImagemagick = true; maxUploadSize = "16G"; - hostName = "cloud.servidos.lat"; + hostName = url; extraApps = { inherit (config.services.nextcloud.package.packages.apps) calendar; }; @@ -126,35 +137,39 @@ in { { }; }; }; - "collabora.${config.my.domain}" = let - localUrl = "http://${localhost}:${toString collaboraPort}"; - proxySettings = { - proxyPass = localUrl; - extraConfig = '' - proxy_set_header Host $host; - ''; + "collabora.${config.my.domain}" = + lib.mkIf config.my.servers.collabora.enable { + forceSSL = true; + enableACME = true; + http2 = true; + locations = { + # static files + "^~ /loleaflet" = { + proxyPass = collaboraProxy; + extraConfig = commonProxyConfig; + }; + # WOPI discovery URL + "^~ /hosting/discovery" = { + proxyPass = collaboraProxy; + extraConfig = commonProxyConfig; + }; + # Capabilities + "^~ /hosting/capabilities" = { + proxyPass = collaboraProxy; + extraConfig = commonProxyConfig; + }; + # download, presentation, image upload and websocket + "~ ^/lool" = { + proxyPass = collaboraProxy; + extraConfig = commonWebsocketConfig; + }; + # Admin Console websocket + "^~ /lool/adminws" = { + proxyPass = collaboraProxy; + extraConfig = commonWebsocketConfig; + }; + }; }; - collaboraSocket = { - proxyPass = localUrl; - extraConfig = '' - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - proxy_read_timeout 36000s; - ''; - }; - in serviceBase lib.mkIf config.my.servers.collabora.enable { - # static files - "^~ /loleaflet" = proxySettings; - # WOPI discovery URL - "^~ /hosting/discovery" = proxySettings; - # Capabilities - "^~ /hosting/capabilities" = proxySettings; - # download, presentation, image upload and websocket - "~ ^/lool" = collaboraSocket; - # Admin Console websocket - "^~ /lool/adminws" = collaboraSocket; - }; }; }; }; @@ -186,8 +201,8 @@ in { ports = [ "9980:9980" ]; environment = { TZ = "America/Mexico_City"; - domain = "cloud.servidos.lat"; - aliasgroup1 = "cloud.servidos.lat:443"; + domain = url; + aliasgroup1 = "${url}:443"; aliasgroup2 = "cloud.rotehaare.art:443"; dictionaries = "en_CA en_US es_MX es_ES fr_FR it pt_BR ru"; extra_params = '' diff --git a/modules/servers/paperless.nix b/modules/servers/paperless.nix new file mode 100644 index 0000000..60db727 --- /dev/null +++ b/modules/servers/paperless.nix @@ -0,0 +1,28 @@ +{ lib, config, ... }: { + options.my.servers.paperless.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.paperless.enable { + services.paperless = { + enable = true; + address = "0.0.0.0"; + consumptionDirIsPublic = true; + consumptionDir = "/mnt/pool/scans/"; + settings = { + PAPERLESS_DBENGINE = "postgress"; + PAPERLESS_DBNAME = "paperless"; + PAPERLESS_DBHOST = config.my.postgresSocket; + PAPERLESS_CONSUMER_IGNORE_PATTERN = + builtins.toJSON [ ".DS_STORE/*" "desktop.ini" ]; + PAPERLESS_TIME_ZONE = "America/Mexico_City"; + PAPERLESS_OCR_USER_ARGS = builtins.toJSON { + optimize = 1; + pdfa_image_compression = "lossless"; + }; + }; + }; + networking.firewall = { + enable = true; + allowedTCPPorts = [ config.services.paperless.port ]; + allowedUDPPorts = [ config.services.paperless.port ]; + }; + }; +} diff --git a/modules/servers/postgres.nix b/modules/servers/postgres.nix new file mode 100644 index 0000000..c9ce16f --- /dev/null +++ b/modules/servers/postgres.nix @@ -0,0 +1,40 @@ +{ config, lib, pkgs, ... }: +let + upgrade-pg-cluster = + let newPostgres = pkgs.postgresql_16.withPackages (pp: [ ]); + in pkgs.writeScriptBin "upgrade-pg-cluster" '' + set -eux + systemctl stop postgresql + export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}" + export NEWBIN="${newPostgres}/bin" + export OLDDATA="${config.services.postgresql.dataDir}" + export OLDBIN="${config.services.postgresql.package}/bin" + install -d -m 0700 -o postgres -g postgres "$NEWDATA" + cd "$NEWDATA" + sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" + sudo -u postgres $NEWBIN/pg_upgrade \ + --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ + --old-bindir $OLDBIN --new-bindir $NEWBIN \ + "$@" + ''; + dbNames = [ "jawz" "paperless" "nextcloud" "ryot" "vaultwarden" "shiori" ]; +in { + options.my.servers.postgres.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.postgres.enable { + environment.systemPackages = [ upgrade-pg-cluster ]; + services.postgresql = { + enable = true; + ensureDatabases = dbNames; + package = pkgs.postgresql_16; + ensureUsers = map (name: { + name = name; + ensureDBOwnership = true; + }) dbNames; + authentication = pkgs.lib.mkOverride 10 '' + local all all trust + host all all ${config.my.localhost}/32 trust + host all all ::1/128 trust + ''; + }; + }; +} diff --git a/modules/servers/prowlarr.nix b/modules/servers/prowlarr.nix index 420f924..631fbde 100644 --- a/modules/servers/prowlarr.nix +++ b/modules/servers/prowlarr.nix @@ -13,5 +13,13 @@ // { }; }; }; + virtualisation.oci-containers = { + backend = "docker"; + containers.flaresolverr = { + autoStart = true; + image = "ghcr.io/flaresolverr/flaresolverr:latest"; + ports = [ "8191:8191" ]; + }; + }; }; } diff --git a/modules/servers/qbittorrent.nix b/modules/servers/qbittorrent.nix new file mode 100644 index 0000000..0ec4b25 --- /dev/null +++ b/modules/servers/qbittorrent.nix @@ -0,0 +1,55 @@ +{ lib, config, pkgs, proxyReverse, ... }: { + options.my.servers.qbittorrent.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.qbittorrent.enable { + systemd = { + packages = [ pkgs.qbittorrent-nox ]; + services = { + "qbittorrent-nox@jawz" = { + enable = true; + overrideStrategy = "asDropin"; + wantedBy = [ "multi-user.target" ]; + }; + }; + user = { + services = { + qbit_manage = { + restartIfChanged = true; + description = "Tidy up my torrents"; + wantedBy = [ "default.target" ]; + path = [ pkgs.python3 pkgs.pipenv ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + WorkingDirectory = "/home/jawz/Development/Git/qbit_manage"; + ExecStart = + "./venv/bin/python3 ./qbit_manage.py -r -c ./config.yml"; + }; + }; + unpackerr = { + enable = false; + restartIfChanged = true; + description = "Run unpackerr"; + wantedBy = [ "default.target" ]; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 30; + ExecStart = + "${pkgs.unpackerr}/bin/unpackerr -c /home/jawz/.config/unpackerr.conf"; + }; + }; + }; + timers.qbit_manage = { + enable = true; + description = "Tidy up my torrents"; + wantedBy = [ "timers.target" ]; + timerConfig = { OnCalendar = "*:0/10"; }; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."xfwmrle6h6skqujbeizw.${config.my.domain}" = + proxyReverse 9091 // { }; + }; + }; +} diff --git a/modules/servers/ryot.nix b/modules/servers/ryot.nix new file mode 100644 index 0000000..787299c --- /dev/null +++ b/modules/servers/ryot.nix @@ -0,0 +1,34 @@ +{ lib, config, proxyReverse, ... }: +let + port = 8881; + url = "tracker.${config.my.domain}"; +in { + options.my.servers.ryot.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.ryot.enable { + virtualisation.oci-containers = { + backend = "docker"; + containers.ryot = { + image = "ghcr.io/ignisda/ryot:v5.5.0"; + ports = [ "8765:8000" ]; + environment = { + TZ = "America/Mexico_City"; + DATABASE_URL = "postgres:///ryot?host=${config.my.postgresSocket}"; + FRONTEND_INSECURE_COOKIES = "true"; + VIDEO_GAMES_TWITCH_CLIENT_ID = "tfu0hw0zbdbu4lco4h72nqkb8krxp9"; + VIDEO_GAMES_TWITCH_CLIENT_SECRET = "582ecfb01ihv6wnt8zbc9pf3hs9p54"; + }; + volumes = [ "${config.my.postgresSocket}:${config.my.postgresSocket}" ]; + labels = { + "flame.type" = "application"; + "flame.name" = "Ryot"; + "flame.url" = url; + "flame.icon" = "radar"; + }; + }; + }; + services.nginx = { + enable = true; + virtualHosts."tracker.${config.my.domain}" = proxyReverse port // { }; + }; + }; +} diff --git a/modules/servers/shiori.nix b/modules/servers/shiori.nix index 7e99c23..be9c61b 100644 --- a/modules/servers/shiori.nix +++ b/modules/servers/shiori.nix @@ -9,13 +9,12 @@ port = 4368; package = pkgs.callPackage ../../pkgs/shiori/shiori.nix { }; httpSecretKey = "password"; - databaseUrl = - "postgres:///shiori?host=${config.my.postgresSocket}"; + databaseUrl = "postgres:///shiori?host=${config.my.postgresSocket}"; }; nginx = { enable = true; - virtualHosts."copy.${config.my.domain}" = - proxyReverse config.my.servers.shiori.port // { }; + virtualHosts."bookmarks.${config.my.domain}" = + proxyReverse config.services.shiori.port // { }; }; }; }; diff --git a/modules/servers/vaultwarden.nix b/modules/servers/vaultwarden.nix new file mode 100644 index 0000000..14bd4a8 --- /dev/null +++ b/modules/servers/vaultwarden.nix @@ -0,0 +1,31 @@ +{ lib, config, pkgs, proxyReverse, ... }: { + options.my.servers.vaultwarden.enable = lib.mkEnableOption "enable"; + config = lib.mkIf config.my.servers.vaultwarden.enable { + services = { + vaultwarden = { + enable = true; + dbBackend = "postgresql"; + package = pkgs.vaultwarden; + environmentFile = "/var/lib/vaultwarden.env"; + config = { + ROCKET_ADDRESS = "${config.my.localhost}"; + ROCKET_PORT = 8222; + WEBSOCKET_PORT = 8333; + DATABASE_URL = + "postgresql:///vaultwarden?host=${config.my.postgresSocket}"; + ENABLE_DB_WAL = false; + WEBSOCKET_ENABLED = true; + SHOW_PASSWORD_HINT = false; + SIGNUPS_ALLOWED = false; + EXTENDED_LOGGING = true; + LOG_LEVEL = "warn"; + }; + }; + nginx = { + enable = true; + virtualHosts."vault.${config.my.domain}" = + proxyReverse config.services.vaultwarden.config.ROCKET_PORT // { }; + }; + }; + }; +}