aboutsummaryrefslogtreecommitdiff
path: root/hosts/tower
diff options
context:
space:
mode:
authorIsabella Bastaja <isabella@sorre.xyz>2026-08-18 20:07:35 +0200
committerIsabella Bastaja <isabella@sorre.xyz>2026-08-20 22:00:12 +0200
commitdcd2c4c4d71161301a956b7e4777b499f5010e74 (patch)
tree91945b57a045cb79bd83e58e898f28c3a626c53c /hosts/tower
parentb57bf02455c97a70efb22c6c7805f4df87c8b998 (diff)
tower: init
Diffstat (limited to 'hosts/tower')
-rw-r--r--hosts/tower/auto-update.nix80
-rw-r--r--hosts/tower/default.nix69
-rw-r--r--hosts/tower/hardware.nix48
-rw-r--r--hosts/tower/network.nix7
-rw-r--r--hosts/tower/ssh.nix16
-rw-r--r--hosts/tower/web/blog.nix24
-rw-r--r--hosts/tower/web/default.nix11
-rw-r--r--hosts/tower/web/git.nix55
-rw-r--r--hosts/tower/web/mediadb.nix50
-rw-r--r--hosts/tower/web/navidrome.nix46
-rw-r--r--hosts/tower/web/static.nix12
-rw-r--r--hosts/tower/web/vaultwarden.nix41
12 files changed, 459 insertions, 0 deletions
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;
+ };
+ };
+}