/ nix / hosts / rig / default.nix
default.nix
  1  { config, pkgs, lib, ... }:
  2  
  3  {
  4    imports = [
  5      ./hardware.nix
  6      ./disk-config.nix
  7      ../../modules/nvidia.nix
  8      ../../modules/docker.nix
  9      ../../modules/nats.nix
 10      ../../modules/caddy.nix
 11      ../../modules/hardening.nix
 12      ../../modules/monitoring.nix
 13      ../../modules/sops.nix
 14      ../../modules/containers.nix
 15      ../../modules/web-terminal.nix
 16    ];
 17  
 18    # ── System ───────────────────────────────────────────────────────────
 19    system.stateVersion = "25.05";
 20    nixpkgs.config.allowUnfree = true; # NVIDIA drivers
 21  
 22    nix = {
 23      settings = {
 24        experimental-features = [ "nix-command" "flakes" ];
 25        auto-optimise-store = true;
 26        # Flox binary cache for prebuilt NVIDIA/CUDA packages
 27        substituters = [
 28          "https://cache.nixos.org"
 29          "https://cache.flox.dev"
 30        ];
 31        trusted-public-keys = [
 32          "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
 33          "flox-cache-public-1:7F4OyH7ZCnFhcze3fJdfyXYLQw/aV7GEed86nQ7IsOs="
 34        ];
 35      };
 36      gc = {
 37        automatic = true;
 38        dates = "weekly";
 39        options = "--delete-older-than 14d";
 40      };
 41    };
 42  
 43    # ── Boot ─────────────────────────────────────────────────────────────
 44    boot.loader = {
 45      systemd-boot.enable = true;
 46      efi.canTouchEfiVariables = true;
 47    };
 48  
 49    # ── Swap (file-based) ───────────────────────────────────────────────
 50    swapDevices = [{
 51      device = "/var/swapfile";
 52      size = 8192; # 8 GB
 53    }];
 54  
 55    # ── Networking ───────────────────────────────────────────────────────
 56    networking = {
 57      hostName = "rig";
 58      domain = "lan";
 59      interfaces.enp3s0.useDHCP = true;
 60      firewall = {
 61        enable = true;
 62        allowedTCPPorts = [
 63          22    # SSH
 64          80    # Caddy HTTP
 65          443   # Caddy HTTPS
 66          4222  # NATS client
 67          8222  # NATS monitoring
 68          8123  # HomeAssistant (proxied via nuclide-amd Caddy)
 69          10700 # Pipecat voice agent WebSocket
 70          10800 # Voice enrollment API
 71          4242  # Reticulum transport node (TCP)
 72          10850 # Web terminal (Claude Code shared session)
 73          8776  # Radicle node (Heartwood gossip protocol)
 74        ];
 75      };
 76    };
 77  
 78    # mDNS for rig.lan resolution
 79    services.avahi = {
 80      enable = true;
 81      nssmdns4 = true;
 82      publish = {
 83        enable = true;
 84        addresses = true;
 85        domain = true;
 86      };
 87    };
 88  
 89    # ── Locale & Time ───────────────────────────────────────────────────
 90    time.timeZone = "America/New_York"; # TODO: adjust to your timezone
 91    i18n.defaultLocale = "en_US.UTF-8";
 92  
 93    # ── Users ────────────────────────────────────────────────────────────
 94    users.users.rig = {
 95      isNormalUser = true;
 96      home = "/home/rig";
 97      extraGroups = [ "docker" "wheel" ];
 98      openssh.authorizedKeys.keys = [
 99        "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCuORrNxVcSNz5reF0seaLo+synL0LILm2FUkey9vbMqfH0K44hIkSzPNYVRgCpb2f6ISVPt4Lp+0AifWIn7om2kn6ppMAI+dV0By8PSliwaUyuq+P0AQ0fqBBrqKSMiH9XG8P/9WubWuuZBgNC6lKPTOIWuWUPBwqtDwA7/ZHntoJuH4KItiC3FqGuTIznmUghZDEp4IcAW+6/DBnx7OxREc1N2VN94aGdDKotDJ7zPZQ1ieZ++okU5htRb6eY+b4pYRZcDPlUc9G1DAnRObosU28IRFmLm8VP6r+HbCIQcJNkuD2K7n2eUYEZtJBpiovl1q7RaZVCFJAIItyLm+08WjmcGL1rVIedUxxwxbewk4YgXSiPGKLgEHOuxus9C/ITntHP6jqSVL8ZRKSB+cwWMAQ01Lpv5jWf/KbOx619OjVaFBol0cxqNGm4Nv5QC2zRhEuS8JclAscYbVe+77+DKVhJr76E8b4cla7XfhjQ5DP/AlWw2f6gaFPdU4MlNPc= nh@NH-OneXPlayer"
100      ];
101    };
102  
103    security.sudo.extraRules = [{
104      users = [ "rig" ];
105      commands = [{
106        command = "ALL";
107        options = [ "NOPASSWD" ];
108      }];
109    }];
110  
111    # ── Secrets ──────────────────────────────────────────────────────────
112    # Managed by sops-nix (see modules/sops.nix)
113    # Age key at /var/lib/sops-nix/key.txt
114    # Encrypted secrets at nix/secrets/secrets.yaml
115  
116    # ── Environment ──────────────────────────────────────────────────────
117    # Ensure /run/wrappers/bin is in PATH for setuid binaries (sudo, etc.)
118    environment.extraInit = ''
119      export PATH="/run/wrappers/bin:$PATH"
120    '';
121  
122    # ── Packages ─────────────────────────────────────────────────────────
123    environment.systemPackages = with pkgs; [
124      git
125      htop
126      nvtopPackages.full
127      jq
128      curl
129      wget
130      tmux
131      restic       # encrypted backups
132      age          # for sops-nix key generation
133      sops         # secret management
134      nats-server  # CLI tools (natscli)
135      natscli
136      radicle-node # Radicle (Heartwood) decentralized git
137    ];
138  
139    # ── Radicle Node ─────────────────────────────────────────────────────
140    # Persistent Radicle node — keeps Bob repo replicated across rig + nuclide
141    systemd.services.radicle-node = {
142      description = "Radicle Heartwood node";
143      wantedBy = [ "multi-user.target" ];
144      after = [ "network-online.target" ];
145      wants = [ "network-online.target" ];
146      serviceConfig = {
147        Type = "simple";
148        User = "rig";
149        Group = "users";
150        ExecStart = "${pkgs.radicle-node}/bin/radicle-node --listen 0.0.0.0:8776 --force";
151        Restart = "always";
152        RestartSec = "10";
153        Environment = [
154          "RAD_HOME=/home/rig/.radicle"
155          "PATH=${pkgs.radicle-node}/bin:/run/current-system/sw/bin"
156        ];
157      };
158    };
159  }