Files
homey/flake.nix
T
2026-04-20 05:40:09 +03:00

156 lines
6.3 KiB
Nix

{
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;
# };
};
};
}