diff options
| author | Isabella Bastaja <isabella@sorre.xyz> | 2026-08-18 20:07:35 +0200 |
|---|---|---|
| committer | Isabella Bastaja <isabella@sorre.xyz> | 2026-08-20 22:00:12 +0200 |
| commit | dcd2c4c4d71161301a956b7e4777b499f5010e74 (patch) | |
| tree | 91945b57a045cb79bd83e58e898f28c3a626c53c | |
| parent | b57bf02455c97a70efb22c6c7805f4df87c8b998 (diff) | |
tower: init
| -rw-r--r-- | flake.lock | 120 | ||||
| -rw-r--r-- | flake.nix | 6 | ||||
| -rw-r--r-- | hosts/tower/auto-update.nix | 80 | ||||
| -rw-r--r-- | hosts/tower/default.nix | 69 | ||||
| -rw-r--r-- | hosts/tower/hardware.nix | 48 | ||||
| -rw-r--r-- | hosts/tower/network.nix | 7 | ||||
| -rw-r--r-- | hosts/tower/ssh.nix | 16 | ||||
| -rw-r--r-- | hosts/tower/web/blog.nix | 24 | ||||
| -rw-r--r-- | hosts/tower/web/default.nix | 11 | ||||
| -rw-r--r-- | hosts/tower/web/git.nix | 55 | ||||
| -rw-r--r-- | hosts/tower/web/mediadb.nix | 50 | ||||
| -rw-r--r-- | hosts/tower/web/navidrome.nix | 46 | ||||
| -rw-r--r-- | hosts/tower/web/static.nix | 12 | ||||
| -rw-r--r-- | hosts/tower/web/vaultwarden.nix | 41 |
14 files changed, 480 insertions, 105 deletions
@@ -42,32 +42,16 @@ "type": "github" } }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "NixOS", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1769996383, - "narHash": "sha256-AnYjnFWgS49RlqX7LrC4uA+sCCDBj0Ry/WOJ5XWAsa0=", + "lastModified": 1785627969, + "narHash": "sha256-4dtXQk/NMePegK/nWp5NSeuZKLATItOq61lpEvmXqGw=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "57928607ea566b5db3ad13af0e57e921e6b12381", + "rev": "427bf4bd9435fdf21321c8cc628c24efc14c0f7a", "type": "github" }, "original": { @@ -105,33 +89,11 @@ "rev": "aaa51589dd772073c6eb48d6b7bd51dc8be3b455", "revCount": 4, "type": "git", - "url": "https://git.sorre.xyz/isabella/futils.git" + "url": "https://git.sorre.xyz/futils" }, "original": { "type": "git", - "url": "https://git.sorre.xyz/isabella/futils.git" - } - }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "sorre-website", - "pre-commit-hooks-nix", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" + "url": "https://git.sorre.xyz/futils" } }, "home-manager": { @@ -230,11 +192,11 @@ }, "nixpkgs-lib": { "locked": { - "lastModified": 1769909678, - "narHash": "sha256-cBEymOf4/o3FD5AZnzC3J9hLbiZ+QDT/KDuyHXVJOpM=", + "lastModified": 1785031560, + "narHash": "sha256-OmshNvn2vupOFpYinLUu+1Dnpu4n7Q5N3ggGVNHpkUI=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "72716169fe93074c333e8d0173151350670b824c", + "rev": "0e79af5e3d4dcfcd676ab5ba3f95d2e3352e078c", "type": "github" }, "original": { @@ -290,29 +252,6 @@ "type": "github" } }, - "pre-commit-hooks-nix": { - "inputs": { - "flake-compat": "flake-compat", - "gitignore": "gitignore", - "nixpkgs": [ - "sorre-website", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770726378, - "narHash": "sha256-kck+vIbGOaM/dHea7aTBxdFYpeUl/jHOy5W3eyRvVx8=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "5eaaedde414f6eb1aea8b8525c466dc37bba95ae", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { "disko": "disko", @@ -322,7 +261,7 @@ "nixpkgs": "nixpkgs", "sops-nix": "sops-nix", "sorre-website": "sorre-website", - "treefmt-nix": "treefmt-nix_2", + "treefmt-nix": "treefmt-nix", "xpkgs": "xpkgs" } }, @@ -351,22 +290,20 @@ "flake-parts": "flake-parts", "nixpkgs": [ "nixpkgs" - ], - "pre-commit-hooks-nix": "pre-commit-hooks-nix", - "treefmt-nix": "treefmt-nix" + ] }, "locked": { - "lastModified": 1771694213, - "narHash": "sha256-T827T+TH1BMcYOjSoX1TfT26wn8cvvhp0dkyGgL0JCg=", + "lastModified": 1786301621, + "narHash": "sha256-G3tCj+gVYP9CNaq7qrBm3+mlNxwwTX2ozCrnzz9B+48=", "ref": "refs/heads/main", - "rev": "d4cc95fe9d1810f273900de3ed1d7cc40b4b2e94", - "revCount": 22, + "rev": "8464edabb2f97a10152c1a8f580110213b8f56c9", + "revCount": 24, "type": "git", - "url": "https://git.sorre.xyz/isabella/sorre-website.git" + "url": "https://git.sorre.xyz/sorre-website" }, "original": { "type": "git", - "url": "https://git.sorre.xyz/isabella/sorre-website.git" + "url": "https://git.sorre.xyz/sorre-website" } }, "systems": { @@ -387,27 +324,6 @@ "treefmt-nix": { "inputs": { "nixpkgs": [ - "sorre-website", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1770228511, - "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", - "owner": "numtide", - "repo": "treefmt-nix", - "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "treefmt-nix", - "type": "github" - } - }, - "treefmt-nix_2": { - "inputs": { - "nixpkgs": [ "nixpkgs" ] }, @@ -456,11 +372,11 @@ "rev": "0b2c891d6bb4a18f18ac7e52df896e40d86829d7", "revCount": 30, "type": "git", - "url": "https://git.sorre.xyz/isabella/xpkgs" + "url": "https://git.sorre.xyz/xpkgs" }, "original": { "type": "git", - "url": "https://git.sorre.xyz/isabella/xpkgs" + "url": "https://git.sorre.xyz/xpkgs" } }, "xwayland-satellite-stable": { @@ -3,7 +3,7 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; - futils.url = "git+https://git.sorre.xyz/isabella/futils.git"; + futils.url = "git+https://git.sorre.xyz/futils"; disko = { url = "github:nix-community/disko"; inputs.nixpkgs.follows = "nixpkgs"; @@ -17,11 +17,11 @@ inputs.nixpkgs.follows = "nixpkgs"; }; sorre-website = { - url = "git+https://git.sorre.xyz/isabella/sorre-website.git"; + url = "git+https://git.sorre.xyz/sorre-website"; inputs.nixpkgs.follows = "nixpkgs"; }; xpkgs = { - url = "git+https://git.sorre.xyz/isabella/xpkgs"; + url = "git+https://git.sorre.xyz/xpkgs"; inputs.nixpkgs.follows = "nixpkgs"; }; niri-flake = { diff --git a/hosts/tower/auto-update.nix b/hosts/tower/auto-update.nix new file mode 100644 index 0000000..2afa4b9 --- /dev/null +++ b/hosts/tower/auto-update.nix @@ -0,0 +1,80 @@ +{ pkgs, ... }: +let + configRepoSource = "file:///var/lib/git/repos/isabella/nixos-config"; +in +{ + systemd.timers.auto-update-nixos = { + enable = false; + description = "Fetch and update the NixOS config every minute"; + timerConfig = { + Unit = "update-nixos.service"; + OnUnitActiveSec = "60s"; + }; + wantedBy = [ "multi-user.target" ]; + }; + + systemd.services.update-nixos = { + enable = false; + description = "Fetches and update the NixOS config"; + serviceConfig = { + Type = "oneshot"; + User = "root"; + StandardOutput = "journal"; + StandardError = "journal"; + }; + path = [ + pkgs.gitMinimal + pkgs.nixos-rebuild-ng + ]; + # we need root privileges for a system update anyway + confinement.enable = false; + + enableStrictShellChecks = true; + script = '' + #!/bin/sh + set -eu + + SRC_REPO="$1" + if [ -z "$SRC_REPO" ]; then + echo "Error: git repository source was not provided." >&2 + exit 1 + fi + + TEMP_DIR="$(mktemp --directory)" + git clone --depth 1 "$SRC_REPO" "$TEMP_DIR" + + pushd "$TEMP_DIR" + + TAGS="$(git tag --sort tag --list 'v*')" + LATEST_TAG="$(echo "$TAGS" | tail --lines 1)" + + if [ -z "$LATEST_TAG" ]; then + echo "Error: no release tags defined." >&2 + exit 1 + fi + + git fetch "$SRC_REPO" "$LATEST_TAG" + git checkout FETCH_HEAD + + CURRENT_REV="$(git rev-parse HEAD)" + STATE_DIR="/var/lib/auto-update" + [ -d "$STATE_DIR" ] || mkdir -p "$STATE_DIR" + + if [ -e "$STATE_DIR/last-commit" ]; then + LAST_REV="$(cat "$STATE_DIR/last-commit")" + if [ "$CURRENT_REV" = "$LAST_REV" ]; then + echo "System is already up to date. Exiting." >&2 + exit 0 + fi + fi + echo -n "$CURRENT_REV" > "$STATE_DIR/last-commit" + + nixos-rebuild switch --flake .# + + popd + + rm -rf "$TEMP_DIR" + ''; + scriptArgs = "${configRepoSource}"; + }; +} diff --git a/hosts/tower/default.nix b/hosts/tower/default.nix new file mode 100644 index 0000000..4fe610f --- /dev/null +++ b/hosts/tower/default.nix @@ -0,0 +1,69 @@ +{ ... }: +{ + imports = [ + # Include the results of the hardware scan. + ./hardware.nix + ./ssh.nix + ./web + ./network.nix + ./auto-update.nix + ]; + + boot.loader.grub.device = "/dev/sda"; + time.timeZone = "Europe/Zagreb"; + + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + dockerSocket.enable = true; + }; + + # Set the max amount of space used for logs + services.journald.extraConfig = '' + SystemMaxUse=100M + ''; + + # Select internationalisation properties. + i18n.defaultLocale = "en_US.UTF-8"; + i18n.extraLocaleSettings = { + LC_ADDRESS = "hr_HR.UTF-8"; + LC_IDENTIFICATION = "hr_HR.UTF-8"; + LC_MEASUREMENT = "hr_HR.UTF-8"; + LC_MONETARY = "hr_HR.UTF-8"; + LC_NAME = "hr_HR.UTF-8"; + LC_NUMERIC = "hr_HR.UTF-8"; + LC_PAPER = "hr_HR.UTF-8"; + LC_TELEPHONE = "hr_HR.UTF-8"; + LC_TIME = "hr_HR.UTF-8"; + }; + + programs.gnupg.agent = { + enable = true; + enableSSHSupport = true; + }; + + users.users = { + isabella = { + isNormalUser = true; + description = "Isabella Morgana Bastaja"; + extraGroups = [ + "networkmanager" + "wheel" + ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM4aG8NI25TgjcDevjsY/Y6d3iYsQxSEtIpsqprMHmad osiris@underworld" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPUcWGKF3uIf/gqbo1/lxb8XLoi67Bc2tVi1Bd/Ddhoz isabella@wonderland" + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEvtzeVHgenfSUrpZeyZBoBTzN96rdYMy3KEJoRXja0O isabella@nyaan" + ]; + }; + }; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "26.05"; # Did you read the comment? +} diff --git a/hosts/tower/hardware.nix b/hosts/tower/hardware.nix new file mode 100644 index 0000000..c776489 --- /dev/null +++ b/hosts/tower/hardware.nix @@ -0,0 +1,48 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ + config, + lib, + pkgs, + modulesPath, + ... +}: + +{ + imports = [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ + "xhci_pci" + "ehci_pci" + "ahci" + "usbhid" + "usb_storage" + "sd_mod" + "sr_mod" + ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/f6e9f2b9-0a50-4e1e-aeb9-2021e174c540"; + fsType = "xfs"; + }; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/FA99-9BD0"; + fsType = "vfat"; + options = [ + "fmask=0077" + "dmask=0077" + ]; + }; + + swapDevices = [ ]; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/tower/network.nix b/hosts/tower/network.nix new file mode 100644 index 0000000..fc0fdc5 --- /dev/null +++ b/hosts/tower/network.nix @@ -0,0 +1,7 @@ +{ ... }: +{ + networking = { + hostName = "tower"; + networkmanager.enable = true; + }; +} diff --git a/hosts/tower/ssh.nix b/hosts/tower/ssh.nix new file mode 100644 index 0000000..13da162 --- /dev/null +++ b/hosts/tower/ssh.nix @@ -0,0 +1,16 @@ +{ ... }: +{ + services.openssh = { + enable = true; + ports = [ 52222 ]; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + AllowUsers = [ + "isabella" + ]; + }; + }; + + networking.firewall.allowedTCPPorts = [ 52222 ]; +} diff --git a/hosts/tower/web/blog.nix b/hosts/tower/web/blog.nix new file mode 100644 index 0000000..7cefd6e --- /dev/null +++ b/hosts/tower/web/blog.nix @@ -0,0 +1,24 @@ +{ + inputs, + pkgs, + # config, + ... +}: +{ + services.nginx = { + enable = true; + + virtualHosts."sorre.xyz" = { + # enableACME = true; + # forceSSL = true; + root = inputs.sorre-website.packages.${pkgs.system}.default; + }; + + virtualHosts."priv.sorre.xyz" = { + # enableACME = true; + # forceSSL = true; + root = "/var/www/priv"; + # basicAuthFile = config.sops.secrets."priv-blog-auth-file".path; + }; + }; +} diff --git a/hosts/tower/web/default.nix b/hosts/tower/web/default.nix new file mode 100644 index 0000000..2424eaf --- /dev/null +++ b/hosts/tower/web/default.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + imports = [ + ./blog.nix + ./mediadb.nix + ./git.nix + ./static.nix + ./navidrome.nix + ./vaultwarden.nix + ]; +} diff --git a/hosts/tower/web/git.nix b/hosts/tower/web/git.nix new file mode 100644 index 0000000..4dcae8e --- /dev/null +++ b/hosts/tower/web/git.nix @@ -0,0 +1,55 @@ +{ config, ... }: +let + # secrets = config.sops.secrets; + domainInternal = "git.sorre.internal"; + domainPublic = "git.sorre.xyz"; + + commonSettings = { + readme = "main:README.md"; + }; +in +{ + services.nginx = { + enable = true; + virtualHosts."${domainInternal}" = { + # forceSSL = true; + # sslCertificateKey = secrets."wg-ca-key".path; + # sslCertificate = secrets."wg-ca-crt".path; + listen = [ + { + addr = "100.64.0.3"; + port = 443; + # ssl = true; + } + ]; + }; + + virtualHosts."${domainPublic}" = { + # enableACME = true; + # forceSSL = true; + }; + }; + + services.cgit.internal = { + enable = true; + user = "cgit-internal"; + group = "cgit"; + nginx.virtualHost = domainInternal; + gitHttpBackend.checkExportOkFiles = false; + scanPath = "/var/lib/git/repos/isabella"; + settings = commonSettings; + }; + + services.cgit.public = { + enable = true; + user = "cgit-public"; + group = "cgit"; + nginx.virtualHost = domainPublic; + gitHttpBackend.checkExportOkFiles = false; + repos = { + futils.path = "/var/lib/git/repos/isabella/futils"; + nixos-config.path = "/var/lib/git/repos/isabella/nixos-config"; + }; + settings = commonSettings; + }; +} diff --git a/hosts/tower/web/mediadb.nix b/hosts/tower/web/mediadb.nix new file mode 100644 index 0000000..67c9fdd --- /dev/null +++ b/hosts/tower/web/mediadb.nix @@ -0,0 +1,50 @@ +{ + pkgs, + lib, + config, + ... +}: +let + newPostgres = pkgs.postgresql_18_jit; + cfg = config.services.postgresql; + upgrade-pg-cluster = pkgs.writeScriptBin "upgrade-pg-cluster" '' + set -eux + systemctl stop postgresql + + export NEWDATA="/var/lib/postgresql/${newPostgres.psqlSchema}" + export NEWBIN="${newPostgres}/bin" + + export OLDDATA="${cfg.dataDir}" + export OLDBIN="${cfg.finalPackage}/bin" + + install -d -m 0700 -o postgres -g postgres "$NEWDATA" + cd "$NEWDATA" + sudo -u postgres "$NEWBIN/initdb" -D "$NEWDATA" ${lib.escapeShellArgs cfg.initdbArgs} + + sudo -u postgres "$NEWBIN/pg_upgrade" \ + --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ + --old-bindir "$OLDBIN" --new-bindir "$NEWBIN" \ + "$@" + ''; +in +{ + services.postgresql = { + enable = true; + package = pkgs.postgresql_18_jit; + enableTCPIP = true; + enableJIT = true; + + settings = { + password_encryption = "scram-sha-256"; + }; + + authentication = '' + # TYPE DATABASE USER ADDRESS METHOD + local all all peer + host all postgres all reject + host all all all scram-sha-256 + ''; + }; # end of services.postgreslq + + environment.systemPackages = [ upgrade-pg-cluster ]; +} diff --git a/hosts/tower/web/navidrome.nix b/hosts/tower/web/navidrome.nix new file mode 100644 index 0000000..70d2779 --- /dev/null +++ b/hosts/tower/web/navidrome.nix @@ -0,0 +1,46 @@ +{ config, ... }: +let + cfg = config.services.navidrome; + # secrets = config.sops.secrets; + domain = "music.sorre.internal"; +in +{ + services.navidrome = { + enable = false; + settings = { + MusicFolder = "/var/navidrome/music"; + DataFolder = "/var/navidrome/data"; + BaseUrl = "https://${domain}"; + Port = 4533; + Address = "127.0.0.1"; + openFirewall = false; + }; + }; + + services.nginx = { + enable = true; + + virtualHosts."navidrome" = { + serverName = domain; + # forceSSL = true; + listen = [ + { + addr = "100.64.0.3"; + port = 443; + # ssl = true; + } + ]; + + # sslCertificateKey = secrets."wg-ca-key".path; + # sslCertificate = secrets."wg-ca-crt".path; + + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.settings.Port}"; + recommendedProxySettings = true; + extraConfig = '' + proxy_buffering off; + ''; + }; + }; + }; +} diff --git a/hosts/tower/web/static.nix b/hosts/tower/web/static.nix new file mode 100644 index 0000000..d73d566 --- /dev/null +++ b/hosts/tower/web/static.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + services.nginx = { + enable = true; + + virtualHosts."static.sorre.xyz" = { + # enableACME = true; + # forceSSL = true; + root = "/var/www/static"; + }; + }; +} diff --git a/hosts/tower/web/vaultwarden.nix b/hosts/tower/web/vaultwarden.nix new file mode 100644 index 0000000..68bb1cd --- /dev/null +++ b/hosts/tower/web/vaultwarden.nix @@ -0,0 +1,41 @@ +{ config, ... }: +let + cfg = config.services.vaultwarden.config; + # secrets = config.sops.secrets; + domain = "vaultwarden.sorre.internal"; +in +{ + services.vaultwarden = { + enable = true; + configureNginx = false; + dbBackend = "sqlite"; + inherit domain; + config = { + SIGNUPS_ALLOWED = false; + + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8222; + ROCKET_LOG = "critical"; + }; + }; + + services.nginx.virtualHosts."vaultwarden" = { + serverName = domain; + # forceSSL = true; + listen = [ + { + addr = "100.64.0.3"; + port = 443; + # ssl = true; + } + ]; + + # sslCertificateKey = secrets."wg-ca-key".path; + # sslCertificate = secrets."wg-ca-crt".path; + + locations."/" = { + proxyPass = "http://127.0.0.1:${toString cfg.ROCKET_PORT}"; + recommendedProxySettings = true; + }; + }; +} |
