diff --git a/home/nomad/homelab.nix b/home/nomad/homelab.nix new file mode 100644 index 0000000..728d5b4 --- /dev/null +++ b/home/nomad/homelab.nix @@ -0,0 +1,22 @@ +{ + imports = [ + ../common + ./dotfiles/nvim.nix + ../features/cli + ../features/desktop + ../features/themes + ./home/home.nix + ]; + + features = { + cli = { + zsh.enable = true; + fzf.enable = true; + neofetch.enable = true; + }; + desktop = { + fonts.enable = true; + }; + }; +} + diff --git a/home/nomad/homelab/home.nix b/home/nomad/homelab/home.nix new file mode 100644 index 0000000..7c1cd41 --- /dev/null +++ b/home/nomad/homelab/home.nix @@ -0,0 +1,34 @@ +{ config, lib, pkgs, user, ... }: + +{ + home.username = lib.mkDefault user; + home.homeDirectory = lib.mkDefault "/home/${config.home.username}"; + home.stateVersion = "24.05"; + + home.packages = with pkgs; [ + mullvad-vpn + tailscale + htop + bun + lua-language-server + + + + + ]; + + home.file = { }; + + home.sessionVariables = { + EDITOR = "nvim"; + GBM_BACKEND = "nvidia-drm"; + WLR_RENDERER = "vulkan"; + VK_DRIVER_FILES = "/run/opengl-driver/share/vulkan/icd.d/nvidia_icd.x86_64.json"; + XDG_CACHE_HOME = "${config.home.homeDirectory}/.cache"; + XDG_CONFIG_HOME = "${config.home.homeDirectory}/.config"; + XDG_BIN_HOME = "${config.home.homeDirectory}/.nix-profile/bin"; + XDG_DATA_HOME = "${config.home.homeDirectory}/.local/share"; + }; + + programs.home-manager.enable = true; +} diff --git a/hosts/common/homelab/arr.nix b/hosts/common/homelab/arr.nix new file mode 100644 index 0000000..9ea6039 --- /dev/null +++ b/hosts/common/homelab/arr.nix @@ -0,0 +1,111 @@ +{ config, lib, pkgs, user, ... }: +with lib; + +let + + arrServices = { + prowlarr = { + image = "ghcr.io/hotio/prowlarr"; + container_name = "prowlarr"; + environment = { + PUID = "1000"; + PGID = "1000"; + UMASK = "002"; + TZ = "Asia/Kuwait"; + }; + volumes = [ "/home/${user}/configs/prowlarr_config:/config" ]; + ports = [ "9696:9696" ]; + restart = "unless-stopped"; + }; + + sonarr = { + image = "linuxserver/sonarr:latest"; + container_name = "sonarr"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + volumes = [ + "/home/${user}/configs/sonarr_config:/config" + "/home/${user}/media/tvshows:/tvshows" + "/home/${user}/media/anime:/anime" + "/home/${user}/media/transmission/downloads/complete:/downloads/complete" + ]; + ports = [ "8989:8989" ]; + restart = "unless-stopped"; + }; + + radarr = { + image = "linuxserver/radarr:latest"; + container_name = "radarr"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + networks = [ "jellyfin" ]; + volumes = [ + "/home/${user}/configs/radarr_config:/config" + "/home/${user}/media/movies:/movies" + "/home/${user}/media/transmission/downloads/complete:/downloads/complete" + ]; + ports = [ "7878:7878" ]; + restart = "unless-stopped"; + }; + + readarr = { + image = "lscr.io/linuxserver/readarr:develop"; + container_name = "readarr"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + networks = [ "jellyfin" ]; + volumes = [ + "/home/${user}/configs/readarr_config:/config" + "/home/${user}/media/books:/books" + "/home/${user}/media/transmission/downloads/complete:/downloads/complete" + ]; + ports = [ "8787:8787" ]; + restart = "unless-stopped"; + }; + + bazarr = { + image = "linuxserver/bazarr"; + container_name = "bazarr"; + environment = { + DOCKER_MODS = "wayller/bazarr-mod-subsync:latest"; + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + networks = [ "jellyfin" ]; + volumes = [ + "/home/${user}/configs/bazarr_config:/config" + "/home/${user}/media/tvshows:/tvshows" + "/home/${user}/media/movies:/movies" + "/home/${user}/media/anime:/anime" + ]; + ports = [ "6767:6767" ]; + restart = "unless-stopped"; + }; + + networks = [ "jellyfin" ]; + + }; +in +{ + options.services.arr.enable = mkEnableOption "Enable ARR services stack"; + + config = mkIf config.services.arr.enable { + virtualisation.arion = { + backend = "docker"; + projects.dufs = { + serviceName = "arr"; + settings = arrServices; + }; + }; + }; +} diff --git a/hosts/common/homelab/default.nix b/hosts/common/homelab/default.nix new file mode 100644 index 0000000..bdee71b --- /dev/null +++ b/hosts/common/homelab/default.nix @@ -0,0 +1,10 @@ +{ + imports = [ + ./arr.nix + ./jellyfin.nix + ./transcoding.nix + ./transmission.nix + ./utils.nix + ]; + +} diff --git a/hosts/common/homelab/jellyfin.nix b/hosts/common/homelab/jellyfin.nix new file mode 100644 index 0000000..3b95d7f --- /dev/null +++ b/hosts/common/homelab/jellyfin.nix @@ -0,0 +1,57 @@ +{ config, lib, pkgs, ... }: +with lib; + +let + jellyfinServices = { + jellyfin = { + image = "nomadics/alaskarfin:latest"; + container_name = "jellyfin"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + volumes = [ + "/home/${user}/configs/jellyfin_config:/config" + "/home/${user}/media/tvshows:/data/tvshows" + "/home/${user}/media/movies:/data/movies" + ]; + ports = [ "8096:8096" ]; + restart = "unless-stopped"; + }; + + jellyseerr = { + image = "nomadics/alaskarseer:latest"; + container_name = "jellyseerr"; + environment = { + PUID = "1000"; + PGID = "1000"; + LOG_LEVEL = "debug"; + TZ = "Asia/Kuwait"; + JELLYFIN_TYPE = "jellyfin"; + }; + networks = [ "jellyfin" ]; + ports = [ "5055:5055" ]; + volumes = [ "/home/${user}/configs/jellyseerr_config:/app/config" ]; + restart = "unless-stopped"; + depends_on = [ + "radarr" + "sonarr" + ]; + }; + networks = [ "jellyfin" ]; + }; +in +{ + options.services.jellyfin-server.enable = mkEnableOption "Enable Jellyfin stack"; + + config = mkIf config.services.jellyfin-server.enable { + virtualisation.arion = { + backend = "docker"; + projects.dufs = { + serviceName = "jellyfin"; + settings = jellyfinServices; + }; + }; + }; +} diff --git a/hosts/common/homelab/transcoding.nix b/hosts/common/homelab/transcoding.nix new file mode 100644 index 0000000..9ea6d29 --- /dev/null +++ b/hosts/common/homelab/transcoding.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: +with lib; + +let + transcodingServices = { + tdarr = { + image = "ghcr.io/haveagitgat/tdarr:latest"; + container_name = "tdarr"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + NVIDIA_VISIBLE_DEVICES = "all"; + }; + volumes = [ + "/home/${user}/configs/tdarr_config:/config" + "/home/${user}/media:/media" + ]; + ports = [ + "8265:8265" + "8266:8266" + ]; + restart = "unless-stopped"; + }; + }; +in +{ + options.services.transcoding.enable = mkEnableOption "Enable transcoding stack"; + + config = mkIf config.services.transcoding.enable { + virtualisation.arion = { + backend = "docker"; # Or "podman" if you use Podman + projects.dufs = { + serviceName = "transcoding"; + settings = transcodingServices; + }; + }; + }; +} diff --git a/hosts/common/homelab/transmission.nix b/hosts/common/homelab/transmission.nix new file mode 100644 index 0000000..f584d78 --- /dev/null +++ b/hosts/common/homelab/transmission.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: +with lib; + +let + transmissionServices = { + transmission = { + image = "linuxserver/transmission:latest"; + container_name = "transmission"; + environment = { + PUID = "1000"; + PGID = "1000"; + TZ = "Asia/Kuwait"; + }; + volumes = [ + "/home/${user}/configs/transmission_config:/config" + "/home/${user}/media/transmission/downloads:/downloads" + ]; + ports = [ + "9091:9091" + "51413:51413" + "51413:51413/udp" + ]; + restart = "unless-stopped"; + }; + }; +in +{ + options.services.downloader.enable = mkEnableOption "Enable Transmission service"; + + config = mkIf config.services.downloader.enable { + virtualisation.arion = { + backend = "docker"; # Or "podman" if you use Podman + projects.dufs = { + serviceName = "transmission"; + settings = transmissionServices; + }; + }; + }; +} diff --git a/hosts/common/homelab/utils.nix b/hosts/common/homelab/utils.nix new file mode 100644 index 0000000..8924c6e --- /dev/null +++ b/hosts/common/homelab/utils.nix @@ -0,0 +1,112 @@ +{ config, lib, pkgs, user, ... }: +with lib; + +let + utilsServices = { + jellystat = { + image = "cyfershepard/jellystat:unstable"; + container_name = "jellystat"; + environment = { + POSTGRES_USER = "postgres"; + POSTGRES_PASSWORD = "serverstat"; + TZ = "Asia/Kuwait"; + }; + volumes = [ "/home/${user}/configs/jellystat-backup-data:/app/backend/backup-data" ]; + ports = [ "3000:3000" ]; + restart = "unless-stopped"; + }; + + jellystat-db = { + container_name = "jellystat-db"; + image = "postgres:15.2"; + environment = { + POSTGRES_DB = "jfstat"; + POSTGRES_USER = "postgres"; + POSTGRES_PASSWORD = "serverstat"; + TZ = "Asia/Kuwait"; + }; + restart = "unless-stopped"; + volumes = [ + "/home/${user}/configs/postgres-data:/var/lib/postgresql/data" # Mounting the volume + ]; + }; + + jfa-go = { + container_name = "jfa-go"; + image = "hrfee/jfa-go:latest"; + restart = "unless-stopped"; + volumes = [ + "/home/${user}/configs/jfa-go_config/jfa-go:/data" + "/home/sager/stream-stack/jellyfin_config:/jf" + "/etc/localtime:/etc/localtime:ro" + ]; + ports = [ + "8056:8056" + ]; + }; + + + image = "golift/unpackerr"; + container_name = "unpackerr"; + volumes = [ + "/home/${user}/media/transmission/downloads:/downloads" + ]; + restart = "always"; + user = "1000:1000"; + environment = { + TZ = "Asia/Kuwait"; + UN_DEBUG = "false"; + UN_LOG_FILE = ""; + UN_LOG_FILES = "10"; + UN_LOG_FILE_MB = "10"; + UN_INTERVAL = "2m"; + UN_START_DELAY = "1m"; + UN_RETRY_DELAY = "5m"; + UN_MAX_RETRIES = "3"; + UN_PARALLEL = "1"; + UN_FILE_MODE = "0644"; + UN_DIR_MODE = "0755"; + + # Sonarr Config + UN_SONARR_0_URL = "http://192.168.0.200:8989"; + UN_SONARR_0_API_KEY = "ece789601b4541be934324cc5c338092"; + UN_SONARR_0_PATHS_0 = "/downloads"; + UN_SONARR_0_PROTOCOLS = "torrent"; + UN_SONARR_0_TIMEOUT = "10s"; + UN_SONARR_0_DELETE_ORIG = "false"; + UN_SONARR_0_DELETE_DELAY = "5m"; + + # Radarr Config + UN_RADARR_0_URL = "http://192.168.0.200:7878"; + UN_RADARR_0_API_KEY = "446ab739173c4cb1b2c52eb1f3000f50"; + UN_RADARR_0_PATHS_0 = "/downloads"; + UN_RADARR_0_PROTOCOLS = "torrent"; + UN_RADARR_0_TIMEOUT = "10s"; + UN_RADARR_0_DELETE_ORIG = "false"; + UN_RADARR_0_DELETE_DELAY = "5m"; + + # UN_READARR_0_URL = "http://readarr:8787"; + # UN_READARR_0_API_KEY = ""; + # UN_READARR_0_PATHS_0 = "/downloads"; + # UN_READARR_0_PROTOCOLS = "torrent"; + # UN_READARR_0_TIMEOUT = "10s"; + # UN_READARR_0_DELETE_ORIG = "false"; + # UN_READARR_0_DELETE_DELAY = "5m"; + }; + security_opt = [ "no-new-privileges:true" ]; + + }; +in +{ + options.services.utils.enable = mkEnableOption "Enable Utils services stack"; + + config = mkIf config.services.utils.enable { + virtualisation.arion = { + backend = "docker"; # Or "podman" if you use Podman + projects.dufs = { + serviceName = "utils"; + settings = utilsServices; + }; + }; + }; +} diff --git a/hosts/homelab/configuration.nix b/hosts/homelab/configuration.nix new file mode 100644 index 0000000..b557d3e --- /dev/null +++ b/hosts/homelab/configuration.nix @@ -0,0 +1,109 @@ +{ pkgs, hostname, ... }: { + + imports = [ + ./hardware-configuration.nix + ]; + + hardware.nvidia.enable = true; + hardware.disko.enable = true; + + + programs.nix-ld.enable = true; + common.services.appimage.enable = true; + + systemd.services.arion = { + enable = true; + serviceConfig = { + Restart = "on-failure"; + }; + }; + + services = { + arr.enable = true; + jellyfin.enable = true; + transcoding.enable = true; + transmission.enable = true; + utils.enable = true; + }; + + sops = { + age.keyFile = "/home/${user}/.config/sops/age/keys.txt"; + defaultSopsFile = ../../secrets/secrets.yaml; + defaultSopsFormat = "yaml"; + }; + + + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + boot.loader.efi.efiSysMountPoint = "/boot/efi"; + boot.loader.systemd-boot.configurationLimit = 3; + boot.supportedFilesystems = [ "ntfs" ]; + + + + networking.hostName = "Homelab"; + networking.networkmanager.enable = true; + + + hardware.pulseaudio.enable = false; + security.rtkit.enable = false; + services.pipewire = { + enable = true; + alsa.enable = true; + alsa.support32Bit = true; + pulse.enable = true; + }; + + + time.timeZone = "Asia/Kuwait"; + i18n.defaultLocale = "en_US.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "en_GB.UTF-8"; + LC_IDENTIFICATION = "en_GB.UTF-8"; + LC_MEASUREMENT = "en_GB.UTF-8"; + LC_MONETARY = "en_GB.UTF-8"; + LC_NAME = "en_GB.UTF-8"; + LC_NUMERIC = "en_GB.UTF-8"; + LC_PAPER = "en_GB.UTF-8"; + LC_TELEPHONE = "en_GB.UTF-8"; + LC_TIME = "en_GB.UTF-8"; + }; + + services.xserver = { + exportConfiguration = true; + xkb.layout = "us,ara"; + xkb.options = "grp:alt_shift_toggle"; + xkb.variant = "qwerty_digits"; + }; + + services.printing.enable = true; + + nixpkgs.config.allowUnfree = true; + + + environment.systemPackages = with pkgs; [ + neovim + git + zsh + ]; + + + networking.firewall.enable = true; + networking.firewall.allowedTCPPorts = [ + 9696 + 8989 + 7878 + 8787 + 6767 + 8096 + 5055 + 8265 + 8266 + 9091 + 51413 + 3000 + 8056 + ]; + + system.stateVersion = "24.05"; +} diff --git a/hosts/homelab/default.nix b/hosts/homelab/default.nix new file mode 100644 index 0000000..5bc7e1c --- /dev/null +++ b/hosts/homelab/default.nix @@ -0,0 +1,48 @@ +# A staring point is the basic NIXOS configuration generated by the ISO installer. +# On an existing NIXOS install you can use the following command in your flakes basedir: +# sudo nixos-generate-config --dir ./hosts/your-host +# +# Please make sure to change the first couple of lines in your configuration.nix: + +# { config, inputs, ouputs, lib, pkgs, ... }: + +{ + # imports = [ # Include the results of the hardware scan. + # ./hardware-configuration.nix + # inputs.home-manager.nixosModules.home-manager + # ]; + # + # # ... + # + # Moreover please update the packages option in your user configuration and add the home-manager options: + + # users.users = { + # ${user} = { + # isNormalUser = true; + # initialPassword = "4321"; + # extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user. + # packages = [ inputs.home-manager.packages.${pkgs.system}.default ]; + # }; + # }; + + # home-manager = { + # useUserPackages = true; + # extraSpecialArgs = { inherit inputs outputs; }; + # users.${user} = + # import ../../home/${user}/${config.networking.hostName}.nix; + # }; + + # Please also change your hostname accordingly: + #:w + + # networking.hostName = "unkown"; # Define your hostname. + + + imports = [ + ../common + ../homelab + ./hardware + ./configuration.nix + ]; + +} diff --git a/hosts/homelab/hardware/default.nix b/hosts/homelab/hardware/default.nix new file mode 100644 index 0000000..c0948b2 --- /dev/null +++ b/hosts/homelab/hardware/default.nix @@ -0,0 +1,7 @@ +{ + imports = [ + ./nvidia.nix + ./disko.nix + ]; +} + diff --git a/hosts/homelab/hardware/disko.nix b/hosts/homelab/hardware/disko.nix new file mode 100644 index 0000000..b0dea06 --- /dev/null +++ b/hosts/homelab/hardware/disko.nix @@ -0,0 +1,50 @@ +{ config +, lib +, pkgs +, ... +}: +with lib; let + cfg = config.hardware.disko; +in +{ + options.hardware.disko.enable = mkEnableOption "disko harddrives"; + + config = mkIf cfg.enable { + disko.devices = { + disk = { + os_drive = { + type = "disk"; + path = "/dev/sde"; # OS hard drive + partitions = { + ESP = { + type = "EF00"; # EFI system partition type + size = "512M"; # EFI partition size + content = { + type = "filesystem"; + format = "vfat"; # Filesystem type for EFI + mountpoint = "/boot/efi"; # Mount point for EFI + }; + }; + root = { + size = "100%"; # Use remaining space for root partition + content = { + type = "filesystem"; + format = "ext4"; # Filesystem type for root + mountpoint = "/"; # Root mount point + }; + }; + }; + + ssd_1 = { + content = { + type = "lvm"; + path = "/dev/vg-ssd/lv-ssd"; + mountPoint = "/home"; + #format = null; # Do not format, preserve data + }; + }; + }; + }; + }; + }; +} diff --git a/hosts/homelab/hardware/nvidia.nix b/hosts/homelab/hardware/nvidia.nix new file mode 100644 index 0000000..9920669 --- /dev/null +++ b/hosts/homelab/hardware/nvidia.nix @@ -0,0 +1,68 @@ +{ config +, lib +, pkgs +, ... +}: +with lib; let + cfg = config.hardware.nvidia; +in +{ + options.hardware.nvidia.enable = mkEnableOption "nvidia driver"; + + config = mkIf cfg.enable { + #Allow unfree packages + nixpkgs.config.allowUnfree = true; + + + services.xserver = { + videoDrivers = [ "nvidia" ]; + }; + + hardware = { + graphics.enable = true; + # opengl.driSupport = true; + graphics.enable32Bit = true; + graphics = { + extraPackages = with pkgs; [ + intel-media-driver # LIBVA_DRIVER_NAME=iHD + # intel-vaapi-driver # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium) + # libvdpau-va-gl + # vaapiVdpau + # mesa.drivers + ]; + }; + + + nvidia.nvidiaSettings = true; + nvidia.powerManagement.enable = false; + nvidia.powerManagement.finegrained = false; + nvidia.open = false; + # nvidia.forceFullCompositionPipeline = true; + + # nvidia-drm.modeset=1 is required for some wayland compositors, e.g. sway + nvidia.modesetting.enable = false; + #nvidia.nvidiaPersistenced = true; + + # Optionally, you may need to select the appropriate driver version for your specific GPU. + nvidia.package = config.boot.kernelPackages.nvidiaPackages.stable; + }; + + + # Nvidia in Docker + virtualisation.docker = { + enable = true; + enableOnBoot = true; + #enableNvidia = true; + }; + + hardware.nvidia-container-toolkit.enable = true; + + environment.systemPackages = with pkgs; [ + cudatoolkit + ]; + }; +} + + + +