mirror of
https://github.com/alyraffauf/nixcfg.git
synced 2024-11-21 20:33:55 -05:00
move raffauflabsModules to separate git repo (#12)
* remove from flake + delete files * README: add raffauflabs modules link
This commit is contained in:
parent
347c343742
commit
58039a6563
|
@ -1,5 +1,5 @@
|
||||||
# nixcfg
|
# nixcfg
|
||||||
NixOS flake for all mine + my husband's hosts, including modules for Hyprland, Sway, GNOME, and a variety of Home lab services running on a mix of nix-native and OCI containers. Built with [agenix](https://github.com/ryantm/agenix) for managing secrets, [disko](https://github.com/nix-community/disko) for automatically partioning drives, and [home-manager](https://github.com/nix-community/home-manager) for managing dotfiles and home configuration.
|
NixOS flake for all mine + my husband's hosts, including modules for Hyprland, Sway, GNOME, and a variety of [home lab](https://github.com/alyraffauf/raffauflabs) services running on a mix of nix-native and OCI containers. Built with [agenix](https://github.com/ryantm/agenix) for managing secrets, [disko](https://github.com/nix-community/disko) for automatically partioning drives, and [home-manager](https://github.com/nix-community/home-manager) for managing dotfiles and home configuration.
|
||||||
|
|
||||||
## Rice
|
## Rice
|
||||||
![](./_img/hyprland.png)
|
![](./_img/hyprland.png)
|
||||||
|
|
23
flake.lock
23
flake.lock
|
@ -563,6 +563,26 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"raffauflabs": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1720224769,
|
||||||
|
"narHash": "sha256-n2wxe8CDZCMRmA7PXN/+OAoqvoDu+hbqmVNKNMyDX8Q=",
|
||||||
|
"owner": "alyraffauf",
|
||||||
|
"repo": "raffauflabs",
|
||||||
|
"rev": "912f73b0d0891ac272721c60ae2da43dbf06778b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "alyraffauf",
|
||||||
|
"repo": "raffauflabs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"agenix": "agenix",
|
"agenix": "agenix",
|
||||||
|
@ -573,7 +593,8 @@
|
||||||
"nixpkgs": "nixpkgs_2",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"nixpkgsUnstable": "nixpkgsUnstable",
|
"nixpkgsUnstable": "nixpkgsUnstable",
|
||||||
"nixvim": "nixvim",
|
"nixvim": "nixvim",
|
||||||
"nur": "nur"
|
"nur": "nur",
|
||||||
|
"raffauflabs": "raffauflabs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Automated disk partitioning.
|
||||||
|
raffauflabs = {
|
||||||
|
url = "github:alyraffauf/raffauflabs";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
|
||||||
## Motion sensor and auto-rotate for Hyprland.
|
## Motion sensor and auto-rotate for Hyprland.
|
||||||
iio-hyprland = {
|
iio-hyprland = {
|
||||||
url = "github:JeanSchoeller/iio-hyprland";
|
url = "github:JeanSchoeller/iio-hyprland";
|
||||||
|
@ -114,8 +120,10 @@
|
||||||
inputs.hyprland.nixosModules.default
|
inputs.hyprland.nixosModules.default
|
||||||
inputs.nixvim.nixosModules.nixvim
|
inputs.nixvim.nixosModules.nixvim
|
||||||
inputs.nur.nixosModules.nur
|
inputs.nur.nixosModules.nur
|
||||||
|
inputs.raffauflabs.nixosModules.raffauflabs
|
||||||
self.nixosModules.hardware
|
self.nixosModules.hardware
|
||||||
self.nixosModules.nixos
|
self.nixosModules.nixos
|
||||||
|
|
||||||
{
|
{
|
||||||
home-manager = {
|
home-manager = {
|
||||||
backupFileExtension = "backup";
|
backupFileExtension = "backup";
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
# Custom desktop with AMD Ryzen 5 2600, 16GB RAM, AMD Rx 6700, and 1TB SSD + 2TB HDD.
|
# Custom desktop with AMD Ryzen 5 2600, 16GB RAM, AMD Rx 6700, and 1TB SSD + 2TB HDD.
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
input,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
self,
|
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
acmeEmail = "alyraffauf@gmail.com";
|
archiveDirectory = "/mnt/Archive";
|
||||||
hostName = "mauville";
|
|
||||||
domain = "raffauflabs.com";
|
domain = "raffauflabs.com";
|
||||||
mediaDirectory = "/mnt/Media";
|
mediaDirectory = "/mnt/Media";
|
||||||
archiveDirectory = "/mnt/Archive";
|
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./filesystems.nix
|
./filesystems.nix
|
||||||
|
@ -21,7 +17,26 @@ in {
|
||||||
|
|
||||||
age.secrets = {
|
age.secrets = {
|
||||||
cloudflare.file = ../../secrets/cloudflare.age;
|
cloudflare.file = ../../secrets/cloudflare.age;
|
||||||
nixCache.file = ../../secrets/nixCache/privKey.age;
|
|
||||||
|
lastfmId = {
|
||||||
|
owner = "navidrome";
|
||||||
|
file = ../../secrets/lastFM/apiKey.age;
|
||||||
|
};
|
||||||
|
|
||||||
|
lastfmSecret = {
|
||||||
|
owner = "navidrome";
|
||||||
|
file = ../../secrets/lastFM/secret.age;
|
||||||
|
};
|
||||||
|
|
||||||
|
spotifyId = {
|
||||||
|
owner = "navidrome";
|
||||||
|
file = ../../secrets/spotify/clientId.age;
|
||||||
|
};
|
||||||
|
|
||||||
|
spotifySecret = {
|
||||||
|
owner = "navidrome";
|
||||||
|
file = ../../secrets/spotify/clientSecret.age;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.loader = {
|
boot.loader = {
|
||||||
|
@ -29,217 +44,9 @@ in {
|
||||||
systemd-boot.enable = true;
|
systemd-boot.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "23.11";
|
networking.hostName = "mauville";
|
||||||
|
|
||||||
networking = {
|
|
||||||
firewall = {
|
|
||||||
allowedTCPPorts = [
|
|
||||||
80
|
|
||||||
443
|
|
||||||
config.ar.containers.oci.transmission.port
|
|
||||||
config.ar.containers.oci.transmission.bitTorrentPort
|
|
||||||
];
|
|
||||||
|
|
||||||
allowedUDPPorts = [config.ar.containers.oci.transmission.bitTorrentPort];
|
|
||||||
};
|
|
||||||
|
|
||||||
# My router doesn't expose settings for NAT loopback
|
|
||||||
# So we have to use this workaround.
|
|
||||||
extraHosts = ''
|
|
||||||
127.0.0.1 git.${domain}
|
|
||||||
127.0.0.1 music.${domain}
|
|
||||||
127.0.0.1 news.${domain}
|
|
||||||
127.0.0.1 nixcache.${domain}
|
|
||||||
127.0.0.1 plex.${domain}
|
|
||||||
127.0.0.1 podcasts.${domain}
|
|
||||||
'';
|
|
||||||
|
|
||||||
hostName = hostName;
|
|
||||||
};
|
|
||||||
|
|
||||||
security.acme = {
|
|
||||||
acceptTerms = true;
|
|
||||||
defaults.email = acmeEmail;
|
|
||||||
};
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
ddclient = {
|
|
||||||
enable = true;
|
|
||||||
domains = [
|
|
||||||
"git.raffauflabs.com"
|
|
||||||
"music.raffauflabs.com"
|
|
||||||
"plex.raffauflabs.com"
|
|
||||||
"podcasts.raffauflabs.com"
|
|
||||||
"raffauflabs.com"
|
|
||||||
];
|
|
||||||
interval = "10min";
|
|
||||||
passwordFile = config.age.secrets.cloudflare.path;
|
|
||||||
protocol = "cloudflare";
|
|
||||||
ssl = true;
|
|
||||||
use = "web, web=dynamicdns.park-your-domain.com/getip, web-skip='Current IP Address: '";
|
|
||||||
username = "token";
|
|
||||||
zone = "raffauflabs.com";
|
|
||||||
};
|
|
||||||
|
|
||||||
fail2ban.enable = true;
|
|
||||||
|
|
||||||
forgejo = {
|
|
||||||
enable = true;
|
|
||||||
lfs.enable = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
actions = {
|
|
||||||
ENABLED = true;
|
|
||||||
DEFAULT_ACTIONS_URL = "https://github.com";
|
|
||||||
};
|
|
||||||
|
|
||||||
cron = {
|
|
||||||
ENABLED = true;
|
|
||||||
RUN_AT_START = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFAULT.APP_NAME = "Git @ RaffaufLabs.com";
|
|
||||||
|
|
||||||
repository = {
|
|
||||||
DEFAULT_BRANCH = "master";
|
|
||||||
ENABLE_PUSH_CREATE_ORG = true;
|
|
||||||
ENABLE_PUSH_CREATE_USER = true;
|
|
||||||
PREFERRED_LICENSES = "GPL-3.0";
|
|
||||||
};
|
|
||||||
|
|
||||||
federation.ENABLED = true;
|
|
||||||
picture.ENABLE_FEDERATED_AVATAR = true;
|
|
||||||
security.PASSWORD_CHECK_PWN = true;
|
|
||||||
|
|
||||||
server = {
|
|
||||||
LANDING_PAGE = "explore";
|
|
||||||
ROOT_URL = "https://git.${domain}/";
|
|
||||||
};
|
|
||||||
|
|
||||||
service = {
|
|
||||||
ALLOW_ONLY_INTERNAL_REGISTRATION = true;
|
|
||||||
DISABLE_REGISTRATION = false;
|
|
||||||
ENABLE_NOTIFY_MAIL = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
session.COOKIE_SECURE = true;
|
|
||||||
|
|
||||||
ui.DEFAULT_THEME = "forgejo-auto";
|
|
||||||
"ui.meta" = {
|
|
||||||
AUTHOR = "Git @ RaffaufLabs.com";
|
|
||||||
DESCRIPTION = "Self-hosted git projects + toys.";
|
|
||||||
KEYWORDS = "git,forge,forgejo,aly raffauf";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
nginx = {
|
|
||||||
enable = true;
|
|
||||||
recommendedGzipSettings = true;
|
|
||||||
recommendedProxySettings = true;
|
|
||||||
recommendedTlsSettings = true;
|
|
||||||
|
|
||||||
virtualHosts = {
|
|
||||||
"git.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://${config.services.forgejo.settings.server.HTTP_ADDR}:${toString config.services.forgejo.settings.server.HTTP_PORT}";
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 512M;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"music.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString config.ar.services.navidrome.port}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"news.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString config.ar.containers.oci.freshRSS.port}";
|
|
||||||
proxyWebsockets = true; # needed if you need to use WebSocket
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_redirect off;
|
|
||||||
# Forward the Authorization header for the Google Reader API.
|
|
||||||
proxy_pass_header Authorization;
|
|
||||||
proxy_set_header Authorization $http_authorization;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"nixcache.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${
|
|
||||||
toString config.services.nix-serve.port
|
|
||||||
}";
|
|
||||||
};
|
|
||||||
|
|
||||||
"plex.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString config.ar.containers.oci.plexMediaServer.port}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
"podcasts.${domain}" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://127.0.0.1:${toString config.ar.containers.oci.audiobookshelf.port}";
|
|
||||||
|
|
||||||
extraConfig = ''
|
|
||||||
client_max_body_size 500M;
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_redirect http:// https://;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
nix-serve = {
|
|
||||||
enable = true;
|
|
||||||
secretKeyFile = config.age.secrets.nixCache.path;
|
|
||||||
};
|
|
||||||
|
|
||||||
ollama = {
|
|
||||||
enable = true;
|
|
||||||
acceleration = "rocm";
|
|
||||||
};
|
|
||||||
|
|
||||||
samba = {
|
samba = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openFirewall = true;
|
||||||
|
@ -248,7 +55,7 @@ in {
|
||||||
shares = {
|
shares = {
|
||||||
Media = {
|
Media = {
|
||||||
browseable = "yes";
|
browseable = "yes";
|
||||||
comment = "Media @ ${hostName}";
|
comment = "Media @ ${config.networking.hostName}";
|
||||||
path = mediaDirectory;
|
path = mediaDirectory;
|
||||||
"read only" = "no";
|
"read only" = "no";
|
||||||
"guest ok" = "yes";
|
"guest ok" = "yes";
|
||||||
|
@ -258,7 +65,7 @@ in {
|
||||||
|
|
||||||
Archive = {
|
Archive = {
|
||||||
browseable = "yes";
|
browseable = "yes";
|
||||||
comment = "Archive @ ${hostName}";
|
comment = "Archive @ ${config.networking.hostName}";
|
||||||
path = archiveDirectory;
|
path = archiveDirectory;
|
||||||
"create mask" = "0755";
|
"create mask" = "0755";
|
||||||
"directory mask" = "0755";
|
"directory mask" = "0755";
|
||||||
|
@ -274,6 +81,8 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "23.11";
|
||||||
|
|
||||||
ar = {
|
ar = {
|
||||||
apps = {
|
apps = {
|
||||||
firefox.enable = true;
|
firefox.enable = true;
|
||||||
|
@ -288,15 +97,6 @@ in {
|
||||||
zramSwap.size = 100;
|
zramSwap.size = 100;
|
||||||
};
|
};
|
||||||
|
|
||||||
containers = {
|
|
||||||
oci = {
|
|
||||||
audiobookshelf.enable = true;
|
|
||||||
freshRSS.enable = true;
|
|
||||||
plexMediaServer.enable = true;
|
|
||||||
transmission.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
desktop = {
|
desktop = {
|
||||||
greetd = {
|
greetd = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -330,8 +130,42 @@ in {
|
||||||
musicPath = "${mediaDirectory}/Music";
|
musicPath = "${mediaDirectory}/Music";
|
||||||
};
|
};
|
||||||
|
|
||||||
navidrome.enable = true;
|
|
||||||
tailscale.enable = true;
|
tailscale.enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
raffauflabs = {
|
||||||
|
inherit domain;
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
oci = {
|
||||||
|
audiobookshelf.enable = true;
|
||||||
|
freshRSS.enable = true;
|
||||||
|
plexMediaServer.enable = true;
|
||||||
|
transmission.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services = {
|
||||||
|
ddclient = {
|
||||||
|
enable = true;
|
||||||
|
passwordFile = config.age.secrets.cloudflare.path;
|
||||||
|
protocol = "cloudflare";
|
||||||
|
};
|
||||||
|
|
||||||
|
forgejo.enable = true;
|
||||||
|
navidrome = {
|
||||||
|
enable = true;
|
||||||
|
lastfm = {
|
||||||
|
idFile = config.age.secrets.lastfmId.path;
|
||||||
|
secretFile = config.age.secrets.lastfmSecret.path;
|
||||||
|
};
|
||||||
|
spotify = {
|
||||||
|
idFile = config.age.secrets.spotifyId.path;
|
||||||
|
secretFile = config.age.secrets.spotifySecret.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [./oci];
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.containers.oci.audiobookshelf.enable {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
audiobookshelf = {
|
|
||||||
ports = ["0.0.0.0:${toString config.ar.containers.oci.audiobookshelf.port}:80"];
|
|
||||||
image = "ghcr.io/advplyr/audiobookshelf:latest";
|
|
||||||
environment = {TZ = "America/New_York";};
|
|
||||||
volumes = ["abs_config:/config" "abs_metadata:/metadata" "${config.ar.containers.oci.audiobookshelf.mediaDirectory}:/Media"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
imports = [
|
|
||||||
./audiobookshelf
|
|
||||||
./freshRSS
|
|
||||||
./jellyfin
|
|
||||||
./plexMediaServer
|
|
||||||
./transmission
|
|
||||||
];
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.containers.oci.freshRSS.enable {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
freshrss = {
|
|
||||||
ports = ["0.0.0.0:${toString config.ar.containers.oci.freshRSS.port}:80"];
|
|
||||||
image = "freshrss/freshrss:latest";
|
|
||||||
environment = {
|
|
||||||
TZ = "America/New_York";
|
|
||||||
CRON_MIN = "1,31";
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"freshrss_data:/var/www/FreshRSS/data"
|
|
||||||
"freshrss_extensions:/var/www/FreshRSS/extensions"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.containers.oci.jellyfin.enable {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
jellyfin = {
|
|
||||||
ports = ["0.0.0.0:${toString config.ar.containers.oci.jellyfin.port}:8096"];
|
|
||||||
image = "jellyfin/jellyfin";
|
|
||||||
environment = {TZ = "America/New_York";};
|
|
||||||
volumes = [
|
|
||||||
"jellyfin_config:/config"
|
|
||||||
"jellyfin_cache:/cache"
|
|
||||||
"${config.ar.containers.oci.jellyfin.mediaDirectory}:/Media"
|
|
||||||
"${config.ar.containers.oci.jellyfin.archiveDirectory}:/Archive"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.containers.oci.plexMediaServer.enable {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
plexMediaServer = {
|
|
||||||
ports = ["0.0.0.0:${toString config.ar.containers.oci.plexMediaServer.port}:32400"];
|
|
||||||
image = "plexinc/pms-docker:public";
|
|
||||||
environment = {TZ = "America/New_York";};
|
|
||||||
volumes = [
|
|
||||||
"plex_config:/config"
|
|
||||||
"plex_transcode:/transcode"
|
|
||||||
"${config.ar.containers.oci.plexMediaServer.mediaDirectory}:/Media"
|
|
||||||
"${config.ar.containers.oci.plexMediaServer.archiveDirectory}:/Archive"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
config,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.containers.oci.transmission.enable {
|
|
||||||
virtualisation.oci-containers.containers = {
|
|
||||||
transmission = {
|
|
||||||
ports = ["0.0.0.0:${toString config.ar.containers.oci.transmission.port}:9091" "0.0.0.0:${toString config.ar.containers.oci.transmission.bitTorrentPort}:51413"];
|
|
||||||
image = "linuxserver/transmission:latest";
|
|
||||||
environment = {
|
|
||||||
PGID = "1000";
|
|
||||||
PUID = "1000";
|
|
||||||
TZ = "America/New_York";
|
|
||||||
};
|
|
||||||
volumes = [
|
|
||||||
"transmission_config:/config"
|
|
||||||
"${config.ar.containers.oci.transmission.mediaDirectory}:/Media"
|
|
||||||
"${config.ar.containers.oci.transmission.archiveDirectory}:/Archive"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -7,7 +7,6 @@ inputs: {
|
||||||
imports = [
|
imports = [
|
||||||
./apps
|
./apps
|
||||||
./base
|
./base
|
||||||
./containers
|
|
||||||
./desktop
|
./desktop
|
||||||
./options.nix
|
./options.nix
|
||||||
./services
|
./services
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
{
|
{
|
||||||
config,
|
config,
|
||||||
inputs,
|
|
||||||
lib,
|
lib,
|
||||||
pkgs,
|
pkgs,
|
||||||
self,
|
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
options.ar = {
|
options.ar = {
|
||||||
|
@ -15,108 +13,6 @@
|
||||||
virt-manager.enable = lib.mkEnableOption "Virtual machine client.";
|
virt-manager.enable = lib.mkEnableOption "Virtual machine client.";
|
||||||
};
|
};
|
||||||
|
|
||||||
containers = {
|
|
||||||
oci = {
|
|
||||||
audiobookshelf = {
|
|
||||||
enable = lib.mkEnableOption "audiobookshelf server in OCI container.";
|
|
||||||
|
|
||||||
mediaDirectory = lib.mkOption {
|
|
||||||
description = "Media directory for audiobookshelf.";
|
|
||||||
default = "/mnt/Media";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for audiobookshelf.";
|
|
||||||
default = 13378;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
freshRSS = {
|
|
||||||
enable = lib.mkEnableOption "FreshRSS news client in OCI container.";
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for FreshRSS.";
|
|
||||||
default = 8080;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
jellyfin = {
|
|
||||||
enable = lib.mkEnableOption "Jellyfin media server in OCI container.";
|
|
||||||
|
|
||||||
archiveDirectory = lib.mkOption {
|
|
||||||
description = "Archive directory for Jellyfin.";
|
|
||||||
default = "/mnt/Archive";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaDirectory = lib.mkOption {
|
|
||||||
description = "Media directory for Jellyfin.";
|
|
||||||
default = "/mnt/Media";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for Jellyfin.";
|
|
||||||
default = 8096;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
plexMediaServer = {
|
|
||||||
enable = lib.mkEnableOption "Plex Media Server in OCI container.";
|
|
||||||
|
|
||||||
archiveDirectory = lib.mkOption {
|
|
||||||
description = "Archive directory for Plex Media Server.";
|
|
||||||
default = "/mnt/Archive";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaDirectory = lib.mkOption {
|
|
||||||
description = "Media directory for Plex Media Server.";
|
|
||||||
default = "/mnt/Media";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for Plex Media Server.";
|
|
||||||
default = 32400;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
transmission = {
|
|
||||||
enable = lib.mkEnableOption "Transmission client in OCI container.";
|
|
||||||
|
|
||||||
archiveDirectory = lib.mkOption {
|
|
||||||
description = "Archive directory for Transmission.";
|
|
||||||
default = "/mnt/Archive";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
bitTorrentPort = lib.mkOption {
|
|
||||||
description = "Port for BitTorrent p2p services.";
|
|
||||||
default = 5143;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
|
|
||||||
mediaDirectory = lib.mkOption {
|
|
||||||
description = "Media directory for Transmission.";
|
|
||||||
default = "/mnt/Media";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for Transmission.";
|
|
||||||
default = 9091;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
desktop = {
|
desktop = {
|
||||||
cinnamon.enable = lib.mkEnableOption "Cinnamon desktop session.";
|
cinnamon.enable = lib.mkEnableOption "Cinnamon desktop session.";
|
||||||
|
|
||||||
|
@ -155,22 +51,6 @@
|
||||||
services = {
|
services = {
|
||||||
flatpak.enable = lib.mkEnableOption "Flatpak support with GUI.";
|
flatpak.enable = lib.mkEnableOption "Flatpak support with GUI.";
|
||||||
|
|
||||||
navidrome = {
|
|
||||||
enable = lib.mkEnableOption "Navidrome music server with secrets.";
|
|
||||||
|
|
||||||
musicDirectory = lib.mkOption {
|
|
||||||
description = "Music directory for Navidrome.";
|
|
||||||
default = "/mnt/Media/Music";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Port for Navidrome.";
|
|
||||||
default = 4533;
|
|
||||||
type = lib.types.int;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
syncthing = {
|
syncthing = {
|
||||||
enable = lib.mkEnableOption "Syncthing sync service.";
|
enable = lib.mkEnableOption "Syncthing sync service.";
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
}: {
|
}: {
|
||||||
imports = [
|
imports = [
|
||||||
./flatpak
|
./flatpak
|
||||||
./navidrome
|
|
||||||
./syncthing
|
./syncthing
|
||||||
./tailscale
|
./tailscale
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
config = lib.mkIf config.ar.services.navidrome.enable {
|
|
||||||
age.secrets = let
|
|
||||||
owner = "navidrome";
|
|
||||||
in {
|
|
||||||
lastFMApiKey = {
|
|
||||||
inherit owner;
|
|
||||||
file = ../../../secrets/lastFM/apiKey.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
lastFMSecret = {
|
|
||||||
inherit owner;
|
|
||||||
file = ../../../secrets/lastFM/secret.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
spotifyClientId = {
|
|
||||||
inherit owner;
|
|
||||||
file = ../../../secrets/spotify/clientId.age;
|
|
||||||
};
|
|
||||||
|
|
||||||
spotifyClientSecret = {
|
|
||||||
inherit owner;
|
|
||||||
file = ../../../secrets/spotify/clientSecret.age;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.navidrome.enable = true;
|
|
||||||
|
|
||||||
systemd.services.navidrome.serviceConfig = let
|
|
||||||
navidromeConfig = builtins.toFile "navidrome.json" (lib.generators.toJSON {} {
|
|
||||||
Address = "0.0.0.0";
|
|
||||||
DefaultTheme = "Auto";
|
|
||||||
MusicFolder = config.ar.services.navidrome.musicDirectory;
|
|
||||||
Port = config.ar.services.navidrome.port;
|
|
||||||
SubsonicArtistParticipations = true;
|
|
||||||
UIWelcomeMessage = "Welcome to Navidrome @ RaffaufLabs.com";
|
|
||||||
"Spotify.ID" = "@spotifyClientId@";
|
|
||||||
"Spotify.Secret" = "@spotifyClientSecret@";
|
|
||||||
"LastFM.Enabled" = true;
|
|
||||||
"LastFM.ApiKey" = "@lastFMApiKey@";
|
|
||||||
"LastFM.Secret" = "@lastFMSecret@";
|
|
||||||
"LastFM.Language" = "en";
|
|
||||||
});
|
|
||||||
|
|
||||||
navidrome-secrets = pkgs.writeShellScript "navidrome-secrets" ''
|
|
||||||
lastFMApiKey=$(cat "${config.age.secrets.lastFMApiKey.path}")
|
|
||||||
lastFMSecret=$(cat "${config.age.secrets.lastFMSecret.path}")
|
|
||||||
spotifyClientId=$(cat "${config.age.secrets.spotifyClientId.path}")
|
|
||||||
spotifyClientSecret=$(cat "${config.age.secrets.spotifyClientSecret.path}")
|
|
||||||
${pkgs.gnused}/bin/sed -e "s/@lastFMApiKey@/$lastFMApiKey/" -e "s/@lastFMSecret@/$lastFMSecret/" \
|
|
||||||
-e "s/@spotifyClientId@/$spotifyClientId/" -e "s/@spotifyClientSecret@/$spotifyClientSecret/" \
|
|
||||||
${navidromeConfig} > /var/lib/navidrome/navidrome.json
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
BindReadOnlyPaths = [
|
|
||||||
config.age.secrets.lastFMApiKey.path
|
|
||||||
config.age.secrets.lastFMSecret.path
|
|
||||||
config.age.secrets.spotifyClientId.path
|
|
||||||
config.age.secrets.spotifyClientSecret.path
|
|
||||||
config.ar.services.navidrome.musicDirectory
|
|
||||||
];
|
|
||||||
|
|
||||||
ExecStartPre = navidrome-secrets;
|
|
||||||
ExecStart = lib.mkForce ''
|
|
||||||
${config.services.navidrome.package}/bin/navidrome --configfile /var/lib/navidrome/navidrome.json \
|
|
||||||
--datafolder /var/lib/navidrome/
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in a new issue