Compare commits

..

No commits in common. "master" and "terranix" have entirely different histories.

50 changed files with 416 additions and 1111 deletions

2
.gitignore vendored
View file

@ -3,8 +3,6 @@ result
result-* result-*
.direnv/ .direnv/
oci-trantor/ oci-trantor/
tailscale-tailnet/
cloudflare-baduhaidev
# Personal notes and temporary files # Personal notes and temporary files
todo.md todo.md

View file

@ -1,12 +1,12 @@
{ inputs, ... }: { ... }:
{ {
perSystem = perSystem =
{ pkgs, system, ... }: { pkgs, ... }:
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
packages = with pkgs; [ packages = with pkgs; [
inputs.agenix.packages.${system}.default agenix-cli
deploy-rs deploy-rs
nil nil
nixfmt-rfc-style nixfmt-rfc-style

View file

@ -1,8 +1,4 @@
{ inputs, ... }:
{ {
imports = [ inputs.disko.nixosModules.default ];
disko.devices.disk.main = { disko.devices.disk.main = {
type = "disk"; type = "disk";
device = "/dev/disk/by-id/mmc-hDEaP3_0x1041b689"; device = "/dev/disk/by-id/mmc-hDEaP3_0x1041b689";

View file

@ -1,11 +1,7 @@
{ inputs, ... }:
{ {
imports = [ inputs.disko.nixosModules.default ];
disko.devices.disk.main = { disko.devices.disk.main = {
type = "disk"; type = "disk";
device = "/dev/disk/by-id/scsi-360b207ed25d84372a95d1ecf842f8e20"; device = "/dev/disk/by-id/scsi-36067d367fe184830a89bbe708c7b1066";
content = { content = {
type = "gpt"; type = "gpt";
partitions = { partitions = {
@ -31,7 +27,8 @@
name = "root"; name = "root";
size = "100%"; size = "100%";
content = { content = {
type = "btrfs"; type = "filesystem";
format = "btrfs";
extraArgs = [ "-f" ]; extraArgs = [ "-f" ];
subvolumes = { subvolumes = {
"@root" = { "@root" = {

12
diskoConfigurations.nix Normal file
View file

@ -0,0 +1,12 @@
{ inputs, ... }:
{
imports = [
inputs.disko.flakeModule
];
flake.diskoConfigurations = {
io.modules = [ ./disko/io.nix ];
trantor.modules = [ ./disko/trantor.nix ];
};
}

348
flake.lock generated
View file

@ -10,11 +10,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1761656077, "lastModified": 1760836749,
"narHash": "sha256-lsNWuj4Z+pE7s0bd2OKicOFq9bK86JE0ZGeKJbNqb94=", "narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm", "owner": "ryantm",
"repo": "agenix", "repo": "agenix",
"rev": "9ba0d85de3eaa7afeab493fed622008b6e4924f5", "rev": "2f0f812f69f3eb4140157fe15e12739adf82e32a",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -91,28 +91,6 @@
"type": "github" "type": "github"
} }
}, },
"blueprint": {
"inputs": {
"nixpkgs": [
"nix-ai-tools",
"nixpkgs"
],
"systems": "systems_3"
},
"locked": {
"lastModified": 1763308703,
"narHash": "sha256-O9Y+Wer8wOh+N+4kcCK5p/VLrXyX+ktk0/s3HdZvJzk=",
"owner": "numtide",
"repo": "blueprint",
"rev": "5a9bba070f801d63e2af3c9ef00b86b212429f4f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "blueprint",
"type": "github"
}
},
"darwin": { "darwin": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
@ -208,11 +186,11 @@
"flake-compat_2": { "flake-compat_2": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1761588595, "lastModified": 1747046372,
"narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=", "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
"owner": "edolstra", "owner": "edolstra",
"repo": "flake-compat", "repo": "flake-compat",
"rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5", "rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -226,11 +204,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1762040540, "lastModified": 1760948891,
"narHash": "sha256-z5PlZ47j50VNF3R+IMS9LmzI5fYRGY/Z5O5tol1c9I4=", "narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "0010412d62a25d959151790968765a70c436598b", "rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -283,25 +261,7 @@
}, },
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems_4" "systems": "systems_3"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_8"
}, },
"locked": { "locked": {
"lastModified": 1731533236, "lastModified": 1731533236,
@ -378,11 +338,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1762178366, "lastModified": 1760929667,
"narHash": "sha256-I+8yE5HVR2SFcHnW0771psQ/zn0qVzsKHY/gUM0nEVM=", "narHash": "sha256-nZh6uvc71nVNaf/y+wesnjwsmJ6IZZUnP2EzpZe48To=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "8c824254b1ed9e797f6235fc3c62f365893c561a", "rev": "189c21cf879669008ccf06e78a553f17e88d8ef0",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -458,11 +418,11 @@
"xwayland-satellite-unstable": "xwayland-satellite-unstable" "xwayland-satellite-unstable": "xwayland-satellite-unstable"
}, },
"locked": { "locked": {
"lastModified": 1762152856, "lastModified": 1760950171,
"narHash": "sha256-U3SDbk7tIwLChpvb3FL66o8V0byaQ2RGMiy/3oLdxTI=", "narHash": "sha256-E2ySTu/oK7cYBdAI3tlGP9zVjF4mZgWJ1OZInBCMb00=",
"owner": "sodiboo", "owner": "sodiboo",
"repo": "niri-flake", "repo": "niri-flake",
"rev": "df17789929ac80f4157b15724450db6a303a6dc9", "rev": "f851a923137c0a54719412146fd63d24b3214e60",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -491,11 +451,11 @@
"niri-unstable": { "niri-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1762146685, "lastModified": 1760940149,
"narHash": "sha256-anRlNG6t7esBbF1+ALDeathVBSclA0PEL52Vo0WnN5g=", "narHash": "sha256-KbM47vD6E0cx+v4jYQZ8mD5N186AKm2CQlyh34TW58U=",
"owner": "YaLTeR", "owner": "YaLTeR",
"repo": "niri", "repo": "niri",
"rev": "a2ca2b3c866bc781b12c334a9f949b3db6d7c943", "rev": "b3245b81a6ed8edfaf5388a74d2e0a23c24941e5",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -504,26 +464,6 @@
"type": "github" "type": "github"
} }
}, },
"nix-ai-tools": {
"inputs": {
"blueprint": "blueprint",
"nixpkgs": "nixpkgs_5",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1763412165,
"narHash": "sha256-n6bChFrCf2/uHzTsZdABUt1+Ua3n0jinNfamHd5DmBA=",
"owner": "numtide",
"repo": "nix-ai-tools",
"rev": "a2dfa932ed37e5b6224b39b4982c85cd8ebcca14",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "nix-ai-tools",
"type": "github"
}
},
"nix-flatpak": { "nix-flatpak": {
"locked": { "locked": {
"lastModified": 1754777568, "lastModified": 1754777568,
@ -547,11 +487,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1762055842, "lastModified": 1760846226,
"narHash": "sha256-Pu1v3mlFhRzZiSxVHb2/i/f5yeYyRNqr0RvEUJ4UgHo=", "narHash": "sha256-xmU8kAsRprJiTGBTaGrwmjBP3AMA9ltlrxHKFuy5JWc=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nix-index-database", "repo": "nix-index-database",
"rev": "359ff6333a7b0b60819d4c20ed05a3a1f726771f", "rev": "5024e1901239a76b7bf94a4cd27f3507e639d49e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -563,7 +503,7 @@
"nix-options-doc": { "nix-options-doc": {
"inputs": { "inputs": {
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"nixpkgs": "nixpkgs_6", "nixpkgs": "nixpkgs_5",
"rust-overlay": "rust-overlay_2" "rust-overlay": "rust-overlay_2"
}, },
"locked": { "locked": {
@ -585,14 +525,14 @@
"inputs": { "inputs": {
"flake-compat": "flake-compat_2", "flake-compat": "flake-compat_2",
"nix-options-doc": "nix-options-doc", "nix-options-doc": "nix-options-doc",
"nixpkgs": "nixpkgs_7" "nixpkgs": "nixpkgs_6"
}, },
"locked": { "locked": {
"lastModified": 1761970410, "lastModified": 1760856139,
"narHash": "sha256-IUm2nkbKlDkG94ruTmIYLERpBn6gXydm3scZIKzpcKs=", "narHash": "sha256-N+F4n1WYE3AWc/kmdqIz67GNX7PgyKosnmGYYx8vR9k=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixos-cli", "repo": "nixos-cli",
"rev": "5c259f72ae1eaa00b99354d81130d8fddb7f9a7a", "rev": "c8f5ce1fd9bf151df74328795b6b2720e2e22d75",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -619,11 +559,11 @@
}, },
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"lastModified": 1761765539, "lastModified": 1754788789,
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=", "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
"owner": "nix-community", "owner": "nix-community",
"repo": "nixpkgs.lib", "repo": "nixpkgs.lib",
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc", "rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -634,11 +574,11 @@
}, },
"nixpkgs-stable": { "nixpkgs-stable": {
"locked": { "locked": {
"lastModified": 1761999846, "lastModified": 1760862643,
"narHash": "sha256-IYlYnp4O4dzEpL77BD/lj5NnJy2J8qbHkNSFiPBCbqo=", "narHash": "sha256-PXwG0TM7Ek87DNx4LbGWuD93PbFeKAJs4FfALtp7Wo0=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "3de8f8d73e35724bf9abef41f1bdbedda1e14a31", "rev": "33c6dca0c0cb31d6addcd34e90a63ad61826b28c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -650,11 +590,11 @@
}, },
"nixpkgs-stable_2": { "nixpkgs-stable_2": {
"locked": { "locked": {
"lastModified": 1761999846, "lastModified": 1760862643,
"narHash": "sha256-IYlYnp4O4dzEpL77BD/lj5NnJy2J8qbHkNSFiPBCbqo=", "narHash": "sha256-PXwG0TM7Ek87DNx4LbGWuD93PbFeKAJs4FfALtp7Wo0=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "3de8f8d73e35724bf9abef41f1bdbedda1e14a31", "rev": "33c6dca0c0cb31d6addcd34e90a63ad61826b28c",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -664,45 +604,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_10": {
"locked": {
"lastModified": 1762111121,
"narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_11": {
"locked": {
"lastModified": 1755615617,
"narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "20075955deac2583bb12f07151c2df830ef346b4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": { "nixpkgs_2": {
"locked": { "locked": {
"lastModified": 1752596105, "lastModified": 1761880412,
"narHash": "sha256-lFNVsu/mHLq3q11MuGkMhUUoSXEdQjCHvpReaGP1S2k=", "narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "dab3a6e781554f965bde3def0aa2fda4eb8f1708", "rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -730,11 +638,11 @@
}, },
"nixpkgs_4": { "nixpkgs_4": {
"locked": { "locked": {
"lastModified": 1761907660, "lastModified": 1760878510,
"narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=", "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2fb006b87f04c4d3bdf08cfdbc7fab9c13d94a15", "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -745,22 +653,6 @@
} }
}, },
"nixpkgs_5": { "nixpkgs_5": {
"locked": {
"lastModified": 1763312402,
"narHash": "sha256-3YJkOBrFpmcusnh7i8GXXEyh7qZG/8F5z5+717550Hk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "85a6c4a07faa12aaccd81b36ba9bfc2bec974fa1",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_6": {
"locked": { "locked": {
"lastModified": 1740695751, "lastModified": 1740695751,
"narHash": "sha256-D+R+kFxy1KsheiIzkkx/6L63wEHBYX21OIwlFV8JvDs=", "narHash": "sha256-D+R+kFxy1KsheiIzkkx/6L63wEHBYX21OIwlFV8JvDs=",
@ -776,13 +668,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_7": { "nixpkgs_6": {
"locked": { "locked": {
"lastModified": 1761880412, "lastModified": 1759070547,
"narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=", "narHash": "sha256-JVZl8NaVRYb0+381nl7LvPE+A774/dRpif01FKLrYFQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386", "rev": "647e5c14cbd5067f44ac86b74f014962df460840",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -792,13 +684,13 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_8": { "nixpkgs_7": {
"locked": { "locked": {
"lastModified": 1761907660, "lastModified": 1760878510,
"narHash": "sha256-kJ8lIZsiPOmbkJypG+B5sReDXSD1KGu2VEPNqhRa/ew=", "narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2fb006b87f04c4d3bdf08cfdbc7fab9c13d94a15", "rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -808,7 +700,7 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_9": { "nixpkgs_8": {
"locked": { "locked": {
"lastModified": 1758690382, "lastModified": 1758690382,
"narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=", "narHash": "sha256-NY3kSorgqE5LMm1LqNwGne3ZLMF2/ILgLpFr1fS4X3o=",
@ -824,20 +716,36 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs_9": {
"locked": {
"lastModified": 1755615617,
"narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "20075955deac2583bb12f07151c2df830ef346b4",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"noctalia": { "noctalia": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"quickshell": "quickshell", "quickshell": "quickshell",
"systems": "systems_5" "systems": "systems_4"
}, },
"locked": { "locked": {
"lastModified": 1762156721, "lastModified": 1761190730,
"narHash": "sha256-gHfzrTDSnNC5yRJwkZfP55fPHUc8DuB4OQEIBSQSs18=", "narHash": "sha256-XAs/Q4zBJIfK/bwq9KjTUkTH15A+Pe2rIilyvalEHuM=",
"owner": "noctalia-dev", "owner": "noctalia-dev",
"repo": "noctalia-shell", "repo": "noctalia-shell",
"rev": "5ca5aa602f58a8e0e73fedbef351f1cdf8cbe981", "rev": "c3439b262c7cb3d57c93197a93a3aa382582bdae",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -879,11 +787,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1761821581, "lastModified": 1753595452,
"narHash": "sha256-nLuc6jA7z+H/6bHPEBSOYPbz7RtvNCZiTKmYItJuBmM=", "narHash": "sha256-vqkSDvh7hWhPvNjMjEDV4KbSCv2jyl2Arh73ZXe274k=",
"ref": "refs/heads/master", "ref": "refs/heads/master",
"rev": "db1777c20b936a86528c1095cbcb1ebd92801402", "rev": "a5431dd02dc23d9ef1680e67777fed00fe5f7cda",
"revCount": 699, "revCount": 665,
"type": "git", "type": "git",
"url": "https://git.outfoxxed.me/outfoxxed/quickshell" "url": "https://git.outfoxxed.me/outfoxxed/quickshell"
}, },
@ -902,16 +810,14 @@
"impermanence": "impermanence", "impermanence": "impermanence",
"niri": "niri", "niri": "niri",
"niri-flake": "niri-flake", "niri-flake": "niri-flake",
"nix-ai-tools": "nix-ai-tools",
"nix-flatpak": "nix-flatpak", "nix-flatpak": "nix-flatpak",
"nix-index-database": "nix-index-database", "nix-index-database": "nix-index-database",
"nixos-cli": "nixos-cli", "nixos-cli": "nixos-cli",
"nixpkgs": "nixpkgs_8", "nixpkgs": "nixpkgs_7",
"nixpkgs-stable": "nixpkgs-stable_2", "nixpkgs-stable": "nixpkgs-stable_2",
"noctalia": "noctalia", "noctalia": "noctalia",
"stylix": "stylix", "stylix": "stylix",
"terranix": "terranix", "terranix": "terranix",
"vicinae": "vicinae",
"zen-browser": "zen-browser" "zen-browser": "zen-browser"
} }
}, },
@ -967,9 +873,9 @@
"firefox-gnome-theme": "firefox-gnome-theme", "firefox-gnome-theme": "firefox-gnome-theme",
"flake-parts": "flake-parts_2", "flake-parts": "flake-parts_2",
"gnome-shell": "gnome-shell", "gnome-shell": "gnome-shell",
"nixpkgs": "nixpkgs_9", "nixpkgs": "nixpkgs_8",
"nur": "nur", "nur": "nur",
"systems": "systems_6", "systems": "systems_5",
"tinted-foot": "tinted-foot", "tinted-foot": "tinted-foot",
"tinted-kitty": "tinted-kitty", "tinted-kitty": "tinted-kitty",
"tinted-schemes": "tinted-schemes", "tinted-schemes": "tinted-schemes",
@ -977,11 +883,11 @@
"tinted-zed": "tinted-zed" "tinted-zed": "tinted-zed"
}, },
"locked": { "locked": {
"lastModified": 1762101397, "lastModified": 1760472212,
"narHash": "sha256-wGiL2K3kAyBBmIZpJEskaSIgyzzpg0zwfvri+Sy6/CI=", "narHash": "sha256-4C3I/ssFsq8EgaUmZP0xv5V7RV0oCHgL/Rx+MUkuE+E=",
"owner": "danth", "owner": "danth",
"repo": "stylix", "repo": "stylix",
"rev": "8c0640d5722a02178c8ee80a62c5f019cab4b3c1", "rev": "8d008296a1b3be9b57ad570f7acea00dd2fc92db",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1080,50 +986,20 @@
"type": "github" "type": "github"
} }
}, },
"systems_7": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_8": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"terranix": { "terranix": {
"inputs": { "inputs": {
"flake-parts": "flake-parts_3", "flake-parts": "flake-parts_3",
"nixpkgs": [ "nixpkgs": [
"nixpkgs" "nixpkgs"
], ],
"systems": "systems_7" "systems": "systems_6"
}, },
"locked": { "locked": {
"lastModified": 1762161791, "lastModified": 1757278723,
"narHash": "sha256-J1L1yP29NVBJO04LA/JGM6kwhnjeNhEsX0tLFnuN3FI=", "narHash": "sha256-hTMi6oGU+6VRnW9SZZ+muFcbfMEf2ajjOp7Z2KM5MMY=",
"owner": "terranix", "owner": "terranix",
"repo": "terranix", "repo": "terranix",
"rev": "a79a47b4617dfb92184e2e5b8f5aa6fc06c659c8", "rev": "924573fa6587ac57b0d15037fbd2d3f0fcdf17fb",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1213,27 +1089,6 @@
"type": "github" "type": "github"
} }
}, },
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nix-ai-tools",
"nixpkgs"
]
},
"locked": {
"lastModified": 1762938485,
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"utils": { "utils": {
"inputs": { "inputs": {
"systems": "systems_2" "systems": "systems_2"
@ -1252,25 +1107,6 @@
"type": "github" "type": "github"
} }
}, },
"vicinae": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_10"
},
"locked": {
"lastModified": 1762709887,
"narHash": "sha256-8BoGGsWfkS/2ODBSCYd5HJNFGuLY8fFl27rXmWClXQw=",
"owner": "vicinaehq",
"repo": "vicinae",
"rev": "54722e36137d8273ef0a5db37776fb8302c79238",
"type": "github"
},
"original": {
"owner": "vicinaehq",
"repo": "vicinae",
"type": "github"
}
},
"xwayland-satellite-stable": { "xwayland-satellite-stable": {
"flake": false, "flake": false,
"locked": { "locked": {
@ -1291,11 +1127,11 @@
"xwayland-satellite-unstable": { "xwayland-satellite-unstable": {
"flake": false, "flake": false,
"locked": { "locked": {
"lastModified": 1761622056, "lastModified": 1759707084,
"narHash": "sha256-fBrUszJXmB4MY+wf3QsCnqWHcz7u7fLq0QMAWCltIQg=", "narHash": "sha256-0pkftKs6/LReNvxw7DVTN2AJEheZVgyeK0Aarbagi70=",
"owner": "Supreeeme", "owner": "Supreeeme",
"repo": "xwayland-satellite", "repo": "xwayland-satellite",
"rev": "0728d59ff6463a502e001fb090f6eb92dbc04756", "rev": "a9188e70bd748118b4d56a529871b9de5adb9988",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -1307,14 +1143,14 @@
"zen-browser": { "zen-browser": {
"inputs": { "inputs": {
"home-manager": "home-manager_3", "home-manager": "home-manager_3",
"nixpkgs": "nixpkgs_11" "nixpkgs": "nixpkgs_9"
}, },
"locked": { "locked": {
"lastModified": 1762131860, "lastModified": 1760934351,
"narHash": "sha256-sIPhzkDrfe6ptthZiwoxQyO6rKd9PgJnl+LOyythQkI=", "narHash": "sha256-RehxVjBRC9EiBO36EPZROLHhVVSWFe3KEROhaEapboM=",
"owner": "0xc000022070", "owner": "0xc000022070",
"repo": "zen-browser-flake", "repo": "zen-browser-flake",
"rev": "10e69cb268b1d3dc91135e72f5462b2acfbcc3aa", "rev": "596c3ac14be576b93f5db9252a1b0581e453ec9f",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -49,10 +49,6 @@
url = "github:terranix/terranix"; url = "github:terranix/terranix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-ai-tools.url = "github:numtide/nix-ai-tools";
vicinae.url = "github:vicinaehq/vicinae";
}; };
outputs = outputs =
@ -66,6 +62,7 @@
imports = [ imports = [
./deploy.nix ./deploy.nix
./devShells.nix ./devShells.nix
./diskoConfigurations.nix
./homeConfigurations.nix ./homeConfigurations.nix
./nixosConfigurations.nix ./nixosConfigurations.nix
./nixosModules.nix ./nixosModules.nix

View file

@ -0,0 +1,11 @@
{ ... }:
{
networking.firewall = {
allowedTCPPorts = [
80
443
];
allowedUDPPorts = [ ];
};
}

View file

@ -0,0 +1,35 @@
{
config,
lib,
inputs,
...
}:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts;
in
{
services.forgejo = {
enable = true;
repositoryRoot = "/data/forgejo";
settings = {
session.COOKIE_SECURE = true;
server = {
PROTOCOL = "http+unix";
DOMAIN = "git.baduhai.dev";
ROOT_URL = "https://git.baduhai.dev";
OFFLINE_MODE = true; # disable use of CDNs
SSH_DOMAIN = "baduhai.dev";
};
log.LEVEL = "Warn";
mailer.ENABLED = false;
actions.ENABLED = false;
};
};
services.nginx.virtualHosts = mkNginxVHosts {
acmeHost = "baduhai.dev";
domains."git.baduhai.dev".locations."/".proxyPass =
"http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/";
};
}

View file

@ -10,6 +10,7 @@ in
}; };
services.nginx.virtualHosts = mkNginxVHosts { services.nginx.virtualHosts = mkNginxVHosts {
acmeHost = "baduhai.dev";
domains."jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/"; domains."jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/";
}; };
} }

View file

@ -1,83 +0,0 @@
{
config,
lib,
inputs,
pkgs,
...
}:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts;
kanidmCertDir = "/var/lib/kanidm/certs";
in
{
services.kanidm = {
enableServer = true;
enableClient = true;
package = pkgs.kanidm;
serverSettings = {
domain = "auth.baduhai.dev";
origin = "https://auth.baduhai.dev";
bindaddress = "127.0.0.1:8443";
ldapbindaddress = "127.0.0.1:636";
trust_x_forward_for = true;
# Use self-signed certificates for internal TLS
tls_chain = "${kanidmCertDir}/cert.pem";
tls_key = "${kanidmCertDir}/key.pem";
};
clientSettings = {
uri = "https://auth.baduhai.dev";
};
};
services.nginx.virtualHosts = mkNginxVHosts {
domains."auth.baduhai.dev" = {
locations."/" = {
proxyPass = "https://127.0.0.1:8443";
extraConfig = ''
proxy_ssl_verify off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
'';
};
};
};
networking.firewall.allowedTCPPorts = [ 636 ];
# Generate self-signed certificates for kanidm's internal TLS
systemd.services.kanidm-generate-certs = {
description = "Generate self-signed TLS certificates for Kanidm";
wantedBy = [ "multi-user.target" ];
before = [ "kanidm.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
mkdir -p ${kanidmCertDir}
if [ ! -f ${kanidmCertDir}/key.pem ]; then
${pkgs.openssl}/bin/openssl req -x509 -newkey rsa:4096 \
-keyout ${kanidmCertDir}/key.pem \
-out ${kanidmCertDir}/cert.pem \
-days 3650 -nodes \
-subj "/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
chown -R kanidm:kanidm ${kanidmCertDir}
chmod 600 ${kanidmCertDir}/key.pem
chmod 644 ${kanidmCertDir}/cert.pem
fi
'';
};
# Ensure certificate generation runs before kanidm starts
systemd.services.kanidm = {
after = [ "kanidm-generate-certs.service" ];
wants = [ "kanidm-generate-certs.service" ];
};
}

View file

@ -0,0 +1,30 @@
{
config,
lib,
inputs,
...
}:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts;
in
{
virtualisation.oci-containers.containers."librespeed" = {
image = "lscr.io/linuxserver/librespeed:latest";
environment = {
TZ = "America/Bahia";
};
ports = [ "127.0.0.1:58080:80" ];
extraOptions = [
"--pull=newer"
"--label=io.containers.autoupdate=registry"
];
};
services.nginx.virtualHosts = mkNginxVHosts {
acmeHost = "baduhai.dev";
domains."speedtest.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:58080/";
};
}

View file

@ -24,13 +24,7 @@ in
database.createLocally = true; database.createLocally = true;
maxUploadSize = "16G"; maxUploadSize = "16G";
extraApps = { extraApps = {
inherit (config.services.nextcloud.package.packages.apps) inherit (config.services.nextcloud.package.packages.apps) calendar contacts notes;
calendar
contacts
notes
tasks
user_oidc
;
}; };
extraAppsEnable = true; extraAppsEnable = true;
caching = { caching = {
@ -41,7 +35,6 @@ in
trusted_proxies = [ "127.0.0.1" ]; trusted_proxies = [ "127.0.0.1" ];
default_phone_region = "BR"; default_phone_region = "BR";
maintenance_window_start = "4"; maintenance_window_start = "4";
allow_local_remote_servers = true;
enabledPreviewProviders = [ enabledPreviewProviders = [
"OC\\Preview\\BMP" "OC\\Preview\\BMP"
"OC\\Preview\\EMF" "OC\\Preview\\EMF"
@ -78,6 +71,7 @@ in
}; };
nginx.virtualHosts = mkNginxVHosts { nginx.virtualHosts = mkNginxVHosts {
acmeHost = "baduhai.dev";
domains."cloud.baduhai.dev" = { }; domains."cloud.baduhai.dev" = { };
}; };
}; };

View file

@ -7,15 +7,7 @@
let let
utils = import ../../utils.nix { inherit inputs lib; }; utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts services; inherit (utils) mkNginxVHosts;
# Get all unique domains from shared services that have LAN IPs (served by this host)
localDomains = lib.unique (map (s: s.domain) (lib.filter (s: s.host == "alexandria") services));
# Generate ACME cert configs for all local domains
acmeCerts = lib.genAttrs localDomains (domain: {
group = "nginx";
});
in in
{ {
@ -27,7 +19,9 @@ in
dnsProvider = "cloudflare"; dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.cloudflare.path; credentialsFile = config.age.secrets.cloudflare.path;
}; };
certs = acmeCerts; certs."baduhai.dev" = {
extraDomainNames = [ "*.baduhai.dev" ];
};
}; };
services.nginx = { services.nginx = {
@ -36,21 +30,14 @@ in
recommendedOptimisation = true; recommendedOptimisation = true;
recommendedProxySettings = true; recommendedProxySettings = true;
recommendedTlsSettings = true; recommendedTlsSettings = true;
virtualHosts = { virtualHosts = mkNginxVHosts {
"_" = { acmeHost = "baduhai.dev";
default = true; domains."_".locations."/".return = "444";
locations."/".return = "444";
};
}; };
}; };
users.users.nginx.extraGroups = [ "acme" ]; users.users.nginx.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [
80
443
];
age.secrets.cloudflare = { age.secrets.cloudflare = {
file = ../../secrets/cloudflare.age; file = ../../secrets/cloudflare.age;
owner = "nginx"; owner = "nginx";

View file

@ -1,58 +0,0 @@
{ inputs, lib, ... }:
let
utils = import ../../utils.nix { inherit inputs lib; };
in
{
services.unbound = {
enable = true;
enableRootTrustAnchor = true;
settings = {
server = {
interface = [
"0.0.0.0"
"::"
];
access-control = [
"127.0.0.0/8 allow"
"192.168.0.0/16 allow"
"::1/128 allow"
];
num-threads = 2;
msg-cache-size = "50m";
rrset-cache-size = "100m";
cache-min-ttl = 300;
cache-max-ttl = 86400;
prefetch = true;
prefetch-key = true;
hide-identity = true;
hide-version = true;
so-rcvbuf = "1m";
so-sndbuf = "1m";
# LAN-only DNS records
local-zone = ''"baduhai.dev." transparent'';
local-data = map (e: ''"${e.domain}. IN A ${e.lanIP}"'')
(lib.filter (e: e ? lanIP) utils.services);
};
forward-zone = [
{
name = ".";
forward-addr = [
"1.1.1.1@853#cloudflare-dns.com"
"1.0.0.1@853#cloudflare-dns.com"
];
forward-tls-upstream = true;
}
];
};
};
networking.firewall = {
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [ 53 ];
};
}

View file

@ -20,6 +20,7 @@ in
}; };
services.nginx.virtualHosts = mkNginxVHosts { services.nginx.virtualHosts = mkNginxVHosts {
acmeHost = "baduhai.dev";
domains."pass.baduhai.dev".locations."/".proxyPass = domains."pass.baduhai.dev".locations."/".proxyPass =
"http://${config.services.vaultwarden.config.ROCKET_ADDRESS}:${toString config.services.vaultwarden.config.ROCKET_PORT}/"; "http://${config.services.vaultwarden.config.ROCKET_ADDRESS}:${toString config.services.vaultwarden.config.ROCKET_PORT}/";
}; };

View file

@ -2,12 +2,15 @@
config, config,
lib, lib,
modulesPath, modulesPath,
inputs, self,
... ...
}: }:
{ {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ]; imports = [
(modulesPath + "/installer/scan/not-detected.nix")
self.diskoConfigurations.io
];
boot = { boot = {
initrd = { initrd = {

View file

@ -49,7 +49,6 @@
}; };
}; };
upower.enable = true; upower.enable = true;
power-profiles-daemon.enable = true;
}; };
# TODO: remove once gmodena/nix-flatpak/issues/45 fixed # TODO: remove once gmodena/nix-flatpak/issues/45 fixed

View file

@ -1,10 +0,0 @@
{ inputs, pkgs, ... }:
{
environment.systemPackages = with inputs.nix-ai-tools.packages.${pkgs.system}; [
claude-desktop
claude-code
claudebox
opencode
];
}

View file

@ -4,8 +4,10 @@
services.openssh = { services.openssh = {
enable = true; enable = true;
settings.PermitRootLogin = "no"; settings.PermitRootLogin = "no";
extraConfig = ''
PrintLastLog no
'';
}; };
programs.fish.interactiveShellInit = ''
if set -q SSH_CONNECTION
neofetch
end
'';
} }

View file

@ -25,16 +25,6 @@
programs = { programs = {
command-not-found.enable = false; command-not-found.enable = false;
fish = { fish.enable = true;
enable = true;
interactiveShellInit = ''
set fish_greeting
if set -q SSH_CONNECTION
export TERM=xterm-256color
clear
fastfetch
end
'';
};
}; };
} }

View file

@ -10,9 +10,8 @@
"wheel" "wheel"
]; ];
openssh.authorizedKeys.keys = [ openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
]; ];
hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0"; hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0";
}; };

View file

@ -20,6 +20,7 @@
systemPackages = with pkgs; [ systemPackages = with pkgs; [
### Web ### ### Web ###
bitwarden-desktop bitwarden-desktop
brave
fragments fragments
nextcloud-client nextcloud-client
tor-browser tor-browser
@ -34,7 +35,6 @@
libreoffice libreoffice
onlyoffice-desktopeditors onlyoffice-desktopeditors
papers papers
presenterm
rnote rnote
### Graphics & Design ### ### Graphics & Design ###
gimp gimp

View file

@ -3,6 +3,7 @@
{ {
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
bat bat
claude-code
lazygit lazygit
fd fd
fzf fzf

View file

@ -10,7 +10,7 @@
enable = true; enable = true;
rootDevice = rootDevice =
if config.networking.hostName == "trantor" then if config.networking.hostName == "trantor" then
"/dev/disk/by-id/scsi-360b207ed25d84372a95d1ecf842f8e20-part2" "/dev/disk/by-id/scsi-36067d367fe184830a89bbe708c7b1066"
else else
"/dev/mapper/cryptroot"; "/dev/mapper/cryptroot";
rootSubvolume = "@root"; rootSubvolume = "@root";

View file

@ -6,6 +6,7 @@
heroic heroic
mangohud mangohud
prismlauncher prismlauncher
protonup
steam-run steam-run
]; ];

View file

@ -1,6 +1,3 @@
{ {
boot = { boot.initrd.systemd.enable = true;
initrd.systemd.enable = true;
loader.efi.efiSysMountPoint = "/boot/efi";
};
} }

View file

@ -1,23 +0,0 @@
{ config, pkgs, ... }:
{
services.fail2ban = {
enable = true;
maxretry = 5;
ignoreIP = [
"127.0.0.0/8"
"::1"
"10.0.0.0/8"
"172.16.0.0/12"
"192.168.0.0/16"
"100.64.0.0/10"
];
bantime = "1h";
bantime-increment = {
enable = true;
multipliers = "1 2 4 8 16 32 64";
maxtime = "10000h";
overalljails = true;
};
};
}

View file

@ -1,72 +0,0 @@
{
config,
lib,
inputs,
...
}:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts;
in
{
services = {
forgejo = {
enable = true;
settings = {
session.COOKIE_SECURE = true;
server = {
PROTOCOL = "http+unix";
DOMAIN = "git.baduhai.dev";
ROOT_URL = "https://git.baduhai.dev";
OFFLINE_MODE = true; # disable use of CDNs
SSH_DOMAIN = "git.baduhai.dev";
};
log.LEVEL = "Warn";
mailer.ENABLED = false;
actions.ENABLED = false;
service.DISABLE_REGISTRATION = true;
oauth2_client = {
ENABLE_AUTO_REGISTRATION = true;
UPDATE_AVATAR = true;
ACCOUNT_LINKING = "login";
USERNAME = "preferred_username";
};
};
};
nginx.virtualHosts = mkNginxVHosts {
domains."git.baduhai.dev".locations."/".proxyPass =
"http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/";
};
fail2ban.jails.forgejo = {
settings = {
enabled = true;
filter = "forgejo";
maxretry = 3;
findtime = "10m";
bantime = "1h";
};
};
};
environment = {
etc."fail2ban/filter.d/forgejo.conf".text = ''
[Definition]
failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
ignoreregex =
journalmatch = _SYSTEMD_UNIT=forgejo.service
'';
persistence.main.directories = [
{
directory = config.services.forgejo.stateDir;
inherit (config.services.forgejo) user group;
mode = "0700";
}
];
};
# Disable PrivateMounts to allow LoadCredential to work with bind-mounted directories
systemd.services.forgejo.serviceConfig.PrivateMounts = lib.mkForce false;
}

View file

@ -1,19 +1,30 @@
{ {
lib, lib,
modulesPath, modulesPath,
self,
... ...
}: }:
{ {
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; imports = [
(modulesPath + "/profiles/qemu-guest.nix")
boot.initrd.availableKernelModules = [ self.diskoConfigurations.trantor
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"usbhid"
]; ];
boot = {
kernelModules = [ ];
extraModulePackages = [ ];
initrd = {
availableKernelModules = [
"xhci_pci"
"virtio_pci"
"virtio_scsi"
"usbhid"
];
kernelModules = [ ];
};
};
networking.useDHCP = lib.mkDefault true; networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux";

View file

@ -1,61 +0,0 @@
{
config,
lib,
inputs,
...
}:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkNginxVHosts services;
# Get all unique domains from shared services on trantor (host = "trantor")
localDomains = lib.unique (
map (s: s.domain) (lib.filter (s: s.host == "trantor") services)
);
# Generate ACME cert configs for all local domains
acmeCerts = lib.genAttrs localDomains (domain: {
group = "nginx";
});
in
{
security.acme = {
acceptTerms = true;
defaults = {
email = "baduhai@proton.me";
dnsResolver = "1.1.1.1:53";
dnsProvider = "cloudflare";
credentialsFile = config.age.secrets.cloudflare.path;
};
certs = acmeCerts;
};
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
virtualHosts = {
"_" = {
default = true;
locations."/".return = "444";
};
};
};
users.users.nginx.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [
80
443
];
age.secrets.cloudflare = {
file = ../../secrets/cloudflare.age;
owner = "nginx";
group = "nginx";
};
}

View file

@ -1,23 +0,0 @@
{ ... }:
{
services = {
openssh = {
settings = {
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
};
};
fail2ban.jails.sshd = {
settings = {
enabled = true;
port = "ssh";
filter = "sshd";
logpath = "/var/log/auth.log";
maxretry = 3;
findtime = "10m";
bantime = "1h";
};
};
};
}

View file

@ -1,58 +0,0 @@
{ inputs, lib, ... }:
let
utils = import ../../utils.nix { inherit inputs lib; };
in
{
services.unbound = {
enable = true;
enableRootTrustAnchor = true;
settings = {
server = {
interface = [
"0.0.0.0"
"::"
];
access-control = [
"127.0.0.0/8 allow"
"100.64.0.0/10 allow" # Tailscale CGNAT range
"::1/128 allow"
"fd7a:115c:a1e0::/48 allow" # Tailscale IPv6
];
num-threads = 2;
msg-cache-size = "50m";
rrset-cache-size = "100m";
cache-min-ttl = 300;
cache-max-ttl = 86400;
prefetch = true;
prefetch-key = true;
hide-identity = true;
hide-version = true;
so-rcvbuf = "1m";
so-sndbuf = "1m";
# Tailnet DNS records from shared services
local-zone = ''"baduhai.dev." transparent'';
local-data = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') utils.services;
};
forward-zone = [
{
name = ".";
forward-addr = [
"1.1.1.1@853#cloudflare-dns.com"
"1.0.0.1@853#cloudflare-dns.com"
];
forward-tls-upstream = true;
}
];
};
};
networking.firewall = {
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [ 53 ];
};
}

View file

@ -10,7 +10,6 @@ in
hostname = "rotterdam"; hostname = "rotterdam";
tags = [ tags = [
"desktop" "desktop"
"ai"
"bluetooth" "bluetooth"
"dev" "dev"
"ephemeral" "ephemeral"
@ -26,7 +25,6 @@ in
hostname = "io"; hostname = "io";
tags = [ tags = [
"desktop" "desktop"
"ai"
"bluetooth" "bluetooth"
"dev" "dev"
"ephemeral" "ephemeral"
@ -40,6 +38,7 @@ in
tags = [ tags = [
# "server" TODO: uncomment when 25.11 is out. # "server" TODO: uncomment when 25.11 is out.
"fwupd" "fwupd"
"podman"
]; ];
}; };

186
readme.md
View file

@ -1,87 +1,123 @@
# Nix Configuration # NixOS Configuration
My personal Nix configuration for multiple NixOS hosts, home-manager users, miscellaneous resources... too many things to list. If I could put my life in a flake I would. A declarative, modular NixOS/Home Manager flake configuration managing multiple systems with a tag-based architecture for maximum code reuse and flexibility.
## Hosts ## Hosts
### Desktop Systems | Host | Type | System | Version | Description |
- **rotterdam** - Main desktop workstation (x86_64) |------|------|--------|---------|-------------|
- Features: Desktop, AI tools, Bluetooth, Dev environment, Gaming, Virtualization (libvirtd), Podman | **rotterdam** | Desktop | x86_64-linux | NixOS Unstable | Primary workstation with gaming, development |
- Storage: Ephemeral root with LUKS encryption | **io** | Laptop | x86_64-linux | NixOS Unstable | Mobile workstation |
| **alexandria** | Server/NAS | x86_64-linux | NixOS 25.05 | Personal server running Nextcloud, Forgejo, Jellyfin, Vaultwarden |
| **trantor** | VPS | aarch64-linux | NixOS 25.05 | Oracle Cloud instance |
- **io** - Laptop workstation (x86_64) ## Key Features
- Features: Desktop, AI tools, Bluetooth, Dev environment, Podman
- Storage: Ephemeral root with LUKS encryption
### Servers ### Architecture
- **alexandria** - Home server (x86_64) - **Tag-based module system** - Compose configurations using tags instead of traditional inheritance
- Hosts: Nextcloud, Vaultwarden, Jellyfin, Kanidm - **Flake-based** - Fully reproducible builds with locked dependencies
- **Multi-platform** - Supports both x86_64 and aarch64 architectures
- **Deployment automation** - Remote deployment via deploy-rs
- **trantor** - Cloud server (aarch64) ### Desktop Experience
- Hosts: Forgejo - **Niri compositor** - Custom fork with auto-centering window columns
- Cloud provider: Oracle Cloud Infrastructure - **Unified theming** - Stylix-based theming
- Storage: Ephemeral root with btrfs - **Wayland-native** - Full Wayland support
- **Ephemeral root** - Impermanent filesystem using BTRFS for atomic rollback capability
## Home Manager Configurations ### Self-Hosted Services
- **Nextcloud** - Cloud storage with calendar, contacts, and notes
- **user@rotterdam** - Full desktop setup with gaming, OBS, and complete development environment - **Forgejo** - Self-hosted Git server
- **user@io** - Lightweight desktop setup - **Jellyfin** - Media streaming
- **Vaultwarden** - Password manager backend
Both configurations include: - **LibreSpeed** - Network speed testing
- btop, direnv, helix, starship, tmux - All services behind Nginx and Tailscale with automatic SSL via Let's Encrypt
- Stylix theme management
- Fish shell with custom configurations
## Terranix Configurations
Infrastructure as code using Terranix (NixOS + Terraform/OpenTofu):
- **oci-trantor** - Oracle Cloud Infrastructure provisioning for Trantor server
- **cloudflare-baduhaidev** - DNS and CDN configuration for baduhai.dev domain
- **tailscale-tailnet** - Tailscale network ACL and device management
## Services
All services are accessible via custom domains under baduhai.dev:
- **Kanidm** (auth.baduhai.dev) - Identity and access management
- **Vaultwarden** (pass.baduhai.dev) - Password manager
- **Forgejo** (git.baduhai.dev) - Git forge (publicly accessible)
- **Nextcloud** (cloud.baduhai.dev) - File sync and collaboration
- **Jellyfin** (jellyfin.baduhai.dev) - Media server
Services are accessible via:
- LAN for alexandria-hosted services
- Tailscale VPN for all services
- Public internet for Forgejo only
## Notable Features
### Ephemeral Root
Rotterdam, io, and trantor use an ephemeral root filesystem that resets on every boot:
- Root filesystem is automatically rolled back using btrfs snapshots
- Old snapshots retained for 30 days
- Persistent data stored in dedicated subvolumes
- Implements truly stateless systems
### Custom DNS Architecture
- Unbound DNS servers on both alexandria and trantor
- Service routing based on visibility flags (public/LAN/Tailscale)
- Split-horizon DNS for optimal access paths
### Security ### Security
- LUKS full-disk encryption on desktop systems - **Agenix** - Encrypted secrets management
- Fail2ban on public-facing servers - **Tailscale** - Zero-config VPN mesh network
- agenix for secrets management - **Firewall** - Configured on all hosts
- Tailscale for secure remote access - SSH key-based authentication
### Desktop Environment ## Repository Structure
- Custom Niri window manager (Wayland compositor)
- Using forked version with auto-centering feature
- Stylix for consistent theming
### Development Setup ```
- Nix flakes for reproducible builds .
- deploy-rs for automated deployments ├── flake.nix # Main flake definition
- Podman for containerization ├── utils.nix # Tag-based module system utilities
- Complete AI tooling integration ├── nixosConfigurations.nix # Host definitions with tags
├── homeConfigurations.nix # User configurations
├── deploy.nix # Remote deployment configuration
├── hosts/
│ ├── alexandria/ # Server-specific config
│ ├── io/ # Laptop-specific config
│ ├── rotterdam/ # Desktop-specific config
│ ├── trantor/ # VPS-specific config
│ └── modules/
│ ├── common/ # Shared base configuration
│ ├── desktop/ # Desktop environment setup
│ ├── server/ # Server-specific modules
│ └── [tag].nix # Optional feature modules
├── users/
│ └── modules/ # Home Manager configurations
│ └── [tag].nix # Optional feature modules
├── packages/ # Custom package definitions
└── secrets/ # Encrypted secrets (agenix)
```
## Tag System
Configurations are composed using tags that map to modules:
**Common Tags** (all hosts):
- `common` - Base system configuration (automatically applied)
**General Tags**:
- `desktop` - *Mostly* full desktop environment with Niri WM
- `dev` - Development tools and environments
- `gaming` - Steam, Heroic, gamemode, controller support
- `ephemeral` - Impermanent root filesystem
- `networkmanager` - WiFi and network management
- `libvirtd` - KVM/QEMU virtualization
- `podman` - Container runtime
- `bluetooth` - Bluetooth support
- `fwupd` - Firmware update daemon
**Server Tags**:
- `server` - Server-specific configuration
## Usage
### Rebuilding a Configuration
```bash
# Local rebuild
sudo nixos-rebuild switch --flake .#hostname
# Remote deployment
deploy .#hostname
```
### Updating Dependencies
```bash
nix flake update
```
### Adding a New Host
1. Create host directory in `hosts/`
2. Define configuration in `nixosConfigurations.nix` with appropriate tags
3. Add deployment profile in `deploy.nix` if needed
## Dependencies
- [nixpkgs](https://github.com/NixOS/nixpkgs) - Stable (25.05) and unstable channels
- [home-manager](https://github.com/nix-community/home-manager) - User configuration
- [agenix](https://github.com/ryantm/agenix) - Secrets management
- [disko](https://github.com/nix-community/disko) - Declarative disk partitioning
- [stylix](https://github.com/danth/stylix) - System-wide theming
- [niri-flake](https://github.com/sodiboo/niri-flake) - Wayland compositor (custom fork)
- [impermanence](https://github.com/nix-community/impermanence) - Ephemeral filesystem support
- [deploy-rs](https://github.com/serokell/deploy-rs) - Remote deployment
- [nix-flatpak](https://github.com/gmodena/nix-flatpak) - Declarative Flatpak management

View file

@ -1,11 +1,9 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 Kfdnog IHXv4c5we36dCUsB1v8uEF23tIRlDQ/8WR1hX4GQ+Uc -> ssh-ed25519 Kfdnog gEZvRtLBhGslmS97VaRqoucgExvOopsHAAne4lCmEEY
Cwccw64BYBdSZUdkSqKESIU7E17cLNtiAZZ3Y1xV87A NkIeFYuQFntDOBqd3k0/OVYMcM7h73uO0jPXaHzEcZc
-> ssh-ed25519 8YSAiw Ce3vdMG111ubjcFgd3+q2Qw2+7dsoUz7SiudtuLDr0Y -> ssh-ed25519 8YSAiw bVV4jIDbBKxsr6mQ4Tv0rP6ylrAEOJWkqjpyvXjnQRU
JUodwFsKfOTZXxFyRrEk/4gxJ4goPkwvYeThi893M0U 6kUe5Syw7sd+aF2QEgr6Yj+fOPL5zSJN1PJvY9Kdhlg
-> ssh-ed25519 J6tVTA bExFuITTGXkTvhW25nushN7zT/PJGDoezsqu7fLKemI -> ssh-ed25519 J6tVTA 4JMlJmhHAYUgjiWwB1Q278TSjJypwecALmfnosxan0s
4a90v0F4wgcZeqWBQ/EpqOZ9OCgT7qruwVvlGZeFmN8 WIubcIFrjMV0GpyU1ZGc48YwrqOtSmJxweonw1KnR+U
-> ssh-ed25519 Qt3Q+A j1oo46pNh1+yPEtxpgj+QPQPf5m82jL0DHGMacY8UFA --- 78A7re4LLB/0n5AXLRlVqiMNFMAQ2ZvjjK21YGRveRE
vy52Hl1WLTdKNA8+4p7A48Sg9+QkMXbECf/uxVMCLYk ú_4pkVCKmÈÊ#~kIô<49>8Em3ôkºp|Ó0^÷tSk<53> És¬/øÃõÎ…?= lÔ,„Ž<E2809A>ì²7âã~Í„¶cû{ãÈž¨AªÝ­ø‹Œ>ZãÈl¬§—GTJs²GYŠ´ —/Ëö/×B4ÃeŠÑ'óðIIÐãcÿ ,"‡
--- 429vzgFnmFbEqDMwdvC0/EYDJlKU64YEGgE0AqPqlBs
čď¬<E280BA>÷€b‰/!8Očô3Df®/ľŹ&kNQhuůr“t¤%&]ł˛ÎŐŇÖucÚjŮHĆ]Ż_łž¨ë5@D$<1C>>éN8Ϧ >Ť9:®CvĐѦ69W'X·]X^çŰĆ»$Ť§}|cš÷ă/ž ߸={ľuÉłs

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -7,7 +7,7 @@ let
alexandria = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK95QueW+jp1ZmF299Xr3XkgHJ6dL7aZVsfWxqbOKVKA root@alexandria"; alexandria = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK95QueW+jp1ZmF299Xr3XkgHJ6dL7aZVsfWxqbOKVKA root@alexandria";
trantor = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIh/2u5pr/iPVeavlsor5hbTtsgUfP1JpzZVco2YQAo3 root@trantor"; trantor = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINkGuGLZPnYJbCGY4BhJ9uTupp6ruuR1NZ7FEYEaLPA7 root@alexandria";
in in
{ {
@ -15,7 +15,6 @@ in
io-user io-user
rotterdam-user rotterdam-user
alexandria alexandria
trantor
]; ];
"nextcloud-adminpass.age".publicKeys = [ "nextcloud-adminpass.age".publicKeys = [
io-user io-user
@ -27,9 +26,4 @@ in
rotterdam-user rotterdam-user
alexandria alexandria
]; ];
"forgejo-root-password.age".publicKeys = [
io-user
rotterdam-user
trantor
];
} }

View file

@ -1,48 +0,0 @@
# Shared service definitions for cross-host configuration
# Used by:
# - alexandria: DNS server (LAN) + service hosting (vaultwarden, nextcloud, jellyfin, kanidm)
# - trantor: DNS server (Tailnet) + service hosting (forgejo)
{
services = [
{
name = "kanidm";
domain = "auth.baduhai.dev";
host = "alexandria";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
port = 8443;
}
{
name = "vaultwarden";
domain = "pass.baduhai.dev";
host = "alexandria";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
port = 8222;
}
{
name = "forgejo";
domain = "git.baduhai.dev";
host = "trantor";
public = true;
tailscaleIP = "100.108.5.90";
port = 3000;
}
{
name = "nextcloud";
domain = "cloud.baduhai.dev";
host = "alexandria";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
port = 443;
}
{
name = "jellyfin";
domain = "jellyfin.baduhai.dev";
host = "alexandria";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
port = 8096;
}
];
}

View file

@ -1,86 +0,0 @@
# Required environment variables:
# CLOUDFLARE_API_TOKEN - API token with "Edit zone DNS" permissions
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, lib, ... }:
let
inherit (import ../../shared/services.nix) services;
# Helper to extract subdomain from full domain (e.g., "git.baduhai.dev" -> "git")
getSubdomain = domain: lib.head (lib.splitString "." domain);
# Generate DNS records for services
# Public services point to trantor's public IP
# Private services point to their tailscale IP
mkServiceRecords = lib.listToAttrs (
lib.imap0 (
i: svc:
let
subdomain = getSubdomain svc.domain;
targetIP =
if svc.public or false then
config.data.terraform_remote_state.trantor "outputs.instance_public_ip"
else
svc.tailscaleIP;
in
{
name = "service_${toString i}";
value = {
zone_id = config.variable.zone_id.default;
name = subdomain;
type = "A";
content = targetIP;
proxied = false;
ttl = 3600;
};
}
) services
);
in
{
terraform.required_providers.cloudflare = {
source = "cloudflare/cloudflare";
version = "~> 5.0";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "cloudflare/baduhai.dev.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
zone_id = {
default = "c63a8332fdddc4a8e5612ddc54557044";
type = "string";
};
};
data = {
terraform_remote_state.trantor = {
backend = "s3";
config = {
bucket = "terraform-state";
key = "oci/trantor.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
};
};
resource.cloudflare_dns_record = mkServiceRecords;
}

View file

@ -1,13 +1,3 @@
# Required environment variables:
# instead of OCI variables, ~/.oci/config may also be used
# OCI_TENANCY_OCID - Oracle tenancy OCID (or use TF_VAR_* to override variables)
# OCI_USER_OCID - Oracle user OCID
# OCI_FINGERPRINT - API key fingerprint
# OCI_PRIVATE_KEY_PATH - Path to OCI API private key
# AWS variables are required
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, ... }: { config, ... }:
{ {
@ -53,7 +43,6 @@
ssh_public_keys = { ssh_public_keys = {
default = [ default = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
]; ];
@ -240,7 +229,6 @@
threshold = 5; threshold = 5;
threshold_type = "PERCENTAGE"; threshold_type = "PERCENTAGE";
display_name = "daily-spend-alert"; display_name = "daily-spend-alert";
recipients = "baduhai@proton.me";
description = "Alert when daily spending exceeds $0.05"; description = "Alert when daily spending exceeds $0.05";
message = "Daily spending has exceeded $0.05 in the trantor compartment"; message = "Daily spending has exceeded $0.05 in the trantor compartment";
}; };

View file

@ -1,43 +0,0 @@
# Required environment variables:
# TAILSCALE_API_KEY - Tailscale API key with appropriate permissions
# TAILSCALE_TAILNET - Your tailnet name (e.g., "user@example.com" or "example.org.github")
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, ... }:
{
terraform.required_providers.tailscale = {
source = "tailscale/tailscale";
version = "~> 0.17";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "tailscale/tailnet.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
trantor_tailscale_ip = {
default = "100.108.5.90";
type = "string";
};
};
resource = {
tailscale_dns_nameservers.global = {
nameservers = [
config.variable.trantor_tailscale_ip.default
"1.1.1.1"
"1.0.0.1"
];
};
};
}

View file

@ -14,14 +14,6 @@
modules = [ ./terranix/oci/trantor.nix ]; modules = [ ./terranix/oci/trantor.nix ];
terraformWrapper.package = pkgs.opentofu; terraformWrapper.package = pkgs.opentofu;
}; };
cloudflare-baduhaidev = {
modules = [ ./terranix/cloudflare/baduhai.dev.nix ];
terraformWrapper.package = pkgs.opentofu;
};
tailscale-tailnet = {
modules = [ ./terranix/tailscale/tailnet.nix ];
terraformWrapper.package = pkgs.opentofu;
};
}; };
}; };
} }

View file

@ -3,10 +3,7 @@
{ {
programs.fish = { programs.fish = {
enable = true; enable = true;
interactiveShellInit = '' interactiveShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source";
set fish_greeting
${lib.getExe pkgs.nix-your-shell} fish | source
'';
loginShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source"; loginShellInit = "${lib.getExe pkgs.nix-your-shell} fish | source";
plugins = [ plugins = [
{ {

View file

@ -1,21 +1,15 @@
{ {
config,
inputs, inputs,
pkgs, pkgs,
... ...
}: }:
{ {
imports = [ inputs.vicinae.homeManagerModules.default ];
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
home.packages = with pkgs; [ xwayland-satellite ]; home.packages = with pkgs; [ xwayland-satellite ];
services.vicinae = {
enable = true;
autoStart = true;
};
programs = { programs = {
ghostty = { ghostty = {
@ -28,7 +22,7 @@
url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl"; url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl";
sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41"; sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41";
}}"; }}";
bell-features = ""; bell-features = "border";
gtk-titlebar-style = "tabs"; gtk-titlebar-style = "tabs";
keybind = [ "shift+enter=text:\\x1b\\r" ]; keybind = [ "shift+enter=text:\\x1b\\r" ];
}; };
@ -47,28 +41,33 @@
enable = true; enable = true;
defaultApplications = { defaultApplications = {
"text/html" = [ "text/html" = [
"re.sonny.Junction.desktop" "com.github.timecraft.junction.desktop"
"zen-browser.desktop" "zen-browser.desktop"
"brave-browser.desktop"
"torbrowser.desktop" "torbrowser.desktop"
]; ];
"x-scheme-handler/http" = [ "x-scheme-handler/http" = [
"re.sonny.Junction.desktop" "com.github.timecraft.junction.desktop"
"zen-browser.desktop" "zen-browser.desktop"
"brave-browser.desktop"
"torbrowser.desktop" "torbrowser.desktop"
]; ];
"x-scheme-handler/https" = [ "x-scheme-handler/https" = [
"re.sonny.Junction.desktop" "com.github.timecraft.junction.desktop"
"zen-browser.desktop" "zen-browser.desktop"
"brave-browser.desktop"
"torbrowser.desktop" "torbrowser.desktop"
]; ];
"x-scheme-handler/about" = [ "x-scheme-handler/about" = [
"re.sonny.Junction.desktop" "com.github.timecraft.junction.desktop"
"zen-browser.desktop" "zen-browser.desktop"
"brave-browser.desktop"
"torbrowser.desktop" "torbrowser.desktop"
]; ];
"x-scheme-handler/unknown" = [ "x-scheme-handler/unknown" = [
"re.sonny.Junction.desktop" "com.github.timecraft.junction.desktop"
"zen-browser.desktop" "zen-browser.desktop"
"brave-browser.desktop"
"torbrowser.desktop" "torbrowser.desktop"
]; ];
"image/jpeg" = "org.gnome.Loupe.desktop"; "image/jpeg" = "org.gnome.Loupe.desktop";

View file

@ -8,35 +8,25 @@
let let
isRotterdam = hostname == "rotterdam"; isRotterdam = hostname == "rotterdam";
noctalia = "${lib.getExe inputs.noctalia.packages.${pkgs.system}.default}";
in in
{ {
imports = [ inputs.noctalia.homeModules.default ]; imports = [ inputs.noctalia.homeModules.default ];
services.kanshi = {
enable = true;
settings = [
{
profile.name = "default";
profile.outputs = [
{
criteria = "*";
scale = 1.0;
}
];
}
];
};
home = { home = {
packages = with pkgs; [ packages = with pkgs; [ xwayland-satellite ];
xwayland-satellite
inputs.noctalia.packages.${pkgs.system}.default
];
sessionVariables.QT_QPA_PLATFORMTHEME = "gtk3"; sessionVariables.QT_QPA_PLATFORMTHEME = "gtk3";
}; };
xdg.configFile."niri/config.kdl".text = '' xdg.configFile."niri/config.kdl".text = ''
output "eDP-1" {
scale 1.0
}
output "DP-3" {
scale 1.0
}
input { input {
keyboard { keyboard {
xkb { xkb {
@ -93,18 +83,23 @@ in
inactive-color "#505050" inactive-color "#505050"
urgent-color "#9b0000" urgent-color "#9b0000"
} }
tab-indicator { tab-indicator {
width 4 width 4
gap 4 gap 4
place-within-column place-within-column
} }
${lib.optionalString isRotterdam ''
struts {
left 8
right 8
}''}
} }
overview { overview {
zoom 0.65 zoom 0.65
} }
spawn-at-startup "noctalia-shell" "-d" spawn-at-startup "${noctalia}"
layer-rule { layer-rule {
match namespace="^wallpaper$" match namespace="^wallpaper$"
place-within-backdrop true place-within-backdrop true
@ -140,18 +135,18 @@ in
} }
binds { binds {
Alt+Space repeat=false { spawn "vicinae" "toggle"; } Alt+Space { spawn "${noctalia}" "ipc" "call" "launcher" "toggle"; }
XF86AudioRaiseVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "increase"; } XF86AudioRaiseVolume allow-when-locked=true { spawn "${noctalia}" "ipc" "call" "volume" "increase"; }
XF86AudioLowerVolume allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "decrease"; } XF86AudioLowerVolume allow-when-locked=true { spawn "${noctalia}" "ipc" "call" "volume" "decrease"; }
XF86AudioMute allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "volume" "muteOutput"; } XF86AudioMute allow-when-locked=true { spawn "${noctalia}" "ipc" "call" "volume" "muteOutput"; }
XF86MonBrightnessUp allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "increase"; } XF86MonBrightnessUp allow-when-locked=true { spawn "${noctalia}" "ipc" "call" "brightness" "increase"; }
XF86MonBrightnessDown allow-when-locked=true { spawn "noctalia-shell" "ipc" "call" "brightness" "decrease"; } XF86MonBrightnessDown allow-when-locked=true { spawn "${noctalia}" "ipc" "call" "brightness" "decrease"; }
XF86AudioPlay allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "play-pause"; } XF86AudioPlay allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "play-pause"; }
XF86AudioStop allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "stop"; } XF86AudioStop allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "stop"; }
XF86AudioPrev allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "previous"; } XF86AudioPrev allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "previous"; }
XF86AudioNext allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "next"; } XF86AudioNext allow-when-locked=true { spawn "${lib.getExe pkgs.playerctl}" "next"; }
Mod+V repeat=false { spawn "vicinae" "vicinae://extensions/vicinae/clipboard/history"; } Mod+V { spawn "${noctalia}" "ipc" "call" "launcher" "clipboard"; }
Mod+Shift+L repeat=false { spawn "noctalia-shell" "ipc" "call" "lockScreen" "lock"; } Mod+Shift+L { spawn "${noctalia}" "ipc" "call" "lockScreen" "toggle"; }
Mod+Return { spawn "ghostty"; } Mod+Return { spawn "ghostty"; }
Ctrl+Alt+Shift+A allow-when-locked=true { spawn "toggleaudiosink"; } Ctrl+Alt+Shift+A allow-when-locked=true { spawn "toggleaudiosink"; }
Mod+W repeat=false { toggle-overview; } Mod+W repeat=false { toggle-overview; }
@ -160,13 +155,17 @@ in
Mod+Shift+Q { close-window; } Mod+Shift+Q { close-window; }
Alt+F4 { close-window; } Alt+F4 { close-window; }
Mod+Left { focus-column-left; } Mod+Left { focus-column-left; }
Mod+Down { focus-window-or-workspace-down; } Mod+Down { focus-window-down; }
Mod+Up { focus-window-or-workspace-up; } Mod+Up { focus-window-up; }
Mod+Right { focus-column-right; } Mod+Right { focus-column-right; }
Mod+H { focus-column-left; } Mod+H { focus-column-left; }
Mod+L { focus-column-right; } Mod+L { focus-column-right; }
Mod+J { focus-window-or-workspace-down; } Mod+J { focus-window-down; }
Mod+K { focus-window-or-workspace-up; } Mod+K { focus-window-up; }
Ctrl+Alt+J { focus-workspace-down; }
Ctrl+Alt+K { focus-workspace-up; }
Ctrl+Alt+Down { focus-workspace-down; }
Ctrl+Alt+Up { focus-workspace-up; }
Mod+Ctrl+Left { move-column-left; } Mod+Ctrl+Left { move-column-left; }
Mod+Ctrl+Down { move-window-down-or-to-workspace-down; } Mod+Ctrl+Down { move-window-down-or-to-workspace-down; }
Mod+Ctrl+Up { move-window-up-or-to-workspace-up; } Mod+Ctrl+Up { move-window-up-or-to-workspace-up; }
@ -221,8 +220,8 @@ in
Mod+Print { screenshot; } Mod+Print { screenshot; }
Ctrl+Print { screenshot-window; } Ctrl+Print { screenshot-window; }
Mod+Backspace allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; } Mod+Backspace allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
Mod+Alt+E { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } Mod+Alt+E { spawn "${noctalia}" "ipc" "call" "sessionMenu" "toggle"; }
Ctrl+Alt+Delete { spawn "noctalia-shell" "ipc" "call" "sessionMenu" "toggle"; } Ctrl+Alt+Delete { spawn "${noctalia}" "ipc" "call" "sessionMenu" "toggle"; }
Mod+Ctrl+P { power-off-monitors; } Mod+Ctrl+P { power-off-monitors; }
} }
''; '';

View file

@ -46,7 +46,7 @@
name = "FiraCode Nerd Font"; name = "FiraCode Nerd Font";
}; };
emoji = { emoji = {
package = pkgs.noto-fonts-color-emoji; package = pkgs.noto-fonts-emoji;
name = "Noto Color Emoji"; name = "Noto Color Emoji";
}; };
sizes = { sizes = {

View file

@ -8,14 +8,9 @@ let
home-manager home-manager
agenix agenix
; ;
# Import shared service definitions
sharedServices = import ./shared/services.nix;
in in
{ {
# Re-export shared services for use in host configs
inherit (sharedServices) services;
# Tag-based host configuration system # Tag-based host configuration system
mkHost = mkHost =
{ {
@ -183,41 +178,16 @@ in
# Nginx virtual host utilities # Nginx virtual host utilities
mkNginxVHosts = mkNginxVHosts =
{ domains }: {
acmeHost,
domains,
}:
let let
# Extract domain name and apply it as useACMEHost commonVHostConfig = {
mkVHostConfig = domain: config: useACMEHost = acmeHost;
lib.recursiveUpdate { forceSSL = true;
useACMEHost = domain; kTLS = true;
forceSSL = true; };
kTLS = true;
} config;
in in
lib.mapAttrs mkVHostConfig domains; lib.mapAttrs (_: lib.recursiveUpdate commonVHostConfig) domains;
# Split DNS utilities for unbound
# Generates unbound view config from a list of DNS entries
mkSplitDNS =
entries:
let
# Generate local-data entries for all domains
tailscaleData = map (e: ''"${e.domain}. IN A ${e.tailscaleIP}"'') entries;
lanData = map (e: ''"${e.domain}. IN A ${e.lanIP}"'') entries;
in
[
# Single Tailscale view with all domains
{
name = "tailscale";
view-first = true;
local-zone = ''"baduhai.dev." transparent'';
local-data = tailscaleData;
}
# Single LAN view with all domains
{
name = "lan";
view-first = true;
local-zone = ''"baduhai.dev." transparent'';
local-data = lanData;
}
];
} }