All my system configs and packages in one repo

systems: init brioche, add tailscale, add ente

Too lazy to separate them into clean commits.

pluie.me f9b99aef 069d8c0a

verified
+326 -20
+4
flake.nix
··· 93 93 ./systems/fettuccine 94 94 ./systems/pappardelle 95 95 ./systems/focaccia 96 + ./systems/brioche 97 + ./systems/deploy.nix 96 98 ]; 97 99 98 100 flake = { ··· 134 136 nixd 135 137 nixfmt 136 138 deploy-rs 139 + sops 137 140 ]; 141 + env.SOPS_AGE_KEY_CMD = "${./age_from_1password.nu}"; 138 142 }; 139 143 }; 140 144 };
+32
systems/NAMING.md
··· 1 + # Naming systems 2 + 3 + In accordance with fun hacker tradition, all of my machines are given fun and 4 + memorable names with an identifiable pattern. Here's all of them (as of time 5 + of writing anyways): 6 + 7 + - Linux personal computers, named after pastas 8 + - ~~`tagliatelle`~~: My custom-built mATX workstation in China. Decommissioned. 9 + - `fettuccine`: An ASUS ROG Zephyrus M16 2021 (GU603H) who served as my main 10 + laptop from 2021 to early 2025. Dormant. 11 + - **`pappardelle`**: A Lenovo XiaoXin Pro / IdeaPad Pro 5 14-inch 2025 (14IAH10). 12 + Current main laptop (and PC in general really). 13 + 14 + - Mobile phones, named after cheeses 15 + - `ricotta`: A Chinese iPhone 12. Mostly used as a hotspot machine and for 16 + quarantining questionable Chinese apps. 17 + - **`roquefort`**: A European iPhone 15. My main phone. 18 + - As an exception to the pattern, `fromage` was my 2018 Intel MacBook Pro. 19 + It still works, but not very well, for obvious reasons. 20 + 21 + - Servers, named after breads 22 + - **`focaccia`**: A CX22 box from Hetzner that runs everything between 23 + proxies, a Tangled knot, an ATProto PDS, even my Ente instance, and 24 + my main reverse proxy tying them all together. 25 + 26 + - `brioche`: A CX23 box from Hetzner. I don't really know what to do 27 + with it yet. 28 + 29 + - Miscellaneous 30 + - `marmelade`: S3-compatible Hetzner Object Storage containing all my 31 + Ente photos. Yes, I should consider getting some backups. Maybe I'll 32 + name them after another jam/jelly/however you call it.
+32
systems/brioche/configuration.nix
··· 1 + { 2 + ... 3 + }: { 4 + imports = [ 5 + ../common.nix 6 + ./hardware-configuration.nix 7 + ./networking.nix 8 + ]; 9 + 10 + networking = { 11 + hostName = "brioche"; 12 + domain = "pluie.me"; 13 + firewall = { 14 + allowedTCPPorts = [ 15 + 80 16 + 443 17 + ]; 18 + }; 19 + }; 20 + 21 + services.openssh = { 22 + enable = true; 23 + # ports = [ 42069 ]; 24 + settings.PermitRootLogin = "prohibit-password"; 25 + }; 26 + 27 + boot.tmp.cleanOnBoot = true; 28 + zramSwap.enable = true; 29 + users.users.root.openssh.authorizedKeys.keys = [ 30 + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbsavGX9rGRx5R+7ovLn+r7D/w3zkbqCik4bS31moSz" 31 + ]; 32 + }
+11
systems/brioche/default.nix
··· 1 + { 2 + inputs, 3 + lib, 4 + ... 5 + }: 6 + { 7 + flake.nixosConfigurations.brioche = lib.nixosSystem { 8 + modules = [ ./configuration.nix ]; 9 + specialArgs = { inherit inputs; }; 10 + }; 11 + }
+18
systems/brioche/hardware-configuration.nix
··· 1 + { modulesPath, ... }: 2 + { 3 + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; 4 + boot.loader.grub.device = "/dev/sda"; 5 + boot.initrd.availableKernelModules = [ 6 + "ata_piix" 7 + "uhci_hcd" 8 + "xen_blkfront" 9 + "vmw_pvscsi" 10 + ]; 11 + boot.initrd.kernelModules = [ "nvme" ]; 12 + fileSystems."/" = { 13 + device = "/dev/sda1"; 14 + fsType = "ext4"; 15 + }; 16 + 17 + nixpkgs.hostPlatform = "x86_64-linux"; 18 + }
+33
systems/brioche/networking.nix
··· 1 + { lib, ... }: { 2 + # This file was populated at runtime with the networking 3 + # details gathered from the active system. 4 + networking = { 5 + nameservers = [ "8.8.8.8" 6 + ]; 7 + defaultGateway = "172.31.1.1"; 8 + defaultGateway6 = { 9 + address = "fe80::1"; 10 + interface = "eth0"; 11 + }; 12 + dhcpcd.enable = false; 13 + usePredictableInterfaceNames = lib.mkForce false; 14 + interfaces = { 15 + eth0 = { 16 + ipv4.addresses = [ 17 + { address="91.99.202.138"; prefixLength=32; } 18 + ]; 19 + ipv6.addresses = [ 20 + { address="2a01:4f8:c2c:cb4e::1"; prefixLength=64; } 21 + { address="fe80::9000:7ff:fe49:d963"; prefixLength=64; } 22 + ]; 23 + ipv4.routes = [ { address = "172.31.1.1"; prefixLength = 32; } ]; 24 + ipv6.routes = [ { address = "fe80::1"; prefixLength = 128; } ]; 25 + }; 26 + 27 + }; 28 + }; 29 + services.udev.extraRules = '' 30 + ATTR{address}=="92:00:07:49:d9:63", NAME="eth0" 31 + 32 + ''; 33 + }
+38
systems/deploy.nix
··· 1 + { 2 + self, 3 + inputs, 4 + ... 5 + }: 6 + { 7 + flake.deploy.nodes = { 8 + focaccia = { 9 + sshOpts = [ 10 + "-p" 11 + "42069" 12 + ]; 13 + hostname = "focaccia.pluie.me"; 14 + profiles = { 15 + system = { 16 + path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.focaccia; 17 + user = "root"; 18 + sshUser = "root"; 19 + }; 20 + }; 21 + }; 22 + 23 + brioche = { 24 + # sshOpts = [ 25 + # "-p" 26 + # "22" 27 + # ]; 28 + hostname = "brioche.pluie.me"; 29 + profiles = { 30 + system = { 31 + path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.brioche; 32 + user = "root"; 33 + sshUser = "root"; 34 + }; 35 + }; 36 + }; 37 + }; 38 + }
+16 -2
systems/focaccia/configuration.nix
··· 13 13 ./services/hysteria.nix 14 14 ./services/knot.nix 15 15 ./services/pds.nix 16 + ./services/ente.nix 16 17 ]; 17 18 18 19 sops = { ··· 28 29 80 29 30 443 30 31 ]; 32 + allowedUDPPorts = [ 33 + 443 34 + ]; 35 + # Allow Tailscale users to connect to port 22 directly 36 + extraInputRules = '' 37 + iifname "tailscale0" tcp dport 22 accept 38 + ''; 31 39 }; 40 + nftables.enable = true; 32 41 }; 33 42 34 43 users.users.leah = { ··· 47 56 48 57 services.openssh = { 49 58 enable = true; 50 - ports = [ 42069 ]; 59 + ports = [ 60 + 22 61 + 42069 62 + ]; 51 63 settings.PermitRootLogin = "prohibit-password"; 52 64 }; 53 65 ··· 60 72 enable = true; 61 73 email = "srv@acc.pluie.me"; 62 74 }; 63 - } 75 + 76 + services.tailscale.enable = true; 77 + }
-16
systems/focaccia/default.nix
··· 1 1 { 2 - self, 3 2 inputs, 4 3 lib, 5 4 ... ··· 8 7 flake.nixosConfigurations.focaccia = lib.nixosSystem { 9 8 modules = [ ./configuration.nix ]; 10 9 specialArgs = { inherit inputs; }; 11 - }; 12 - 13 - flake.deploy.nodes.focaccia = { 14 - sshOpts = [ 15 - "-p" 16 - "42069" 17 - ]; 18 - hostname = "focaccia.pluie.me"; 19 - profiles = { 20 - system = { 21 - path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.focaccia; 22 - user = "root"; 23 - sshUser = "root"; 24 - }; 25 - }; 26 10 }; 27 11 }
+36
systems/focaccia/secrets/ente.yaml
··· 1 + s3: 2 + b2-eu-cen: 3 + key: ENC[AES256_GCM,data:+u8cUMH4UKmObQHDfXoGk/UY8FM=,iv:FqsD0fmYoUhbHI6Ozqfk19fN6B5Ju20ZeB2SEo4uVxM=,tag:HBsWCaJgCw/TaMn1NOof8w==,type:str] 4 + secret: ENC[AES256_GCM,data:uzwfBiZ2vasW7KWFYLFvunV0CpdDefawxb+3yXUTACHT3xgXkdt4ug==,iv:oAW2L7lmh9xXjxfO3LJ2ePDLBX+MkojlKnQEv+Jsdfc=,tag:FFwqK5WlAypZ6Jpn9StHxA==,type:str] 5 + key: 6 + encryption: ENC[AES256_GCM,data:SOUgVR+SN8r8JFiAYs3rhSrJ6YvLrGuLZPq285BsRKf6QKxTLk7LS7k1zHQ=,iv:2BJWKuS3bgyNiDAH8KvpqFRFhNX19g/I0/g0lXhh1co=,tag:GjbVWE2Q/fGuu9Re6aTf2Q==,type:str] 7 + hash: ENC[AES256_GCM,data:5LF8v1o8ZmChkuIfyhBuo/uTMwLDmezXH5Ajh4wgWWeb5Mk/I8TNKNeosOil7aOvXnbSAJRr43ATDX7hvBQtIJy20Nzjhri01bTQbwBKIGw6fFPug8vhdg==,iv:+OUxhWdIpyGzMYHPyu9FmhyWCnmjRD7DuRhrYMbgjC8=,tag:bSavxsF38tfHjphBp2vjBA==,type:str] 8 + jwt: 9 + secret: ENC[AES256_GCM,data:v59Duv9kJOW74Caeitvp3Lys+6dkkDarraMWmmGTRZwo+cH0RVB/Aijiyzw=,iv:Zm3Q66KFmc+cvvAyxi91dAqhEeWACMp1EUm499+FtXc=,tag:jiiA2P+f/5I/spX5K662yQ==,type:str] 10 + internal: 11 + admins: 12 + - ENC[AES256_GCM,data:sj1ATdVgPti/IAUGM8dYVw==,iv:vP45TCr+c4yPIV3y3mzcRvcPYpWo+2Kg3bmQt7kOCBM=,tag:IPGDydcXzzITknY0OBOvhw==,type:int] 13 + sops: 14 + age: 15 + - recipient: age1lh4sn2s9gxj2s3naqdl4wpmz3uhpd3p8l0jfy6k5hu6cu34uyygsdwadd5 16 + enc: | 17 + -----BEGIN AGE ENCRYPTED FILE----- 18 + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1SGlOU2pPNkRtZ0VlME5V 19 + NVFyZllGT25YSURxUnQ2N3VTdFN5bFYvNnhrCm5xUlZBeHFHWS9FbWw0R1lXMUpm 20 + OVVIOVhvM0pGQVErUHYveVEyMVYzMVEKLS0tIHVCZTRNSTRSTmNhVlVPcXRCam11 21 + dm95SFY4eHpaYkc3R1pURmFCalVrbFkK89/h3FUcVQIrbOr6GiYORtHBjw6TTpHs 22 + uzx5cFaTtS2oweYTkTcuWzJzjG+pzuKBKrw3NCxbOW6EcSIvg6H5MQ== 23 + -----END AGE ENCRYPTED FILE----- 24 + - recipient: age1wtr58sze4sxjjzq9jmsq7ztkvkjakvnfzuqzn025p92htz7zsdesjpc2c8 25 + enc: | 26 + -----BEGIN AGE ENCRYPTED FILE----- 27 + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUa2czYURoeGhXWU9sOW9M 28 + cmxETG9pdVdzWURpZUdoZUp2T0Mwak5aT2prCmhnOEJERG53ZEtCRS9UZmtDRlFx 29 + Q1docCsrN2F2cGdZUUtNS3cyMXVYYzAKLS0tIEZzNXFXeWU5RVA4QzcwM0pMT2NU 30 + Y3FpS01jaDBHZTNSbXhuRDRyb2xHZk0K7cOxejnHR4Wm81dO18+r3PVY2nxlKqXf 31 + Ldrht8GxVR7kdACdlr34B4QO97O86WuUcjndt60+Lu2aGUOVVjaZ3w== 32 + -----END AGE ENCRYPTED FILE----- 33 + lastmodified: "2026-02-27T14:59:06Z" 34 + mac: ENC[AES256_GCM,data:tZHHz5wLTOvMsGFA+WEnejV1PKK9Rbqxx0oil+cjE8X5qWQ7UW+PFVtfwnsTPG3LFDg2oa0Cy0Nzwd5de+yRJo/7sb+2MNbdrQaSUEZv8t8PAeBxaY2c2BBVTO7Z4tQBVllWs7UstPLLCgz7QMkvTeObvFCtPrBNXctsTieesYU=,iv:JeubVhKbvtO1Hzymp+zNg10Ico/NTSUnGBnflBf3JH4=,tag:PTWcseQ/23J1u0kJnQ69LQ==,type:str] 35 + unencrypted_suffix: _unencrypted 36 + version: 3.11.0
+100
systems/focaccia/services/ente.nix
··· 1 + { 2 + config, 3 + lib, 4 + ... 5 + }: 6 + let 7 + baseDomain = "ente.pluie.me"; 8 + domainFor = n: "${n}.${baseDomain}"; 9 + 10 + webPackage = 11 + enteApp: 12 + let 13 + cfgWeb = config.services.ente.web; 14 + in 15 + cfgWeb.package.override { 16 + inherit enteApp; 17 + enteMainUrl = "https://${cfgWeb.domains.photos}"; 18 + extraBuildEnv = { 19 + NEXT_PUBLIC_ENTE_ENDPOINT = "https://${cfgWeb.domains.api}"; 20 + NEXT_PUBLIC_ENTE_ALBUMS_ENDPOINT = "https://${cfgWeb.domains.albums}"; 21 + NEXT_TELEMETRY_DISABLED = "1"; 22 + }; 23 + }; 24 + 25 + apps = rec { 26 + photos = webPackage "photos"; 27 + albums = photos; 28 + accounts = webPackage "accounts"; 29 + cast = webPackage "cast"; 30 + }; 31 + subdomains = lib.mapAttrs (n: _: domainFor n) apps; 32 + in 33 + { 34 + sops.secrets.ente = { 35 + # Needs an explicit file extension 36 + name = "ente.yaml"; 37 + sopsFile = ../secrets/ente.yaml; 38 + format = "yaml"; 39 + key = ""; # Use the entire file 40 + 41 + # Allow the service user to access the secret 42 + owner = config.services.ente.api.user; 43 + }; 44 + 45 + services.ente = { 46 + web = { 47 + enable = true; 48 + domains = { 49 + api = domainFor "api"; 50 + inherit (subdomains) 51 + photos 52 + cast 53 + albums 54 + accounts 55 + ; 56 + }; 57 + }; 58 + 59 + api = { 60 + enable = true; 61 + enableLocalDB = true; 62 + nginx.enable = false; 63 + 64 + domain = domainFor "api"; 65 + settings = { 66 + credentials-file = config.sops.secrets.ente.path; 67 + s3 = { 68 + are_local_buckets = false; 69 + b2-eu-cen = { 70 + endpoint = "nbg1.your-objectstorage.com"; 71 + region = "eu-central"; 72 + bucket = "marmelade"; 73 + }; 74 + }; 75 + }; 76 + }; 77 + }; 78 + 79 + # FIXME: For some arcane reason the ente module keeps 80 + # trying to enable nginx despite me explicitly disabling it. 81 + # PR a fix to upstream soon. 82 + services.nginx.enable = lib.mkForce false; 83 + 84 + services.postgresql.authentication = "local all all trust"; 85 + 86 + services.caddy.virtualHosts = 87 + (lib.mapAttrs' (name: app: { 88 + name = domainFor name; 89 + value.extraConfig = '' 90 + root * ${app} 91 + file_server 92 + try_files {path} {path}.html /index.html 93 + ''; 94 + }) apps) 95 + // { 96 + "api.${baseDomain}" = { 97 + extraConfig = "reverse_proxy :8080"; 98 + }; 99 + }; 100 + }
-1
systems/focaccia/services/hysteria.nix
··· 6 6 sops.secrets.hysteria = { }; 7 7 8 8 networking.firewall.allowedUDPPorts = [ 53 ]; 9 - 10 9 services.hysteria = { 11 10 enable = true; 12 11 settings = {
+1 -1
systems/laptop.nix
··· 15 15 nix.settings.extra-platforms = [ "aarch64-linux" ]; 16 16 17 17 boot = { 18 - kernelPackages = pkgs.linuxPackages_xanmod; 18 + kernelPackages = pkgs.linuxPackages_xanmod_latest; 19 19 20 20 loader = { 21 21 limine = {
+5
systems/pappardelle/configuration.nix
··· 12 12 hardware.bluetooth.enable = true; 13 13 networking.hostName = "pappardelle"; 14 14 users.users.leah.enable = true; 15 + 16 + boot.kernelParams = [ "intel_idle.max_cstate=9" ]; 17 + services.fwupd.enable = true; 18 + 19 + services.tailscale.enable = true; 15 20 }