{ config, lib, pkgs, homeyConfig, ... }: # Common configuration shared by every host in the homey ecosystem. # Hardware-specific settings (disk layout, device trees, etc.) go in # hosts//hardware.nix instead. { # ------------------------------------------------------------------------- # Nix / flakes # ------------------------------------------------------------------------- nix = { settings = { experimental-features = [ "nix-command" "flakes" ]; auto-optimise-store = true; # Extra binary caches — speeds up aarch64-linux builds significantly substituters = [ "https://cache.nixos.org" "https://nix-community.cachix.org" ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "nix-community.cachix.org-1:mB9FkXj6Q3Q4ohOcbM4FJ9Z1X2kCrVK4vZOqsDqqNqk=" ]; # Trigger GC automatically when free space drops below 2 GB; # stop once 5 GB is free. Prevents CI builds from filling the disk # between weekly GC runs. min-free = 2147483648; # 2 GiB max-free = 5368709120; # 5 GiB }; gc = { automatic = true; dates = "weekly"; options = "--delete-older-than 14d"; }; }; # Allow unfree packages (e.g. cloudflared binary) nixpkgs.config.allowUnfree = true; # ------------------------------------------------------------------------- # Boot — set in hardware.nix; this is just a safe default # ------------------------------------------------------------------------- # boot.loader is intentionally left to hardware.nix # ------------------------------------------------------------------------- # Locale / timezone # ------------------------------------------------------------------------- time.timeZone = homeyConfig.timezone; i18n.defaultLocale = "en_US.UTF-8"; # ------------------------------------------------------------------------- # Networking # ------------------------------------------------------------------------- networking = { # hostname is set per-host in default.nix firewall = { enable = true; allowedTCPPorts = [ 22 # SSH 80 # Caddy HTTP (redirect to HTTPS or ACME challenge) 443 # Caddy HTTPS ]; }; # Use systemd-resolved for DNS — supports mDNS and local overrides nameservers = [ "1.1.1.1" "8.8.8.8" ]; }; # ------------------------------------------------------------------------- # SSH # ------------------------------------------------------------------------- services.openssh = { enable = true; settings = { PasswordAuthentication = false; PermitRootLogin = "no"; }; }; # ------------------------------------------------------------------------- # Container runtime — podman (rootless-capable, no daemon needed) # ------------------------------------------------------------------------- virtualisation.podman = { enable = true; dockerCompat = true; # allow `docker` CLI commands against podman defaultNetwork.settings.dns_enabled = true; }; # Create the shared "homey" podman network that all service containers join. # DNS is enabled by default on netavark-backed networks, so containers can # reach each other by container name (e.g. "openldap", "nextcloud-postgres"). systemd.services.podman-homey-network = { description = "Create homey podman network"; wantedBy = [ "multi-user.target" ]; before = [ "podman-openldap.service" "podman-authelia.service" "podman-gitea.service" "podman-nextcloud-postgres.service" "podman-nextcloud.service" "podman-phpldapadmin.service" "podman-jellyfin.service" "podman-transmission.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; ExecStart = pkgs.writeShellScript "create-homey-network" '' ${pkgs.podman}/bin/podman network exists homey \ || ${pkgs.podman}/bin/podman network create homey ''; }; }; # ------------------------------------------------------------------------- # Core packages available on every host # ------------------------------------------------------------------------- environment.systemPackages = with pkgs; [ git vim htop curl wget rsync lsof sops # secret editing age # key generation for sops restic # backup (CLI, also used by services.restic) podman-compose ]; # ------------------------------------------------------------------------- # sops-nix global config — point at the secrets file and the host's age key # ------------------------------------------------------------------------- sops = { defaultSopsFile = ../secrets/secrets.yaml; # The age private key must be present on the host at this path. # Generate on the Pi with: age-keygen -o /var/lib/sops-nix/key.txt # Then add the PUBLIC key to secrets/.sops.yaml before encrypting. age.keyFile = "/var/lib/sops-nix/key.txt"; }; # ------------------------------------------------------------------------- # Admin user — adjust username / SSH key in hosts//default.nix # ------------------------------------------------------------------------- users.mutableUsers = false; # all user config must be declared here # The actual admin user is declared in hosts//default.nix so the # SSH authorized key can be host-specific. # ------------------------------------------------------------------------- # System state version — do not change after first install # (tracks NixOS backwards-compat markers) # ------------------------------------------------------------------------- system.stateVersion = "25.05"; }