feat(deertopia): *Arr suite
This commit is contained in:
@@ -20,9 +20,11 @@ in {
|
||||
nixpkgs.overlays = [ inputs.copyparty.overlays.default ];
|
||||
|
||||
# HACK: Ad-hoc permissions, as typical.
|
||||
users.users.copyparty.extraGroups = [ "jellyfin" ];
|
||||
users.users.copyparty.extraGroups = [
|
||||
"media"
|
||||
];
|
||||
|
||||
# HACK: Make files created by copypaste.service initialise with the mode
|
||||
# HACK: Make files created by copyparty.service initialise with the mode
|
||||
# 775.
|
||||
systemd.services.copyparty.serviceConfig.UMask = lib.mkForce "002";
|
||||
|
||||
@@ -46,12 +48,17 @@ in {
|
||||
path = "/var/lib/slskd";
|
||||
access.r = "*";
|
||||
};
|
||||
"/Jellyfin" = {
|
||||
path = "/persist/vault/jellyfin";
|
||||
"/Media library" = {
|
||||
path = "/persist/media/library";
|
||||
# View and upload, but no deleting.
|
||||
access.rw = "*";
|
||||
access.rwmd = "@jellyfin-admin";
|
||||
};
|
||||
"/Torrents" = {
|
||||
path = "/persist/media/torrents";
|
||||
access.r = "*";
|
||||
access.rwmd = "@jellyfin-admin";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ in
|
||||
|
||||
vhosts = lib.mkOption {
|
||||
# NOTE: `name` shouldn't contain spaces.
|
||||
default = {};
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
||||
options = {
|
||||
enable = lib.mkOption {
|
||||
|
||||
96
modules/nixos/deertopia/servarr.nix
Normal file
96
modules/nixos/deertopia/servarr.nix
Normal file
@@ -0,0 +1,96 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr = {
|
||||
enable = lib.mkEnableOption "Deertopia's *arr suite";
|
||||
peer = lib.mkOption {
|
||||
default = "us-den-wg-101";
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
The name of a Wireguard configuration file in
|
||||
modules/nixos/deertopia/mullvad/, without the .conf suffix. Ideally, we
|
||||
would support multiple peers without rebuilding, but...
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
imports = [
|
||||
./servarr/jellyfin.nix
|
||||
./servarr/lidarr.nix
|
||||
./servarr/prowlarr.nix
|
||||
./servarr/sabnzbd.nix
|
||||
./servarr/sonarr.nix
|
||||
./servarr/radarr.nix
|
||||
./servarr/transmission.nix
|
||||
# ./servarr/slskd.nix
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sydnix.impermanence.directories = [
|
||||
# "All services support state management and all state that they manage is
|
||||
# located by default in /data/.state/nixarr/*"
|
||||
# See https://nixarr.com/nixos-options/
|
||||
config.nixarr.stateDir
|
||||
];
|
||||
|
||||
# Mount our NAS's 'media' share.
|
||||
fileSystems."/persist/media/library" = {
|
||||
# DNS is seemingly unavailable to the mount service.
|
||||
device = "//192.168.68.62/media";
|
||||
mountPoint = "/persist/media/library";
|
||||
fsType = "cifs";
|
||||
options = [
|
||||
"vers=2.0"
|
||||
"cred=/run/secrets/buffalo-nas-creds"
|
||||
# It appears that the group/user names used by Nixarr are hard-coded.
|
||||
"gid=media"
|
||||
"uid=streamer"
|
||||
# Mysteriously, 0664 doesn't work…
|
||||
"dir_mode=0770"
|
||||
"file_mode=0770"
|
||||
];
|
||||
};
|
||||
|
||||
sydnix.sops.secrets.wireguard-mullvad-key = {};
|
||||
|
||||
systemd.services."create-wireguard-config" = {
|
||||
script = ''
|
||||
wgConf="${config.nixarr.stateDir}/wg.conf"
|
||||
cp "/persist/dots/modules/nixos/deertopia/mullvad/${cfg.peer}.conf" \
|
||||
"$wgConf"
|
||||
${pkgs.replace-secret}/bin/replace-secret \
|
||||
'{{WG_PRIVATE_KEY}}' \
|
||||
/run/secrets/wireguard-mullvad-key \
|
||||
"$wgConf"
|
||||
${pkgs.gnused}/bin/sed -i -e 's/^DNS.*/DNS = 1.1.1.1/' "$wgConf"
|
||||
chmod 700 "$wgConf"
|
||||
chown root "$wgConf"
|
||||
'';
|
||||
requiredBy = [ "wg.service" ];
|
||||
};
|
||||
|
||||
systemd.services.test-mullvad-connection = {
|
||||
script = ''
|
||||
${pkgs.curl}/bin/curl -s https://am.i.mullvad.net/connected >&2
|
||||
${pkgs.curl}/bin/curl -s https://am.i.mullvad.net/connected 2>/dev/null
|
||||
'';
|
||||
vpnconfinement = {
|
||||
enable = true;
|
||||
vpnnamespace = "wg";
|
||||
};
|
||||
};
|
||||
|
||||
nixarr = {
|
||||
enable = true;
|
||||
# The default value is overly anti-FHS.
|
||||
stateDir = "/var/lib/nixarr";
|
||||
mediaDir = "/persist/media";
|
||||
vpn = {
|
||||
enable = true;
|
||||
wgConf = "${config.nixarr.stateDir}/wg.conf";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
67
modules/nixos/deertopia/servarr/jellyfin.nix
Normal file
67
modules/nixos/deertopia/servarr/jellyfin.nix
Normal file
@@ -0,0 +1,67 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.jellyfin;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.jellyfin = {
|
||||
enable = lib.mkEnableOption "Jellyfin (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sydnix.deertopia.nginx.vhosts."watch".vhost =
|
||||
# Currently no (convenient) way to specify Jellyfin's port from Nix.
|
||||
let port = builtins.toString 8096;
|
||||
in {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".extraConfig = ''
|
||||
# Proxy main Jellyfin traffic.
|
||||
proxy_pass $jellyfin;
|
||||
proxy_set_header Host $host;
|
||||
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 $scheme;
|
||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
|
||||
# Disable buffering when the nginx proxy gets very resource heavy upon
|
||||
# streaming.
|
||||
proxy_buffering off;
|
||||
'';
|
||||
locations."/socket".extraConfig = ''
|
||||
# Proxy Jellyfin Websockets traffic
|
||||
proxy_pass $jellyfin;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
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 $scheme;
|
||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
'';
|
||||
extraConfig = ''
|
||||
set $jellyfin http://127.0.0.1:${port};
|
||||
'';
|
||||
};
|
||||
|
||||
nixarr.jellyfin = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
sydnix.deertopia.nginx.vhosts."jellyseer".vhost =
|
||||
# Currently no (convenient) way to specify Jellyfin's port from Nix.
|
||||
let port = builtins.toString 8096;
|
||||
in {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/".proxyPass = "http://127.0.0.1:5055";
|
||||
};
|
||||
|
||||
nixarr.jellyseerr = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
33
modules/nixos/deertopia/servarr/lidarr.nix
Normal file
33
modules/nixos/deertopia/servarr/lidarr.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.lidarr;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.lidarr = {
|
||||
enable = lib.mkEnableOption "Lidarr (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sydnix.deertopia.nginx.vhosts."lidarr" = {
|
||||
directory = null;
|
||||
vhost = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = ''
|
||||
# include ${../authelia/authelia-location.conf};
|
||||
set $upstream http://127.0.0.1:8686;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
# include ${../authelia/authelia-authrequest.conf};
|
||||
# include ${../authelia/proxy.conf};
|
||||
proxy_pass $upstream;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
nixarr.lidarr = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
32
modules/nixos/deertopia/servarr/prowlarr.nix
Normal file
32
modules/nixos/deertopia/servarr/prowlarr.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.prowlarr;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.prowlarr = {
|
||||
enable = lib.mkEnableOption "Prowlarr (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixarr.prowlarr = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
sydnix.deertopia.nginx.vhosts."prowlarr" = {
|
||||
directory = null;
|
||||
vhost = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = ''
|
||||
# include ${../authelia/authelia-location.conf};
|
||||
set $upstream http://127.0.0.1:9696;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
# include ${../authelia/authelia-authrequest.conf};
|
||||
# include ${../authelia/proxy.conf};
|
||||
proxy_pass $upstream;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
33
modules/nixos/deertopia/servarr/radarr.nix
Normal file
33
modules/nixos/deertopia/servarr/radarr.nix
Normal file
@@ -0,0 +1,33 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.radarr;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.radarr = {
|
||||
enable = lib.mkEnableOption "Radarr (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixarr.radarr = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
sydnix.deertopia.nginx.vhosts."radarr" = {
|
||||
directory = null;
|
||||
vhost = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = ''
|
||||
# include ${../authelia/authelia-location.conf};
|
||||
set $upstream http://127.0.0.1:7878;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
# include ${../authelia/authelia-authrequest.conf};
|
||||
# include ${../authelia/proxy.conf};
|
||||
proxy_pass $upstream;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
17
modules/nixos/deertopia/servarr/sabnzbd.nix
Normal file
17
modules/nixos/deertopia/servarr/sabnzbd.nix
Normal file
@@ -0,0 +1,17 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.sabnzbd;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.sabnzbd = {
|
||||
enable = lib.mkEnableOption "SABnzbd (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixarr.sabnzbd = {
|
||||
enable = true;
|
||||
# vpn.enable = true;
|
||||
openFirewall = true;
|
||||
guiPort = 43288;
|
||||
};
|
||||
};
|
||||
}
|
||||
74
modules/nixos/deertopia/servarr/slskd.nix
Normal file
74
modules/nixos/deertopia/servarr/slskd.nix
Normal file
@@ -0,0 +1,74 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.slskd;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.slskd = {
|
||||
enable = lib.mkEnableOption "Slskd (à la Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sydnix.sops.secrets.slskd-credentials = {
|
||||
owner = "torrenter";
|
||||
};
|
||||
|
||||
# TODO: Patch Nixpkgs to add option services.slskd.appDir.
|
||||
|
||||
services.slskd = {
|
||||
enable = true;
|
||||
user = "torrenter";
|
||||
group = "media";
|
||||
|
||||
openFirewall = true;
|
||||
domain = null;
|
||||
environmentFile = "/run/secrets/slskd-credentials";
|
||||
|
||||
settings = {
|
||||
# Disable slskd's authentication in favour of Authelia.
|
||||
web.authentication.disabled = true;
|
||||
shares.directories = [
|
||||
config.nixarr.mediaDir
|
||||
];
|
||||
directories = {
|
||||
downloads = "/var/lib/slskd/downloads";
|
||||
incomplete = "/var/lib/slskd/incomplete";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
config.services.slskd.settings.web.port
|
||||
];
|
||||
|
||||
sydnix.deertopia.nginx.vhosts."slsk" = {
|
||||
directory = null;
|
||||
vhost = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig =
|
||||
let port = builtins.toString config.services.slskd.settings.web.port;
|
||||
in ''
|
||||
include ${../authelia/authelia-location.conf};
|
||||
set $upstream http://127.0.0.1:${port};
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
include ${../authelia/authelia-authrequest.conf};
|
||||
include ${../authelia/proxy.conf};
|
||||
proxy_pass $upstream;
|
||||
'';
|
||||
locations."/hub".extraConfig = ''
|
||||
proxy_pass $upstream;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
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 $scheme;
|
||||
proxy_set_header X-Forwarded-Protocol $scheme;
|
||||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
32
modules/nixos/deertopia/servarr/sonarr.nix
Normal file
32
modules/nixos/deertopia/servarr/sonarr.nix
Normal file
@@ -0,0 +1,32 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.sonarr;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.sonarr = {
|
||||
enable = lib.mkEnableOption "Sonarr (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
nixarr.sonarr = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
};
|
||||
|
||||
sydnix.deertopia.nginx.vhosts."sonarr" = {
|
||||
directory = null;
|
||||
vhost = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
extraConfig = ''
|
||||
# include ${../authelia/authelia-location.conf};
|
||||
set $upstream http://127.0.0.1:8989;
|
||||
'';
|
||||
locations."/".extraConfig = ''
|
||||
# include ${../authelia/authelia-authrequest.conf};
|
||||
# include ${../authelia/proxy.conf};
|
||||
proxy_pass $upstream;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
24
modules/nixos/deertopia/servarr/transmission.nix
Normal file
24
modules/nixos/deertopia/servarr/transmission.nix
Normal file
@@ -0,0 +1,24 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config.sydnix.deertopia.servarr.transmission;
|
||||
in {
|
||||
options.sydnix.deertopia.servarr.transmission = {
|
||||
enable = lib.mkEnableOption "Transmission (via Nixarr)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
sydnix.sops.secrets.transmission-credentials = {
|
||||
owner = config.services.transmission.user;
|
||||
group = config.services.transmission.group;
|
||||
mode = "700";
|
||||
};
|
||||
|
||||
nixarr.transmission = {
|
||||
enable = true;
|
||||
vpn.enable = true;
|
||||
credentialsFile = "/run/secrets/transmission-credentials";
|
||||
# Default (9091) conflicts with Authelia.
|
||||
uiPort = 7052;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -22,11 +22,12 @@ in {
|
||||
# Disable slskd's authentication in favour of Authelia.
|
||||
web.authentication.disabled = true;
|
||||
shares.directories = [
|
||||
"/persist/vault/jellyfin/Music"
|
||||
"/persist/vault/jellyfin/Shows"
|
||||
"/persist/vault/jellyfin/Documents"
|
||||
"/persist/vault/jellyfin/Music Videos"
|
||||
"/persist/vault/jellyfin/Movies"
|
||||
"/persist/media/library"
|
||||
# "/persist/vault/jellyfin/Music"
|
||||
# "/persist/vault/jellyfin/Shows"
|
||||
# "/persist/vault/jellyfin/Documents"
|
||||
# "/persist/vault/jellyfin/Music Videos"
|
||||
# "/persist/vault/jellyfin/Movies"
|
||||
];
|
||||
# directories.downloads = "/persist/vault/jellyfin/Music";
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user