{ description = "Homey - self-hosted home server NixOS configuration"; # Binary cache for pre-built Raspberry Pi kernel + firmware packages. # nixos-raspberrypi builds against its own pinned nixpkgs and publishes # to this cache — using it avoids compiling linuxPackages_rpi4 from source. nixConfig = { extra-substituters = [ "https://nixos-raspberrypi.cachix.org" ]; extra-trusted-public-keys = [ "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI=" ]; }; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; # sops-nix for secret management sops-nix = { url = "github:Mic92/sops-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; # Raspberry Pi hardware support — provides vendor kernel, firmware, # bootloader management, and a binary cache for pre-built aarch64 packages. # Intentionally NOT following our nixpkgs: the cache is built against the # flake's own pinned nixpkgs, so following would invalidate all cache hits. nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/main"; }; outputs = { self, nixpkgs, sops-nix, nixos-raspberrypi, ... }@inputs: let # Shared specialArgs passed to every host commonArgs = { inherit inputs nixos-raspberrypi; # Top-level site config — override per-host if needed homeyConfig = { domain = "home.zakobar.com"; # base domain for all services organization = "Zakobar Home Server"; timezone = "Asia/Jerusalem"; # External HD mount point — set in hardware.nix per host # dataDir is intentionally NOT set here; each host sets it }; }; # nixos-raspberrypi.lib.nixosSystem is a drop-in replacement for # nixpkgs.lib.nixosSystem that: # - injects vendor kernel/firmware overlays # - wires up the trusted cache substituters # - passes nixos-raspberrypi into specialArgs automatically # It uses the flake's own pinned nixpkgs by default (currently 25.11). mkHost = { hostPath, extraModules ? [] }: nixos-raspberrypi.lib.nixosSystem { specialArgs = commonArgs; modules = [ sops-nix.nixosModules.sops # RPi 4 base: vendor kernel (linuxPackages_rpi4), firmware, # bootloader (u-boot), initrd modules, config.txt management nixos-raspberrypi.nixosModules.raspberry-pi-4.base # SD image target — provides system.build.sdImage ({ modulesPath, ... }: { imports = [ "${modulesPath}/installer/sd-card/sd-image-aarch64.nix" ]; }) hostPath ./modules/common.nix ./modules/storage.nix ./modules/caddy.nix ./modules/cloudflared.nix ./modules/backup.nix ./modules/services/openldap.nix ./modules/services/authelia.nix ./modules/services/gitea.nix ./modules/services/nextcloud.nix ./modules/services/phpldapadmin.nix ./modules/services/jellyfin.nix ./modules/services/transmission.nix ] ++ extraModules; }; in { nixosConfigurations = { # Bootstrap image — flash this first. # Minimal: SSH key, WiFi, static IP. No sops, no services. # Purpose: boot the Pi, generate the age key, then deploy pi-main. pi-main-bootstrap = nixos-raspberrypi.lib.nixosSystem { specialArgs = commonArgs; modules = [ nixos-raspberrypi.nixosModules.raspberry-pi-4.base ({ modulesPath, ... }: { imports = [ "${modulesPath}/installer/sd-card/sd-image-aarch64.nix" ]; }) ./hosts/pi-main/hardware.nix ({ pkgs, lib, ... }: { networking.hostName = "pi-main"; time.timeZone = commonArgs.homeyConfig.timezone; i18n.defaultLocale = "en_US.UTF-8"; system.stateVersion = "25.05"; nix.settings.experimental-features = [ "nix-command" "flakes" ]; nixpkgs.config.allowUnfree = true; # WiFi — PSK inline (bootstrap only, not in Nix store long-term) networking.wireless = { enable = true; networks."Zakobar".psk = "0502711157"; }; networking.interfaces.wlan0.ipv4.addresses = [{ address = "192.168.1.100"; prefixLength = 24; }]; networking.useDHCP = false; networking.interfaces.wlan0.useDHCP = false; networking.defaultGateway = "192.168.1.1"; networking.nameservers = [ "1.1.1.1" "8.8.8.8" ]; networking.firewall.allowedTCPPorts = [ 22 ]; # SSH — key only, no passwords, no root services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; }; users.mutableUsers = false; users.users.admin = { isNormalUser = true; extraGroups = [ "wheel" ]; openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDBFZRqiTsOCAJPMqUyMeLd2MbyjdGoyqDVq5/Inhb6EOaM1NUGG4b6FPmYgFLyJIm5LC9BOo6M7npiaiOs/zMqp+hoGLNQUNwm5/G0uy1bjkEfKdUTdGnJ2+M9rkxrR1c+KXrjkiqECqTbnPE4mJbGyVxBW2MwMeP5w8c0DB5KO528PetvHMPPQuEdXyZzDI4kKtVpMlJoPIrIGlNFX0G/wrgXcM4zU1snOTuYGqZnWW++4kBsgIlRKpf/bLJyUMTp30eLVr0fQ6OMBtj1tzUUBaaowU6VGYQQDU/rIh/NpkA2cEVPXZegM4OohkAqrJBFPIAg90WD9Z/SyQlz0Jn8PpAloP0Cuq2vVRr+QLEwxqGiFq91YQ2VtwksMHwJGVrXRCNegpxTZQijWMEd+o0FD2cEd7Ftw6v2L6g12GJ3QGX/q0d/u0GongLLa9fPXl4VoAu7AL+cUcbX/SS7RCG8kYAR3DwOazVbK0NWEdwvWdoSU4lZ3j2at1xqMGjHjyLiTeUqZBjm+Sl5MJWIYNg+8hnONljvggg4SzDFDAkgVLZtOCaZibsMA1ucGR7VRCM09uoaEI4/ZS5pCBtYcp8X67Bv67Og8s2NFf5sUfYBPPKpdBSs+dEPycNVff6JlmzfNiyzLawacGKIDWYSgkOl43N/5ehtpsL3HMZ+5SVNIw==" ]; }; security.sudo.wheelNeedsPassword = false; environment.systemPackages = [ pkgs.age pkgs.vim ]; }) ]; }; # Primary Raspberry Pi 4 pi-main = mkHost { hostPath = ./hosts/pi-main/default.nix; }; # Future second machine (placeholder — uncomment and configure when ready) # pi-secondary = mkHost { # hostPath = ./hosts/pi-secondary/default.nix; # }; }; }; }