{ config, pkgs, ... }: let lib = pkgs.lib; host = "10.0.${toString vm-index}.1"; ports = { sonarr.port = 8989; radarr.port = 7878; jackett.port = 9117; }; vm-index = 1; vm-mac = "02:00:00:00:00:02"; vm-name = "auto-torrent"; vpn-endpoint = "193.32.248.70"; enable-services = true; wg-config = "/mnt/wg.conf"; jellyfin-gid = 989; ports-list = pkgs.lib.attrsets.mapAttrsToList (name: value: value.port) ports; in { microvm.autostart = [vm-name]; imports = [./nginx.nix]; users.extraUsers.microvm.extraGroups = [ "jellyfin" # access to media folder ]; system.activationScripts."make-${vm-name}-data-dir" = lib.stringAfter ["var"] '' mkdir -p /var/lib/${vm-name} # chown -R microvm:jellyfin /var/lib/${vm-name} ''; microvm.vms.${vm-name} = { config = {...}: { system.stateVersion = "25.05"; microvm.interfaces = [ { id = "vm${toString vm-index}"; type = "tap"; mac = vm-mac; } ]; time.timeZone = "Europe/Copenhagen"; # 1gb of memory microvm.mem = 1024; microvm.shares = let proto = "virtiofs"; in [ { tag = "ro-store"; source = "/nix/store"; mountPoint = "/nix/.ro-store"; } { tag = "data-dir"; source = "/var/lib/${vm-name}"; mountPoint = "/mnt"; inherit proto; } { tag = "media-dir"; source = "/var/lib/media"; mountPoint = "/media"; inherit proto; } ]; networking.useNetworkd = true; networking.usePredictableInterfaceNames = false; systemd.network.networks."10-eth" = { matchConfig.MACAddress = vm-mac; address = [ "10.0.${toString vm-index}.1/24" ]; routes = [ # Default route { Destination = "${toString vpn-endpoint}/32"; Gateway = "10.0.${toString vm-index}.254"; GatewayOnLink = true; } ]; networkConfig = { DNS = [ "9.9.9.9" "8.8.8.8" "8.8.4.4" ]; }; }; networking.useDHCP = false; networking.nameservers = [ "10.0.101.1" "8.8.8.8" "8.8.4.4" ]; systemd.services."start-wireguard" = { description = "Start wireguard mullvad"; after = ["network-online.target"]; wants = ["network-online.target"]; wantedBy = ["multi-user.target"]; serviceConfig = { type = "oneshot"; ExecStart = pkgs.writeShellScript "wgconf.sh" '' ${pkgs.wireguard-tools}/bin/wg-quick up ${wg-config} ''; RemainAfterExit = "yes"; }; }; networking.wireguard.enable = true; # Sleep them for a while to make sure everything is set up systemd.services.sonarr.serviceConfig.ExecStartPre = pkgs.lib.mkIf enable-services "/run/current-system/sw/bin/sleep 1"; systemd.services.radarr.serviceConfig.ExecStartPre = pkgs.lib.mkIf enable-services "/run/current-system/sw/bin/sleep 1"; systemd.services.jackett.serviceConfig.ExecStartPre = pkgs.lib.mkIf enable-services "/run/current-system/sw/bin/sleep 1"; systemd.services.rutorrent.serviceConfig.ExecStartPre = pkgs.lib.mkIf enable-services "/run/current-system/sw/bin/sleep 1"; # fuck nano programs.nano.enable = lib.mkForce false; programs.vim.enable = true; # Fix permissions with groups users.users = { sonarr.extraGroups = ["jellyfin"]; radarr.extraGroups = ["jellyfin"]; transmission.extraGroups = ["jellyfin"]; jackett.extraGroups = ["jellyfin"]; }; users.groups.jellyfin = { gid = jellyfin-gid; }; # Services services.sonarr = pkgs.lib.mkIf enable-services { enable = true; openFirewall = true; dataDir = "/mnt/sonarr"; }; services.radarr = pkgs.lib.mkIf enable-services { enable = true; openFirewall = true; dataDir = "/mnt/radarr"; }; services.jackett = pkgs.lib.mkIf enable-services { enable = true; dataDir = "/mnt/jackett"; openFirewall = true; }; services.transmission = pkgs.lib.mkIf enable-services { enable = true; openPeerPorts = true; home = "/mnt/transmission"; settings = { download-dir = "/media/.transmission/"; incomplete-dir = "/media/.transmission/.incomplete"; peer-port-random-low = 65500; peer-port-random-high = 65535; peer-port-random-on-start = true; download-queue-enabled = false; }; downloadDirPermissions = "775"; performanceNetParameters = true; }; # debugging users.users.root = { openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC562Woe/yT/3dNVceN9rKPJQcvgTFzIhJVdVGv7sqn1 baritone@server" ]; }; environment.systemPackages = with pkgs; [ wireguard-tools tcpdump ]; services.openssh = { enable = true; settings = { PermitRootLogin = "yes"; AllowUsers = null; PasswordAuthentication = true; KbdInteractiveAuthentication = true; }; }; }; }; # Add virtual hosts for all the different services running in the vm services.nginx.virtualHosts = builtins.listToAttrs (pkgs.lib.attrsets.mapAttrsToList ( name: value: { name = "${name}.spoodythe.one"; value = { addSSL = true; enableACME = true; listen = [ { port = value.port; addr = "0.0.0.0"; ssl = false; } { port = 443; addr = "0.0.0.0"; ssl = true; } ]; locations."/" = { proxyPass = "http://${host}:${toString value.port}"; }; }; } ) ports); networking.firewall.allowedTCPPorts = ports-list; networking.firewall.allowedUDPPorts = ports-list; }