diff --git a/.github/workflows/flake-health-checks.yml b/.github/workflows/flake-health-checks.yml index 123f5cb..af05117 100644 --- a/.github/workflows/flake-health-checks.yml +++ b/.github/workflows/flake-health-checks.yml @@ -6,8 +6,8 @@ on: branches: ["main"] merge_group: concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: health-check: name: "Perform Nix flake checks" diff --git a/.github/workflows/flake-update.yml b/.github/workflows/flake-update.yml index acb55b7..ac4aa8a 100644 --- a/.github/workflows/flake-update.yml +++ b/.github/workflows/flake-update.yml @@ -5,8 +5,8 @@ on: schedule: - cron: "00 12 * * *" concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: update_lockfile: runs-on: ubuntu-latest diff --git a/.github/workflows/lock-health-checks.yml b/.github/workflows/lock-health-checks.yml index f27e0a3..f2724d6 100644 --- a/.github/workflows/lock-health-checks.yml +++ b/.github/workflows/lock-health-checks.yml @@ -6,8 +6,8 @@ on: branches: ["main"] merge_group: concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true jobs: health-check: name: "Check health of `flake.lock`" diff --git a/.sops.yaml b/.sops.yaml index 627d319..45d9626 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -49,3 +49,9 @@ creation_rules: - *admin_alice age: - *palatine-hill + - path_regex: systems/palatine-hill/docker/openvpn/.*\.ovpn$ + key_groups: + - pgp: + - *admin_alice + age: + - *palatine-hill diff --git a/modules/users.nix b/modules/users.nix new file mode 100644 index 0000000..98c54c6 --- /dev/null +++ b/modules/users.nix @@ -0,0 +1,11 @@ +{ + ... +}: + +{ + users.groups = { + users = { + gid = 100; + }; + }; +} diff --git a/systems/artemision/configuration.nix b/systems/artemision/configuration.nix index 72dcc48..0e32712 100644 --- a/systems/artemision/configuration.nix +++ b/systems/artemision/configuration.nix @@ -60,12 +60,13 @@ fwupd = { enable = true; - package = - (import (builtins.fetchTarball { - url = "https://github.com/NixOS/nixpkgs/archive/bb2009ca185d97813e75736c2b8d1d8bb81bde05.tar.gz"; - sha256 = "sha256:003qcrsq5g5lggfrpq31gcvj82lb065xvr7bpfa8ddsw8x4dnysk"; - }) { inherit (pkgs) system; }).fwupd; + # package = + # (import (builtins.fetchTarball { + # url = "https://github.com/NixOS/nixpkgs/archive/bb2009ca185d97813e75736c2b8d1d8bb81bde05.tar.gz"; + # sha256 = "sha256:003qcrsq5g5lggfrpq31gcvj82lb065xvr7bpfa8ddsw8x4dnysk"; + # }) { inherit (pkgs) system; }).fwupd; }; + mullvad-vpn.enable = true; fprintd.enable = lib.mkForce false; openssh.enable = lib.mkForce false; diff --git a/systems/palatine-hill/configuration.nix b/systems/palatine-hill/configuration.nix index 4281bd6..7a2f455 100644 --- a/systems/palatine-hill/configuration.nix +++ b/systems/palatine-hill/configuration.nix @@ -17,6 +17,7 @@ ./minio.nix ./networking.nix ./nextcloud.nix + #./plex ./postgresql.nix ./samba.nix ./zfs.nix @@ -57,16 +58,37 @@ }; }; - environment.systemPackages = with pkgs; [ - chromedriver - chromium - docker-compose - intel-gpu-tools - jellyfin-ffmpeg - jq - yt-dlp - yq - ]; + environment = { + systemPackages = with pkgs; [ + chromedriver + chromium + docker-compose + filebot + intel-gpu-tools + jellyfin-ffmpeg + jq + yt-dlp + yq + ]; + etc = { + # Creates /etc/lynis/custom.prf + "lynis/custom.prf" = { + text = '' + skip-test=BANN-7126 + skip-test=BANN-7130 + skip-test=DEB-0520 + skip-test=DEB-0810 + skip-test=FIRE-4513 + skip-test=HRDN-7222 + skip-test=KRNL-5820 + skip-test=LOGG-2190 + skip-test=LYNIS + skip-test=TOOL-5002 + ''; + mode = "0440"; + }; + }; + }; services = { samba.enable = true; diff --git a/systems/palatine-hill/docker/act-runner.nix b/systems/palatine-hill/docker/act-runner.nix index dc7fcfd..9c57225 100644 --- a/systems/palatine-hill/docker/act-runner.nix +++ b/systems/palatine-hill/docker/act-runner.nix @@ -12,6 +12,7 @@ in virtualisation.oci-containers.containers = { act-stable-latest-main = { image = "gitea/act_runner:latest"; + pull = "always"; extraOptions = [ "--stop-signal=SIGINT" ]; @@ -35,6 +36,7 @@ in act-stable-latest-1 = { image = "gitea/act_runner:latest"; + pull = "always"; extraOptions = [ "--stop-signal=SIGINT" ]; @@ -57,6 +59,7 @@ in act-stable-latest-2 = { image = "gitea/act_runner:latest"; + pull = "always"; extraOptions = [ "--stop-signal=SIGINT" ]; diff --git a/systems/palatine-hill/docker/arr.nix b/systems/palatine-hill/docker/arr.nix new file mode 100644 index 0000000..ede4c4d --- /dev/null +++ b/systems/palatine-hill/docker/arr.nix @@ -0,0 +1,124 @@ +{ + config, + lib, + pkgs, + ... +}: +let + vars = import ../vars.nix; +in +{ + virtualisation.oci-containers.containers = { + bazarr = { + image = "ghcr.io/linuxserver/bazarr:latest"; + ports = [ "6767:6767" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/bazarr:/config" + "${vars.primary_plex_storage}/data:/data" + ]; + autoStart = true; + }; + prowlarr = { + image = "ghcr.io/linuxserver/prowlarr:latest"; + ports = [ "9696:9696" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ "${vars.primary_docker}/prowlarr:/config" ]; + autoStart = true; + }; + radarr = { + image = "ghcr.io/linuxserver/radarr:latest"; + ports = [ "7878:7878" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/radarr:/config" + "${vars.primary_plex_storage}/data:/data" + ]; + autoStart = true; + }; + sonarr = { + image = "ghcr.io/linuxserver/sonarr:latest"; + ports = [ "8989:8989" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/sonarr:/config" + "${vars.primary_plex_storage}/data:/data" + ]; + autoStart = true; + }; + lidarr = { + image = "ghcr.io/linuxserver/lidarr:latest"; + ports = [ "8686:8686" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/lidarr:/config" + "${vars.primary_plex_storage}/data:/data" + ]; + autoStart = true; + }; + readarr = { + image = "ghcr.io/linuxserver/readarr:latest"; + ports = [ "8787:8787" ]; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/readarr:/config" + "${vars.primary_plex_storage}/data:/data" + ]; + autoStart = true; + }; + unpackerr = { + image = "golift/unpackerr:latest"; + user = "600:100"; + environment = { + TZ = "America/New_York"; + }; + volumes = [ + "${vars.primary_docker}/unpackerr:/config" + "${vars.primary_plex_storage}:/data" + ]; + autoStart = true; + }; + + overseerr = { + image = "lscr.io/linuxserver/overseerr"; + environment = { + PUID = "600"; + PGID = "100"; + TZ = "America/New_York"; + }; + volumes = [ "${vars.primary_docker}/overseerr:/config" ]; + # TODO: remove ports later since this is going through web + ports = [ "5055:5055" ]; # Web UI port + dependsOn = [ + "radarr" + "sonarr" + ]; + extraOptions = [ "--network=haproxy-net" ]; + autoStart = true; + }; + }; +} diff --git a/systems/palatine-hill/docker/default.nix b/systems/palatine-hill/docker/default.nix index 2af50cd..6535987 100644 --- a/systems/palatine-hill/docker/default.nix +++ b/systems/palatine-hill/docker/default.nix @@ -8,6 +8,7 @@ { imports = [ ./act-runner.nix + ./arr.nix # temp disable archiveteam for tiktok archiving #./archiveteam.nix # ./books.nix diff --git a/systems/palatine-hill/docker/glances.nix b/systems/palatine-hill/docker/glances.nix index c7757cc..8ee4117 100644 --- a/systems/palatine-hill/docker/glances.nix +++ b/systems/palatine-hill/docker/glances.nix @@ -8,6 +8,7 @@ in virtualisation.oci-containers.containers = { glances = { image = "nicolargo/glances:latest-full"; + pull = "always"; extraOptions = [ "--pid=host" "--network=haproxy-net" diff --git a/systems/palatine-hill/docker/minecraft.nix b/systems/palatine-hill/docker/minecraft.nix index 0a5d0db..07761cf 100644 --- a/systems/palatine-hill/docker/minecraft.nix +++ b/systems/palatine-hill/docker/minecraft.nix @@ -39,6 +39,7 @@ in virtualisation.oci-containers.containers = { mc-router = { image = "itzg/mc-router:latest"; + pull = "always"; extraOptions = [ "--network=haproxy-net" "--network=minecraft-net" diff --git a/systems/palatine-hill/docker/nextcloud.nix b/systems/palatine-hill/docker/nextcloud.nix index bdcb3de..132fef2 100644 --- a/systems/palatine-hill/docker/nextcloud.nix +++ b/systems/palatine-hill/docker/nextcloud.nix @@ -9,6 +9,7 @@ let nextcloud-base = { # image comes from running docker compose build in nextcloud-docker/.examples/full/apache image = "nextcloud-nextcloud"; + pull = "always"; hostname = "nextcloud"; volumes = [ "${nextcloud_path}/nc_data:/var/www/html:z" @@ -32,6 +33,7 @@ in }; redis = { image = "redis:latest"; + pull = "always"; user = "600:600"; volumes = [ "${config.sops.secrets."docker/redis".path}:/usr/local/etc/redis/redis.conf" @@ -47,6 +49,7 @@ in }; go-vod = { image = "radialapps/go-vod:latest"; + pull = "always"; dependsOn = [ "nextcloud" ]; environment = { NEXTCLOUD_HOST = "https://nextcloud.alicehuston.xyz"; @@ -58,6 +61,7 @@ in }; collabora-code = { image = "collabora/code:latest"; + pull = "always"; dependsOn = [ "nextcloud" ]; environment = { aliasgroup1 = "https://collabora.nayenoie.com:443"; diff --git a/systems/palatine-hill/docker/openvpn/se.protonvpn.udp.ovpn b/systems/palatine-hill/docker/openvpn/se.protonvpn.udp.ovpn new file mode 100644 index 0000000..8ddae2f --- /dev/null +++ b/systems/palatine-hill/docker/openvpn/se.protonvpn.udp.ovpn @@ -0,0 +1,22 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:egGgv+40qX3c1XsYFi/XNHgKHJCLlmQuDuJgf03pWSE=,tag:hxlDrxGVL848NUV8NTLo6w==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qw5k8h72k3fjg5gmlxx8q8gwlc2k6n6u08d8hdzpm2pk9r0fnfxsmw33nh", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPZ2hSTk94YmxUdXY4bHJF\nQ1hpbEtzWnRCOGpBL29pMXI0TENwS2dNa21RCkhEZ0ZQR1o0SlBaRm54ZEtMa1Fz\nMlUwaVk4dE9YWG1UTUNYeDEwd2lEQTAKLS0tIGxFaUw2M29XSlIxNFFvajE5Rm8r\nNlVRRk5PNlg0TEFwSzZpTlVIY2FRVjgKirrnI0oRNvvVndFeO6H5t6cfJ76R1cW0\nga1HqW7yYioXbgdfPDB9xO46QBPIhve4zmnBHJVYjbKos890ghh8eg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-06-01T19:09:47Z", + "mac": "ENC[AES256_GCM,data:vNM8sMxuv8HLlx4h5y8nmY0KyDDHxjTVxH7V91FT+bURXX1N+7f63xQrp7rNdZiG1InUkLWPvzdIqe0GziOWqVHL9KrAqhE151cYDJZ4f7wJ2RRORRUwtF8Sk/PY1k2Zy3qu6EPFV7QhR/lOTOAu6lsqCqDCNVGikU3Neo5wPLI=,iv:+rYkCHT6BrZC68nEFizOaD3I8SRTlyDZsXAVRhzj4gQ=,tag:s7fcM/fZxnVQJzVTAXtz8w==,type:str]", + "pgp": [ + { + "created_at": "2025-06-01T19:09:47Z", + "enc": "-----BEGIN PGP MESSAGE-----\n\nhF4DQWNzDMjrP2ISAQdA3wrVCUQjHkeFhAfrfy6h2/e+UZZhzZSGFIsyZS/v0lww\n3IoRCtHG7NmZK82PC1T5oYIFQu/CsBFvLqZThY4B7yAlV7cEG2quTvbn5BeOXzha\n0l4Be8rPGsUmbGmqnGQPZaDycfNseJZVhjJ2DWCD6PoGd0rovJQGHgFD2j/PMD41\nQE0Ek05ZMiFHmRZsNXCrYN31MBsWPjZL0IWYT7+MZswFhawEtNHLFBVpfa6o276E\n=7CRo\n-----END PGP MESSAGE-----", + "fp": "5EFFB75F7C9B74EAA5C4637547940175096C1330" + } + ], + "unencrypted_suffix": "_unencrypted", + "version": "3.10.2" + } +} diff --git a/systems/palatine-hill/docker/torr.nix b/systems/palatine-hill/docker/torr.nix index 6fe0352..a822297 100644 --- a/systems/palatine-hill/docker/torr.nix +++ b/systems/palatine-hill/docker/torr.nix @@ -1,7 +1,8 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: let delugeBase = { + pull = "always"; environment = { PUID = "600"; PGID = "100"; @@ -19,18 +20,31 @@ let deluge_path = "${torr_path}/deluge"; delugevpn_path = "${torr_path}/delugevpn"; - genSopsConf = file: { + #genSopsConfWg = file: { + # "${file}" = { + # format = "binary"; + # sopsFile = ./wg/${file}; + # path = "${delugevpn_path}/config/wireguard/configs/${file}"; + # owner = "docker-service"; + # group = "users"; + # restartUnits = [ "docker-delugeVPN.service" ]; + # }; + #}; + + genSopsConfOvpn = file: { "${file}" = { format = "binary"; - sopsFile = ./wg/${file}; - path = "${delugevpn_path}/config/wireguard/configs/${file}"; + sopsFile = ./openvpn/${file}; + path = "${delugevpn_path}/config/openvpn/configs/${file}"; owner = "docker-service"; group = "users"; restartUnits = [ "docker-delugeVPN.service" ]; }; + }; in { + virtualisation.oci-containers.containers = { deluge = delugeBase // { image = "binhex/arch-deluge"; @@ -45,25 +59,26 @@ in ]; }; delugeVPN = delugeBase // { - image = "binhex/arch-delugevpn"; - extraOptions = [ - "--privileged=true" - "--sysctl" - "net.ipv4.conf.all.src_valid_mark=1" - ]; + image = "binhex/arch-delugevpn:latest"; + capabilities = { + NET_ADMIN = true; + }; + autoRemoveOnStop = false; environment = delugeBase.environment // { VPN_ENABLED = "yes"; - VPN_CLIENT = "wireguard"; - VPN_PROV = "custom"; + VPN_CLIENT = "openvpn"; + VPN_PROV = "protonvpn"; ENABLE_PRIVOXY = "yes"; LAN_NETWORK = "192.168.0.0/16"; - NAME_SERVERS = "194.242.2.9"; + ENABLE_STARTUP_SCRIPTS = "yes"; + #NAME_SERVERS = "194.242.2.9"; + #NAME_SERVERS = "9.9.9.9"; # note, delete /config/perms.txt to force a bulk permissions update - }; + environmentFiles = [ config.sops.secrets."docker/delugevpn".path ]; volumes = [ "${delugevpn_path}/config:/config" - "${delugevpn_path}/data:/data" + "${deluge_path}/data:/data" # use common torrent path yuck "/etc/localtime:/etc/localtime:ro" ]; ports = [ @@ -71,6 +86,9 @@ in "8119:8118" "39275:39275" "39275:39275/udp" + "48346:48346" + "48346:48346/udp" + ]; }; }; @@ -79,25 +97,34 @@ in serviceConfig = { ExecStartPre = [ ( - "${pkgs.bash}/bin/bash -c \"${pkgs.findutils}/bin/find ${delugevpn_path}/config/wireguard/configs " - + "-type l -not -name wg0.conf " + "${pkgs.bash}/bin/bash -c \"${pkgs.findutils}/bin/find ${delugevpn_path}/config/openvpn/configs " + + "-type l -not -name network.ovpn " + "| ${pkgs.coreutils}/bin/shuf -n 1 " - + "| ${pkgs.findutils}/bin/xargs -I {} cp -L {} ${delugevpn_path}/config/wireguard/wg0.conf &&" - + "${pkgs.coreutils}/bin/chown docker-service:users ${delugevpn_path}/config/wireguard/wg0.conf &&" - + "${pkgs.coreutils}/bin/chmod 440 ${delugevpn_path}/config/wireguard/wg0.conf\"" + + "| ${pkgs.findutils}/bin/xargs -I {} cp -L {} ${delugevpn_path}/config/openvpn/network.ovpn &&" + + "${pkgs.coreutils}/bin/chown docker-service:users ${delugevpn_path}/config/openvpn/network.ovpn &&" + + "${pkgs.coreutils}/bin/chmod 440 ${delugevpn_path}/config/openvpn/network.ovpn\"" + ) + ( + "${pkgs.bash}/bin/bash -c \"${pkgs.findutils}/bin/find ${delugevpn_path}/config/scripts/links " + + "-type l " + + "| ${pkgs.findutils}/bin/xargs -I {} cp -L {} ${delugevpn_path}/config/scripts/ \"" ) ]; - ExecStopPost = [ "${pkgs.coreutils}/bin/rm ${delugevpn_path}/config/wireguard/wg0.conf" ]; + ExecStopPost = [ "${pkgs.coreutils}/bin/rm ${delugevpn_path}/config/scripts/*sh" ]; }; }; - sops.secrets = - (genSopsConf "se-mma-wg-001.conf") - // (genSopsConf "se-mma-wg-002.conf") - // (genSopsConf "se-mma-wg-003.conf") - // (genSopsConf "se-mma-wg-004.conf") - // (genSopsConf "se-mma-wg-005.conf") - // (genSopsConf "se-mma-wg-101.conf") - // (genSopsConf "se-mma-wg-102.conf") - // (genSopsConf "se-mma-wg-103.conf"); + sops.secrets = (genSopsConfOvpn "se.protonvpn.udp.ovpn") // { + "docker/delugevpn" = { + owner = "docker-service"; + group = "users"; + restartUnits = [ "docker-delugeVPN.service" ]; + }; + "docker/protonvpn-start-script" = { + path = "${delugevpn_path}/config/scripts/links/protonvpn-start-script.sh"; + owner = "docker-service"; + group = "users"; + restartUnits = [ "docker-delugeVPN.service" ]; + }; + }; } diff --git a/systems/palatine-hill/firewall.nix b/systems/palatine-hill/firewall.nix index f43e9c9..33ffd45 100644 --- a/systems/palatine-hill/firewall.nix +++ b/systems/palatine-hill/firewall.nix @@ -24,6 +24,15 @@ # collabora 9980 + + # arr + 6767 + 9696 + 7878 + 8989 + 8686 + 8787 + 5055 ]; } diff --git a/systems/palatine-hill/hydra.nix b/systems/palatine-hill/hydra.nix index a9c92d8..d265715 100644 --- a/systems/palatine-hill/hydra.nix +++ b/systems/palatine-hill/hydra.nix @@ -82,10 +82,10 @@ in ''; }; - nix-serve = { - enable = true; - secretKeyFile = config.sops.secrets."nix-serve/secret-key".path; - }; + # nix-serve = { + # enable = true; + # secretKeyFile = config.sops.secrets."nix-serve/secret-key".path; + # }; prometheus = { enable = true; webExternalUrl = "https://prom.alicehuston.xyz"; @@ -134,7 +134,7 @@ in sops = { secrets = { "hydra/environment".owner = "hydra"; - "nix-serve/secret-key".owner = "root"; + # "nix-serve/secret-key".owner = "root"; "alice/gha-hydra-token" = { sopsFile = ../../users/alice/secrets.yaml; owner = "hydra"; diff --git a/systems/palatine-hill/plex/default.nix b/systems/palatine-hill/plex/default.nix new file mode 100644 index 0000000..95d2a1f --- /dev/null +++ b/systems/palatine-hill/plex/default.nix @@ -0,0 +1,28 @@ +{ + pkgs, + ... +}: +let + vars = import ../vars.nix; +in +{ + services.plex = { + enable = true; + dataDir = vars.primary_plex; + }; + systemd.services.plex_permission = { + description = "maintains plex permissions"; + serviceConfig = { + Type = "oneshot"; + ExecStart = "${pkgs.bash}/bin/bash ${./plex_permission.sh}"; + }; + }; + systemd.timers.plex_permission = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnBootSec = "1h"; + OnCalendar = "daily 03:00"; + Unit = "plex_permission.service"; + }; + }; +} diff --git a/systems/palatine-hill/plex/plex_permission.sh b/systems/palatine-hill/plex/plex_permission.sh new file mode 100644 index 0000000..bbea0a1 --- /dev/null +++ b/systems/palatine-hill/plex/plex_permission.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +plex_dir="/ZFS/ZFS-primary/plex" + +chown docker-service:users -R "$plex_dir" +find "$plex_dir" -type f -exec chmod 664 {} \; +find "$plex_dir" -type d -exec chmod 775 {} \; diff --git a/systems/palatine-hill/secrets.yaml b/systems/palatine-hill/secrets.yaml index c1afa14..3cfed62 100644 --- a/systems/palatine-hill/secrets.yaml +++ b/systems/palatine-hill/secrets.yaml @@ -23,6 +23,8 @@ docker: redis: ENC[AES256_GCM,data:c+55cN6IpUNeKd+wC2zv3eunYjBsmZtXTczokqaxB2Q=,iv:M3pwNUlT9kUMv4JDE6bp/gub9CdBGxdApIvpOt3JpgE=,tag:3rPlV3U0AP9zAeF7xDouKw==,type:str] act-runner: ENC[AES256_GCM,data:gdrqXBBzdMW26MgNfP6P1c/m7pLANCXjcZLvVsxlWcgpAZd8IaO2FUqomL3xFI3UDPveQh0UvC3044ueoWhYJOq7ZmKJGvdf0ZrpP1MkXZKvjFjbTsuf/6/SYKhPqnP28HqznUWIVJYcRmP+A2oVeJY=,iv:/yOqJYDpxbqCm1whqcypp7Ba1Xlaebrv+h6lHr57Qa8=,tag:PzVqxP+QwQq69jqhmagj3w==,type:str] collabora: ENC[AES256_GCM,data:LPRkzPEv5qfzeWSDbf+L+0asfmiK5Mhj8jCdfVyvVQAaD75Cbo4qLD0Nc80z,iv:/l2vAyYYJChhv6T+JkHT4I74ZpdhvbVqxlDWIM4Y4bw=,tag:/+uzn1vtd1RnO9/lGiQAKA==,type:str] + delugevpn: ENC[AES256_GCM,data:YGkgaQUuA9oteKD77tnFzxZSHctyOQjMNlfvJr3mPWAl2P8wfcshiUoa6SNp69pagxbzRV6mfuzwzinbkQCoZN3lw7uF76y0,iv:Bro0H4tFR+3wi9DGGq9a6ge4o4uPlVXBUF7h17zyqg8=,tag:N1kVNFasqGMx8R9qTq2dJA==,type:str] + protonvpn-start-script: ENC[AES256_GCM,data:ZnlDpCLdILHXSUCI6itWkqO4y75Lwjj7qT1DBkfueLneQOaQ0JhuE2FbOOajkmI046nP9fMrJbu3g4QZHsq1g8yqGU1wb0OOT+eS9+M92Md29B4NnUdwnVAO6/RzvRKXP2tsQ4iprx9An+BEFwZYD6WG6DQc6NjJVSgRcYvfH9rQey2VdwLysNsgFCs8eC6QgikqBpeg4eOIvDDNbdXPKkW+ZPph9xpzGkcFIMwlX5esg0n7qyUoMvWwBn4avC46U5erOw0fNajY60ri9sm5Afht6LZrFal71Hx/K9/5EXBp9dD4teLO2Ew0CQX0i94pKCuR207l9868s7Ao3udLp4wbiLnXoRKq+w==,iv:qR0kNYpb50NXEqSksvHBPAaRG51RKCsSwTq32nosxzo=,tag:+xRQyuWi4Ja/N9lcd11oJA==,type:str] acme: bunny: ENC[AES256_GCM,data:P2yROVUga9mORcq8VR/l0i4/2Vod1zvlYq+ZJLLNKow0SpblkwQX/i1ucQYAOkTTRddN+3C+t0zj1rMWkdLoaLjEUJJi3VsSxi+chV2FFiVKFQGEcg24,iv:aQvGgGLsgRGoEmwTgZHR8Jm/MYxmGtVTT/fZKaTLeMs=,tag:m3ssF4O8qs4yxvMu6yUcjw==,type:str] dnsimple: ENC[AES256_GCM,data:37FKyBibFtXZgI4EduJQ0z8F+shBc5Q6YlLa3YkVPh9XuJVS20eybi75bfJxiozcZ9d+YRaqcbkBQCSdFOCotDU=,iv:oq3JjqbfAm2C4jcL1lvUb2EOmnwlR07vPoO8H0BmydQ=,tag:E3NO/jMElL6Q817666gIyg==,type:str] @@ -41,8 +43,8 @@ sops: cXNZWmZqd0R0SmhINExscHBKWmxvblUKEFEQvt/zQFARba4S8vHz/1SoKdKg69At LZ58XQGOmlGbBhPr7EzYQ2XSY4flWbnnD174cmCR8DNFm15DsNA5fw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-05-30T04:36:41Z" - mac: ENC[AES256_GCM,data:fEsUt5g0/7j8IVgtXQ0thV93dxe6SGCglqeHdnaXFOjKcCUEFWUmi98M8X92hR9AJzscRK6wqzijd/AQBzl+GL2QtDYsn8qx9Nr0DBd6Gh1vi25eh5LtADm09COSae1THWuFLP7L1Qamyt+XzlBa7Xnrzfuzzp0s2/cZoxZiueU=,iv:VYzh833cMQwGmkB6QunRys0Eluz+0KGj8Y43B9icE9w=,tag:EWJSizBMTFZ0TZhncYe2Sw==,type:str] + lastmodified: "2025-06-01T23:54:50Z" + mac: ENC[AES256_GCM,data:xBSrKfuBEXYVqLhZF903HbLaCpgXyuo3r7/FUBPM9Pl+rKUGx8p7LKCIec2NPCGO8ylQvC8T2mochSHSAvN339nxPlQ7f/tKWc6QgicaX4Sb4k0wJdqamSJTq4mkg8482HOUiFCSi3lA3zWC3Y9ZixESmEWTbxe9sQ51Vo69lkw=,iv:XiGVzryZwo5UmJe7I8pkg5IEdms0vR9iRdlFu2wjUeI=,tag:jhOuV+aZd5rQF0xg+0tvOg==,type:str] pgp: - created_at: "2024-11-28T18:56:39Z" enc: |- diff --git a/systems/palatine-hill/vars.nix b/systems/palatine-hill/vars.nix index 9b06ade..8566078 100644 --- a/systems/palatine-hill/vars.nix +++ b/systems/palatine-hill/vars.nix @@ -17,4 +17,6 @@ rec { primary_nextcloud = "${zfs_primary}/nextcloud"; primary_redis = "${zfs_primary}/redis"; primary_torr = "${zfs_primary}/torr"; + primary_plex = "${zfs_primary}/plex"; + primary_plex_storage = "${zfs_primary}/plex_storage"; } diff --git a/users/default.nix b/users/default.nix index bd221ef..0149557 100644 --- a/users/default.nix +++ b/users/default.nix @@ -14,6 +14,7 @@ hashedPasswordFile = config.sops.secrets."${name}/user-password".path or null; openssh.authorizedKeys.keys = publicKeys; extraGroups = [ + "users" "wheel" "media" (lib.mkIf config.networking.networkmanager.enable "networkmanager")