diff --git a/flake.nix b/flake.nix index 41232c2..d841292 100644 --- a/flake.nix +++ b/flake.nix @@ -116,6 +116,56 @@ ]; }; + death-pc = + let + system = "x86_64-linux"; + in + nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit + inputs + system + overlays + primaryUser + hyprland + stylix + ; + unstablePkgs = import nixpkgs-unstable { inherit system; }; + }; + modules = [ + stylix.nixosModules.stylix + { + nixpkgs.overlays = [ + overlays.waveterm + overlays.rust + overlays.halloy + overlays.karakeep + ]; + } + ./nixos/death-pc.nix + home-manager.nixosModules.home-manager + ( + { + unstablePkgs, + ... + }: + { + home-manager.useGlobalPkgs = true; + home-manager.useUserPackages = true; + home-manager.backupFileExtension = "backup"; + home-manager.extraSpecialArgs = { inherit hmLib unstablePkgs inputs; }; + home-manager.users.death916 = { + imports = [ + ./home-manager/home.nix + stylix.homeModules.stylix + ]; + }; + } + ) + ]; + }; + homelab = let system = "x86_64-linux"; diff --git a/home-manager/halloy.nix b/home-manager/halloy.nix index 33a2a51..9db6a27 100644 --- a/home-manager/halloy.nix +++ b/home-manager/halloy.nix @@ -57,8 +57,6 @@ chathistory = true; logging = true; buffer = "replace-pane"; - filters.ignore = [ - ]; }; actions = { diff --git a/modules/nixos/desktop/desktop.nix b/modules/nixos/desktop/desktop.nix new file mode 100644 index 0000000..4b057b9 --- /dev/null +++ b/modules/nixos/desktop/desktop.nix @@ -0,0 +1,122 @@ +# ~/nixconfig/modules.new/nixos/laptop/desktop.nix +{ + config, + pkgs, + inputs, + unstablePkgs, + ... +}: + +{ + + hardware.rtl-sdr.enable = true; + + programs.steam = { + enable = true; + remotePlay.openFirewall = true; # Open ports in the firewall for Steam Remote Play + }; + services.xserver.enable = true; + services.gnome.gnome-keyring.enable = true; + services.dbus.enable = true; # for nextcloud client + # Enable the GNOME Desktop Environment. + services.displayManager.gdm.enable = true; + services.desktopManager.gnome.enable = true; + #cosmic instead + services.desktopManager.cosmic.enable = true; + # services.displayManager.cosmic-greeter.enable = true; + services.desktopManager.cosmic.xwayland.enable = true; + services.system76-scheduler.enable = true; + + # This is to fix clementine gui not showing up on wayland + environment.variables.QT_QPA_PLATFORM = "wayland"; + services.udisks2.enable = true; + # environment.sessionVariables.NIXOS_OZONE_WL = "1"; # Required for some Electron apps + + programs.hyprland = { + enable = true; + xwayland.enable = true; + package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland; + portalPackage = + inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland; + }; + + environment.systemPackages = with pkgs; [ + coreutils + git + vim + wget + unstablePkgs.tailscale + unstablePkgs.cosmic-session + # halloy + inputs.flox.packages.${pkgs.stdenv.hostPlatform.system}.flox + wl-clipboard + clementine + systemctl-tui + btrfs-progs + unstablePkgs.btrfs-assistant + rust-analyzer + snapper + inetutils + # rustdesk + sdrpp + gqrx + # unstablePkgs.sdrangel + restic + docker-compose # Added for Winboat + cifs-utils + nil + nixfmt + nixd + ]; + + services.snapper.configs.nix = { + SUBVOLUME = "/nix"; + allowUsers = [ "death916" ]; + + CLEANUP_EMPTY = true; + CLEANUP_NUMBER = true; + CLEANUP_TIMELINE = true; + TIMELINE_CREATE = true; + TIMELINE_LIMIT_HOURLY = 5; + TIMELINE_LIMIT_DAILY = 7; + TIMELINE_LIMIT_WEEKLY = 0; + TIMELINE_LIMIT_MONTHLY = 0; + TIMELINE_LIMIT_YEARLY = 0; + }; + + services.snapper.configs.home = { + SUBVOLUME = "/home"; + allowUsers = [ "death916" ]; + + CLEANUP_EMPTY = true; + CLEANUP_NUMBER = true; + CLEANUP_TIMELINE = true; + TIMELINE_CREATE = true; + TIMELINE_LIMIT_HOURLY = 5; + TIMELINE_LIMIT_DAILY = 7; + TIMELINE_LIMIT_WEEKLY = 0; + TIMELINE_LIMIT_MONTHLY = 0; + TIMELINE_LIMIT_YEARLY = 0; + }; + + virtualisation.docker.enable = true; + hardware.bluetooth.enable = true; + hardware.bluetooth.powerOnBoot = true; + services.blueman.enable = true; + hardware.bluetooth.settings = { + General = { + Experimental = true; + }; + }; + + programs.nh = { + enable = true; + clean.enable = true; + clean.extraArgs = "--keep-since 7d --keep 10"; + flake = "/home/death916/Documents/nix-config/"; + }; + services.fprintd.enable = false; + programs.direnv.enable = true; + programs.nix-ld.enable = true; + programs.fish.enable = true; +} diff --git a/modules/nixos/desktop/gaming.nix b/modules/nixos/desktop/gaming.nix new file mode 100644 index 0000000..b7a8c1e --- /dev/null +++ b/modules/nixos/desktop/gaming.nix @@ -0,0 +1,51 @@ +{ + config, + pkgs, + unstablePkgs, + ... +}: +{ + # NVIDIA & Audio + services.xserver.videoDrivers = [ "nvidia" ]; + hardware.graphics.enable = true; + hardware.graphics.enable32Bit = true; + hardware.nvidia = { + modesetting.enable = true; + powerManagement.enable = false; + open = false; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.stable; + }; + services.nvidia.persistence.enable = true; # Prevents stuttering + + services.pipewire.enable = true; + security.rtkit.enable = true; + + # Gaming & BTRFS Packages + programs.steam.enable = true; + programs.gamemode.enable = true; + environment.systemPackages = with pkgs; [ + steam + lutris + gamemode + prismlauncher + vlc + discord + btrfs-progs + unstablePkgs.btrfs-assistant + snapper + # (proton-ge-custom.override { version = "GE-Proton9-6"; }) + ]; + + # Snapper Setup + services.snapper.configs.home = { + SUBVOLUME = "/home"; + allowUsers = [ "death916" ]; + TIMELINE_CREATE = true; + }; + services.snapper.configs.nix = { + SUBVOLUME = "/nix"; + allowUsers = [ "death916" ]; + TIMELINE_CREATE = true; + }; +} diff --git a/modules/nixos/piefed/default.nix b/modules/nixos/piefed/default.nix new file mode 100644 index 0000000..1aa046b --- /dev/null +++ b/modules/nixos/piefed/default.nix @@ -0,0 +1,141 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.piefed; + + # local callPackage pattern from c2cscrape + piefedPkg = pkgs.python3Packages.callPackage ../../pkgs/piefed/default.nix { + tesseract = pkgs.tesseract; + # Custom python packages need to be passed if not automatically resolved + }; + + # Helper to run piefed commands + piefedManage = pkgs.writeShellScriptBin "piefed-manage" '' + export FLASK_APP=pyfedi.py + export PYTHONPATH=${piefedPkg}/opt/piefed + export EnvironmentFile=${cfg.environmentFile} + cd ${piefedPkg}/opt/piefed + # Use environment variables from cfg.environmentFile if possible, + # but for simple CLI we might need to source it or use 'env' + exec ${pkgs.python3}/bin/python3 -m flask "$@" + ''; +in +{ + options.services.piefed = { + enable = mkEnableOption "PieFed"; + domain = mkOption { + type = types.str; + description = "The domain name for the instance"; + }; + environmentFile = mkOption { + type = types.path; + description = "Path to the .env file containing secrets"; + }; + dataDir = mkOption { + type = types.path; + default = "/var/lib/piefed"; + description = "Directory to store media, uploads, and logs"; + }; + }; + + config = mkIf cfg.enable { + services.postgresql = { + enable = true; + ensureDatabases = [ "piefed" ]; + ensureUsers = [{ + name = "piefed"; + ensureDBOwnership = true; + }]; + }; + + services.redis.servers.piefed = { + enable = true; + port = 6379; + }; + + systemd.tmpfiles.rules = [ + "d ${cfg.dataDir} 0750 piefed piefed -" + "d ${cfg.dataDir}/media 0750 piefed piefed -" + "d ${cfg.dataDir}/logs 0750 piefed piefed -" + "d ${cfg.dataDir}/tmp 0750 piefed piefed -" + ]; + + users.users.piefed = { + isSystemUser = true; + group = "piefed"; + home = cfg.dataDir; + }; + users.groups.piefed = { }; + + systemd.services.piefed-web = { + description = "PieFed Web Service"; + after = [ "network.target" "postgresql.service" "redis-piefed.service" ]; + wantedBy = [ "multi-user.target" ]; + environment = { + FLASK_APP = "pyfedi.py"; + PYTHONPATH = "${piefedPkg}/opt/piefed"; + PIEFED_MEDIA_PATH = "${cfg.dataDir}/media"; + PIEFED_LOG_PATH = "${cfg.dataDir}/logs"; + }; + serviceConfig = { + User = "piefed"; + Group = "piefed"; + WorkingDirectory = "${piefedPkg}/opt/piefed"; + EnvironmentFile = cfg.environmentFile; + ExecStart = "${pkgs.python3Packages.gunicorn}/bin/gunicorn --config ${piefedPkg}/opt/piefed/gunicorn.conf.py --preload pyfedi:app"; + Restart = "always"; + }; + }; + + systemd.services.piefed-worker = { + description = "PieFed Celery Worker"; + after = [ "piefed-web.service" ]; + wantedBy = [ "multi-user.target" ]; + environment = { + PYTHONPATH = "${piefedPkg}/opt/piefed"; + }; + serviceConfig = { + User = "piefed"; + Group = "piefed"; + WorkingDirectory = "${piefedPkg}/opt/piefed"; + EnvironmentFile = cfg.environmentFile; + ExecStart = "${pkgs.python3Packages.celery}/bin/celery -A celery_worker.celery worker --loglevel=INFO"; + Restart = "always"; + }; + }; + + systemd.services.piefed-notifs = { + description = "PieFed Notifications Service"; + after = [ "piefed-web.service" ]; + wantedBy = [ "multi-user.target" ]; + environment = { + PYTHONPATH = "${piefedPkg}/opt/piefed"; + }; + serviceConfig = { + User = "piefed"; + Group = "piefed"; + WorkingDirectory = "${piefedPkg}/opt/piefed"; + EnvironmentFile = cfg.environmentFile; + ExecStart = "${pkgs.python3Packages.uvicorn}/bin/uvicorn fastapi_server:app --host 127.0.0.1 --port 8040"; + Restart = "always"; + }; + }; + + # Migration one-shot service + systemd.services.piefed-migrate = { + description = "PieFed Database Migrations"; + after = [ "postgresql.service" ]; + serviceConfig = { + Type = "oneshot"; + User = "piefed"; + Group = "piefed"; + WorkingDirectory = "${piefedPkg}/opt/piefed"; + EnvironmentFile = cfg.environmentFile; + ExecStart = "${piefedManage}/bin/piefed-manage db upgrade"; + RemainAfterExit = true; + }; + }; + }; +} diff --git a/nixos/death-pc.nix b/nixos/death-pc.nix new file mode 100644 index 0000000..314b9f0 --- /dev/null +++ b/nixos/death-pc.nix @@ -0,0 +1,51 @@ +{ + config, + pkgs, + lib, + inputs, + ... +}: +{ + imports = [ + ./hardware-death-pc.nix + ../modules/nixos/desktop/desktop.nix + ../modules/nixos/common/base.nix + ../modules/nixos/laptop/user.nix + ../modules/nixos/common/tailscale.nix + ../modules/nixos/laptop/hyprland-deps.nix + ../modules/nixos/desktop/gaming.nix + ]; + + networking.hostName = "death-pc"; + + # Use linux_zen kernel for performance improvements + boot.kernelPackages = pkgs.linuxKernel.packages.linux_zen; + + # --- Bootloader: GRUB Dual-Boot --- + # Overriding the systemd-boot from base.nix + boot.loader.systemd-boot.enable = lib.mkForce false; + boot.loader.grub = { + enable = true; + device = "nodev"; + efiSupport = true; + useOSProber = true; # Automatically detects Windows on the Small SSD + default = 0; + }; + boot.loader.efi.canTouchEfiVariables = true; + + # --- System Optimizations --- + hardware.enableRedistributableFirmware = true; + services.btrfs.autoScrub.enable = true; + + # --- NVIDIA G-SYNC / Tear-Free --- + services.xserver.screenSection = '' + Option "AllowGNULL" "False" + Option "metamodes" "nvidia-auto-select +0+0 {ForceFullCompositionPipeline=On, AllowGSYNC=On}" + ''; + + # State version for this specific machine + system.stateVersion = "25.11"; + + # Set wallpaper for Stylix + stylix.image = "/home/death916/Documents/nix-config/home-manager/wallpaper.jpg"; +} diff --git a/nixos/hardware-death-pc.nix b/nixos/hardware-death-pc.nix new file mode 100644 index 0000000..c266eab --- /dev/null +++ b/nixos/hardware-death-pc.nix @@ -0,0 +1,77 @@ +{ + config, + lib, + pkgs, + modulesPath, + ... +}: +{ + imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; + + boot.initrd.availableKernelModules = [ + "nvme" + "xhci_pci" + "usb_storage" + "usbhid" + "sd_mod" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ + "subvol=@" + "compress=zstd" + "noatime" + ]; + }; + + fileSystems."/nix" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ + "subvol=@nix" + "compress=zstd" + "noatime" + ]; + }; + + fileSystems."/home" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ + "subvol=@home" + "compress=zstd" + "noatime" + ]; + }; + + fileSystems."/var/log" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ + "subvol=@log" + "compress=zstd" + "noatime" + ]; + neededForBoot = true; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-label/BOOT"; + fsType = "vfat"; + options = [ + "fmask=0022" + "dmask=0022" + ]; + }; + + swapDevices = [ ]; + + networking.useDHCP = lib.mkDefault true; + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/pkgs/piefed/default.nix b/pkgs/piefed/default.nix new file mode 100644 index 0000000..ccd0351 --- /dev/null +++ b/pkgs/piefed/default.nix @@ -0,0 +1,172 @@ +{ lib +, buildPythonPackage +, fetchFromGitea +, fetchPypi +, tesseract +, tatsu +, urllib3 +, flask +, python-dotenv +, flask-wtf +, flask-sqlalchemy +, flask-migrate +, flask-login +, flask-limiter +, email-validator +, flask-mail +, flask-babel +, flask-bcrypt +, psycopg2 +, httpx +, pyjwt +, sqlalchemy-utils +, cryptography +, arrow +, pyld +, boto3 +, markdown2 +, beautifulsoup4 +, flask-caching +, pillow +, pillow-heif +, feedgen +, celery +, redis +, werkzeug +, pytesseract +, sentry-sdk +, python-slugify +, furl +, ua-parser +, captcha +, pytest +, stripe +, authlib +, webauthn +, ldap3 +, sqlalchemy +, orjson +, marshmallow +, flask-smorest +, ics +, dateparser +, uvicorn +, asgiref +, pygments +, fastapi +, sqlakeyset +, rich +, validators +, wtforms +}: + +let + sqlalchemy-searchable = buildPythonPackage rec { + pname = "sqlalchemy-searchable"; + version = "1.4.1"; + src = fetchPypi { + inherit pname version; + hash = "sha256-0000000000000000000000000000000000000000000="; + }; + propagatedBuildInputs = [ + sqlalchemy + sqlalchemy-utils + validators + ]; + doCheck = false; + }; + + bootstrap-flask = buildPythonPackage rec { + pname = "bootstrap-flask"; + version = "2.5.0"; + src = fetchPypi { + pname = "Bootstrap-Flask"; + inherit version; + hash = "sha256-0000000000000000000000000000000000000000000="; + }; + propagatedBuildInputs = [ + flask + wtforms + ]; + doCheck = false; + }; +in +buildPythonPackage rec { + pname = "piefed"; + version = "1.6.8"; + + src = fetchFromGitea { + domain = "codeberg.org"; + owner = "rimu"; + repo = "pyfedi"; + rev = "v${version}"; + hash = "sha256-0000000000000000000000000000000000000000000="; + }; + + format = "other"; + + propagatedBuildInputs = [ + tatsu + urllib3 + flask + python-dotenv + flask-wtf + flask-sqlalchemy + flask-migrate + flask-login + flask-limiter + email-validator + flask-mail + flask-babel + flask-bcrypt + psycopg2 + httpx + pyjwt + sqlalchemy-utils + cryptography + arrow + pyld + boto3 + markdown2 + beautifulsoup4 + flask-caching + pillow + pillow-heif + feedgen + celery + redis + werkzeug + pytesseract + sentry-sdk + python-slugify + furl + ua-parser + captcha + pytest + stripe + authlib + webauthn + ldap3 + sqlalchemy + orjson + marshmallow + flask-smorest + ics + dateparser + uvicorn + asgiref + pygments + fastapi + sqlakeyset + rich + sqlalchemy-searchable + bootstrap-flask + ]; + + buildInputs = [ tesseract ]; + + installPhase = '' + mkdir -p $out/opt/piefed + cp -rv . $out/opt/piefed + ''; +}