diff --git a/modules/hosts/dnsc-vps-sm/_hardware-configuration.nix b/modules/hosts/dnsc-vps-sm/_hardware-configuration.nix new file mode 100644 index 0000000..b58fbe3 --- /dev/null +++ b/modules/hosts/dnsc-vps-sm/_hardware-configuration.nix @@ -0,0 +1,22 @@ +{ + config, + lib, + modulesPath, + ... +}: + +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + boot.loader.grub.device = "/dev/sda"; + boot.initrd.availableKernelModules = [ + "ata_piix" + "uhci_hcd" + "xen_blkfront" + "vmw_pvscsi" + ]; + boot.initrd.kernelModules = [ "nvme" ]; + fileSystems."/" = { + device = "/dev/sda1"; + fsType = "ext4"; + }; +} diff --git a/modules/hosts/dnsc-vps-sm/_networking.nix b/modules/hosts/dnsc-vps-sm/_networking.nix new file mode 100644 index 0000000..4b1d76b --- /dev/null +++ b/modules/hosts/dnsc-vps-sm/_networking.nix @@ -0,0 +1,58 @@ +{ + lib, + ... +}: + +{ + # This file was populated at runtime with the networking + # details gathered from the active system. + networking = { + nameservers = [ + "8.8.8.8" + ]; + defaultGateway = "172.31.1.1"; + defaultGateway6 = { + address = "fe80::1"; + interface = "eth0"; + }; + dhcpcd.enable = false; + usePredictableInterfaceNames = lib.mkForce false; + interfaces = { + eth0 = { + ipv4.addresses = [ + { + address = "91.99.21.186"; + prefixLength = 32; + } + ]; + ipv6.addresses = [ + { + address = "2a01:4f8:1c1a:cdfb::1"; + prefixLength = 64; + } + { + address = "fe80::9400:4ff:fe27:8245"; + prefixLength = 64; + } + ]; + ipv4.routes = [ + { + address = "172.31.1.1"; + prefixLength = 32; + } + ]; + ipv6.routes = [ + { + address = "fe80::1"; + prefixLength = 128; + } + ]; + }; + + }; + }; + services.udev.extraRules = '' + ATTR{address}=="96:00:04:27:82:45", NAME="eth0" + + ''; +} diff --git a/modules/hosts/dnsc-vps-sm/default.nix b/modules/hosts/dnsc-vps-sm/default.nix new file mode 100644 index 0000000..f5ea706 --- /dev/null +++ b/modules/hosts/dnsc-vps-sm/default.nix @@ -0,0 +1,75 @@ +{ inputs, config, ... }: +let + hostname = "dnsc-vps-sm"; + secretsDir = "${inputs.self}/secrets"; +in +{ + flake.nixosConfigurations.${hostname} = inputs.nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = with config.flake.modules.nixos; [ + inputs.agenix.nixosModules.default + home-manager + base + server-shell + git + ssh + cli-tools + nix + restic + caddy + vaultwarden + uptime-kuma + homepage + actual-server + + ( + { config, ... }: + { + imports = [ + ./_hardware-configuration.nix + ./_networking.nix + ]; + + networking.hostName = hostname; + networking.hostId = "e5d5a602"; + networking.domain = "dnsc.io"; + networking.firewall = { + enable = true; + allowedTCPPorts = [ + 22 + 80 + 443 + ]; + }; + + system.stateVersion = "24.11"; + boot.tmp.cleanOnBoot = true; + zramSwap.enable = true; + # Fix due to https://github.com/NixOS/nixpkgs/issues/180175 + systemd.services.NetworkManager-wait-online.enable = false; + + # Secrets for this machine + age = { + identityPaths = [ + "${config.users.users.dennis.home}/.ssh/id_ed25519" + ]; + secrets."vaultwarden/env" = { + file = "${secretsDir}/vaultwarden/env"; + }; + secrets."restic/password" = { + file = "${secretsDir}/restic/password.age"; + }; + }; + + # Custom Module Options + restic.repository = "sftp:dnsc-storage:restic/dnsc-server"; + restic.backupPaths = [ + "/var/backup/vaultwarden" + "/data/actual-server" + # TODO: Include memos path, maybe uptime kuma + ]; + } + ) + ]; + }; +} diff --git a/modules/restic/default.nix b/modules/restic/default.nix index eb0fbf8..9b44db6 100644 --- a/modules/restic/default.nix +++ b/modules/restic/default.nix @@ -1,8 +1,25 @@ { inputs, ... }: { flake.modules.nixos.restic = - { pkgs, config, ... }: { + pkgs, + config, + lib, + ... + }: + { + options.restic = { + repository = lib.mkOption { + type = lib.types.str; + description = "The repository name to back up to"; + }; + backupPaths = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "List of paths to back up"; + }; + }; + # Root SSH for storage box programs.ssh = { extraConfig = '' @@ -20,12 +37,9 @@ "dnsc-storage" = { initialize = true; passwordFile = config.age.secrets."restic/password".path; - repository = "sftp:dnsc-storage:restic/dnsc-server"; + repository = config.restic.repository; createWrapper = true; - paths = [ - "/main/share" - "/data/actual-server" - ]; + paths = config.restic.backupPaths; pruneOpts = [ "--keep-last 3" ]; diff --git a/modules/selfhosted/actual-server/default.nix b/modules/selfhosted/actual-server/default.nix new file mode 100644 index 0000000..e1f52e2 --- /dev/null +++ b/modules/selfhosted/actual-server/default.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + flake.modules.nixos.actual-server = + { pkgs, config, ... }: + { + environment.systemPackages = with pkgs; [ + actual-server + ]; + + systemd.services.actual = { + enable = true; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + description = "user service for the actual budgeting server instance"; + environment = { + ACTUAL_PORT = "9002"; + }; + serviceConfig = { + Type = "simple"; + ExecStart = "/run/current-system/sw/bin/actual-server"; + Restart = "on-failure"; + RestartSec = 3; + }; + }; + }; +} diff --git a/modules/selfhosted/caddy/default.nix b/modules/selfhosted/caddy/default.nix new file mode 100644 index 0000000..b7da834 --- /dev/null +++ b/modules/selfhosted/caddy/default.nix @@ -0,0 +1,40 @@ +{ ... }: +{ + flake.modules.nixos.caddy = + { pkgs, ... }: + { + services.caddy = { + enable = true; + virtualHosts."www.dnsc.io".extraConfig = '' + redir https://dnsc.io{uri} + ''; + virtualHosts."dnsc.io".extraConfig = '' + encode gzip + file_server + + root * /var/www/homepage + ''; + virtualHosts."slides.dnsc.io".extraConfig = '' + encode gzip + file_server + + root * /var/www/slides + ''; + virtualHosts."vault.dnsc.io".extraConfig = '' + reverse_proxy localhost:8000 + ''; + virtualHosts."uptime.dnsc.io".extraConfig = '' + reverse_proxy localhost:9000 + ''; + virtualHosts."home.dnsc.io".extraConfig = '' + reverse_proxy localhost:9001 + ''; + virtualHosts."finance.dnsc.io".extraConfig = '' + reverse_proxy localhost:9002 + ''; + virtualHosts."notes.dnsc.io".extraConfig = '' + reverse_proxy localhost:9003 + ''; + }; + }; +} diff --git a/modules/selfhosted/homepage/default.nix b/modules/selfhosted/homepage/default.nix new file mode 100644 index 0000000..e55d206 --- /dev/null +++ b/modules/selfhosted/homepage/default.nix @@ -0,0 +1,219 @@ +{ ... }: +{ + flake.modules.nixos.homepage = + { pkgs, config, ... }: + { + environment.systemPackages = with pkgs; [ + glance + ]; + + services.glance = { + enable = true; + settings = { + server = { + port = 9001; + }; + theme = { + background-color = "hsl(264 31.3% 6.3%)"; + primary-color = "hsl(9 92.1% 85.1%)"; + contrast-multiplier = 1.2; + positive-color = "hsl(174 100% 32%)"; + negative-color = "hsl(354 100% 70.8%)"; + disable-picker = false; + }; + pages = [ + { + name = "Home"; + columns = [ + { + size = "small"; + widgets = [ + + { + type = "monitor"; + cache = "1m"; + title = "Selfhosted"; + sites = [ + { + title = "Fastmail"; + url = "https://app.fastmail.com/"; + icon = "si:protonmail"; + } + { + title = "Actual"; + url = "https://finance.dnsc.io"; + icon = "si:actualbudget"; + } + { + title = "Vaultwarden"; + url = "https://vault.dnsc.io"; + icon = "si:vaultwarden"; + } + { + title = "Notes"; + url = "https://notes.dnsc.io"; + icon = "si:memos"; + } + { + title = "Uptime Kuma"; + url = "https://uptime.dnsc.io"; + icon = "si:uptimekuma"; + } + { + title = "dnsc.io"; + url = "https://dnsc.io"; + icon = "si:htmx"; + } + { + title = "Jellyfin"; + url = "http://192.168.178.69:8096"; + icon = "si:jellyfin"; + allow-insecure = true; + } + ]; + } + { + type = "bookmarks"; + groups = [ + { + title = "Hosting"; + color = "hsl(187 56.6% 47.8%)"; + links = [ + { + title = "Hetzner"; + url = "https://console.hetzner.com/projects/1355757/dashboard"; + } + { + title = "Netcup"; + url = "https://www.servercontrolpanel.de/SCP/Home"; + } + { + title = "Porkbun"; + url = "https://porkbun.com/account/domainsSpeedy"; + } + ]; + } + { + title = "Dev"; + color = "hsl(319 37.6% 63.5%)"; + links = [ + { + title = "Codeberg"; + url = "https://codeberg.org/dnscio"; + } + { + title = "Github"; + url = "https://github.com/dennisschoepf?tab=repositories"; + } + ]; + } + ]; + } + ]; + } + { + size = "full"; + widgets = [ + { + type = "group"; + widgets = [ + { + type = "hacker-news"; + limit = 15; + collapse-after = 5; + } + { + type = "rss"; + title = "r/neovim"; + single-line-titles = true; + feeds = [ + { + url = "https://www.reddit.com/r/neovim.rss"; + } + ]; + } + { + type = "rss"; + title = "r/onepiece"; + single-line-titles = true; + feeds = [ + { + url = "https://www.reddit.com/r/onepiece.rss"; + } + ]; + } + { + type = "rss"; + title = "r/triathlon"; + single-line-titles = true; + feeds = [ + { + url = "https://www.reddit.com/r/triathlon.rss"; + } + ]; + } + ]; + } + { + type = "twitch-channels"; + channels = [ + "theprimeagen" + "tsoding" + "noway4u_sir" + "broxah" + "caedrel" + "bashbunni" + ]; + } + + { + type = "videos"; + collapse-after = 6; + channels = [ + "UCuTaETsuCOkJ0H_GAztWt0Q" + "UCJVMrR290HU9pDxaP35u_cg" + "UCqqJQ_cXSat0KIAVfIfKkVA" + "UCdC0An4ZPNr_YiFiYoVbwaw" + "UCsXVk37bltHxD1rDPwtNM8Q" + "UCofJu853kJKpkg4y5a-9YXg" + "UCewLMcro9tNP97XQ1rxtLXQ" + "UCuo9VyowIT-ljA5G2ZuC6Yw" + "UCipCyKo5D3FyWE6_TpQyr5A" + "UCmL9OhLB27r1lTCHQ3pEiIQ" + "UCNIuvl7V8zACPpTmmNIqP2A" + "UC-gct8TB_8l5HsQHBBr8hyQ" + ]; + } + ]; + } + { + size = "small"; + widgets = [ + { + type = "server-stats"; + servers = [ + { + name = "dnsc-vps-sm"; + type = "local"; + } + ]; + } + { + type = "calendar"; + first-day-of-the-week = "monday"; + } + { + type = "weather"; + units = "metric"; + hour-format = "24h"; + location = "Munich, Germany"; + } + ]; + } + ]; + } + ]; + }; + }; + }; +} diff --git a/modules/selfhosted/uptime-kuma/default.nix b/modules/selfhosted/uptime-kuma/default.nix new file mode 100644 index 0000000..420d86d --- /dev/null +++ b/modules/selfhosted/uptime-kuma/default.nix @@ -0,0 +1,13 @@ +{ ... }: +{ + flake.modules.nixos.uptime-kuma = + { pkgs, config, ... }: + { + services.uptime-kuma = { + enable = true; + settings = { + PORT = "9000"; + }; + }; + }; +} diff --git a/modules/selfhosted/vaultwarden/default.nix b/modules/selfhosted/vaultwarden/default.nix new file mode 100644 index 0000000..0e088e9 --- /dev/null +++ b/modules/selfhosted/vaultwarden/default.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + flake.modules.nixos.vaultwarden = + { pkgs, config, ... }: + { + services.vaultwarden = { + enable = true; + environmentFile = config.age.secrets."vaultwarden/env".path; + backupDir = "/var/backup/vaultwarden"; + }; + }; +}