Merge pull request 'feature/add-overseerr' (#120) from feature/add-overseerr into main
All checks were successful
Check flake.lock / Check health of `flake.lock` (push) Successful in 8s
Check Nix flake / Perform Nix flake checks (push) Successful in 3m32s
Update flakes / update_lockfile (push) Successful in 12m22s

Reviewed-on: #120
This commit is contained in:
ahuston-0 2025-06-03 01:03:59 -04:00
commit ac210e99c3
22 changed files with 330 additions and 58 deletions

View File

@ -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"

View File

@ -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

View File

@ -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`"

View File

@ -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

11
modules/users.nix Normal file
View File

@ -0,0 +1,11 @@
{
...
}:
{
users.groups = {
users = {
gid = 100;
};
};
}

View File

@ -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;

View File

@ -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;

View File

@ -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"
];

View File

@ -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;
};
};
}

View File

@ -8,6 +8,7 @@
{
imports = [
./act-runner.nix
./arr.nix
# temp disable archiveteam for tiktok archiving
#./archiveteam.nix
# ./books.nix

View File

@ -8,6 +8,7 @@ in
virtualisation.oci-containers.containers = {
glances = {
image = "nicolargo/glances:latest-full";
pull = "always";
extraOptions = [
"--pid=host"
"--network=haproxy-net"

View File

@ -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"

View File

@ -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";

File diff suppressed because one or more lines are too long

View File

@ -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" ];
};
};
}

View File

@ -24,6 +24,15 @@
# collabora
9980
# arr
6767
9696
7878
8989
8686
8787
5055
];
}

View File

@ -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";

View File

@ -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";
};
};
}

View File

@ -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 {} \;

View File

@ -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: |-

View File

@ -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";
}

View File

@ -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")