move raffauflabsModules to separate git repo (#12)

* remove from flake + delete files

* README: add raffauflabs modules link
This commit is contained in:
Aly Raffauf 2024-07-05 20:58:05 -04:00
parent 347c343742
commit 58039a6563
15 changed files with 92 additions and 557 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +0,0 @@
{
pkgs,
lib,
config,
...
}: {
imports = [./oci];
}

View file

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

View file

@ -1,14 +0,0 @@
{
pkgs,
lib,
config,
...
}: {
imports = [
./audiobookshelf
./freshRSS
./jellyfin
./plexMediaServer
./transmission
];
}

View file

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

View file

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

View file

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

View file

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

View file

@ -7,7 +7,6 @@ inputs: {
imports = [ imports = [
./apps ./apps
./base ./base
./containers
./desktop ./desktop
./options.nix ./options.nix
./services ./services

View file

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

View file

@ -6,7 +6,6 @@
}: { }: {
imports = [ imports = [
./flatpak ./flatpak
./navidrome
./syncthing ./syncthing
./tailscale ./tailscale
]; ];

View file

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