{ config, lib, pkgs, ... }: { imports = [ # Include the results of the hardware scan. ./hardware-configuration.nix ]; nixpkgs.config.allowUnfree = true; # Use the systemd-boot EFI boot loader. boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; networking.hostName = "${hostname}"; # Define your hostname. time.timeZone = "Australia/Melbourne"; # List packages installed in system profile. To search, run: # $ nix search wget # environment.systemPackages = with pkgs; [ # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default. # wget # ]; # Some programs need SUID wrappers, can be configured further or are # started in user sessions. # programs.mtr.enable = true; # programs.gnupg.agent = { # enable = true; # enableSSHSupport = true; # }; # List services that you want to enable: services = { nomad = { enable = true; enableDocker = true; dropPrivileges = false; settings = { datacenter = "jaglan-beta"; server = { enabled = true; %{if bootstrap ~} bootstrap_expect = 1; %{endif ~} }; client = { enabled = true; preferred_address_family = "ipv4"; %{if cpu_total_compute != null ~} cpu_total_compute = ${cpu_total_compute}; %{endif ~} %{if node_class != null ~} node_class = "${node_class}"; %{endif ~} host_volume = { %{ for volume in host_volumes ~} ${volume} = { path = "/opt/${volume}"; read_only = false; }; %{ endfor ~} }; cni_path = "$${pkgs.cni-plugins}/bin"; }; plugin.docker.config.allow_privileged = true; }; extraPackages = with pkgs; [ cni-plugins consul ]; }; consul = { enable = true; webUi = true; interface.bind = "${bind_interface}"; interface.advertise = "${bind_interface}"; forceAddrFamily = "ipv4"; extraConfig = { client_addr = "{{ GetPrivateInterfaces | exclude \"type\" \"ipv6\" | join \"address\" \" \" }} {{ GetAllInterfaces | include \"flags\" \"loopback\" | join \"address\" \" \" }}"; %{if bootstrap ~} bootstrap_expect = 1; %{endif ~} server = true; retry_join = [ "jaglan-beta-m01" "jaglan-beta-m02" "jaglan-beta-m03" "jaglan-beta-m04" "jaglan-beta-m05" "jaglan-beta-m20" "jaglan-beta-m21" "jaglan-beta-m22" ]; datacenter = "jaglan-beta"; connect.enabled = true; ports.grpc = 8502; }; }; openssh = { enable = true; settings.PermitRootLogin = "yes"; }; }; systemd.tmpfiles.rules = [ # Fix issue where nomad needs alloc_mounts to be writable "d /var/lib/alloc_mounts 0755 root root -" %{ for volume in host_volumes ~} # Create a directory for ${volume} to store its data "d /opt/${volume} 0755 root root -" %{ endfor ~} ]; # Open ports in the firewall. 80/443 are for HTTP/HTTPS (terraform), 464X are the default ports for Nomad, 830X are the default ports for Consul. networking.firewall.allowedTCPPorts = [ 80 443 8081 4646 4647 4648 8300 8301 8500 ]; networking.firewall.allowedUDPPorts = [ 8301 ]; # Ensure Docker daemon is available (Nomad enableDocker only configures Nomad, does not guarantee docker service) virtualisation.docker.enable = true; %{if node_class == "latte-panda-n150" ~} # Enable Intel iGPU (N150 UHD Graphics) for OpenVINO / VA-API workloads running in Docker hardware.graphics = { enable = true; extraPackages = with pkgs; [ intel-media-driver # VA-API (iHD) intel-compute-runtime # OpenCL / oneAPI ]; }; %{endif ~} # Proper systemd service definition for macvlan network creation systemd.services.docker-macvlan-network = { description = "Ensure macvlan Docker network exists"; after = [ "network-online.target" "docker.service" ]; wants = [ "network-online.target" "docker.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; }; # Provide required binaries in PATH path = [ pkgs.docker pkgs.bash pkgs.coreutils pkgs.iproute2 pkgs.gnugrep ]; script = '' set -euo pipefail NET_NAME=macvlan if docker network inspect "$NET_NAME" >/dev/null 2>&1; then echo "Docker network $NET_NAME already exists" exit 0 fi echo "Creating Docker macvlan network $NET_NAME on interface ${bind_interface}" # We intentionally do NOT use --ip-range here to avoid allocating the # same reserved pool on every host (which could lead to collisions if # multiple macvlan containers are started across nodes). Instead, we # give critical services (like UniFi) an explicit static IP via the # Nomad job (Docker static assignment) and rely on manual DHCP # reservations to prevent conflicts. # # If you later need multiple macvlan-assigned containers per host, # consider one of these strategies: # 1. Per-host distinct network name + ip-range slice (macvlan-m01, ...) # 2. Parameterize an ip-range per host in Terraform and template here # 3. Keep a registry of allocated static IPs in Consul KV / Nomad vars docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --gateway=192.168.1.1 \ -o parent=${bind_interface} \ "$NET_NAME" echo "Docker macvlan network $NET_NAME created" ''; restartIfChanged = false; # Don't rerun just because comment changed }; # Copy the NixOS configuration file and link it from the resulting system # (/run/current-system/configuration.nix). This is useful in case you # accidentally delete configuration.nix. system.copySystemConfiguration = true; # Defines the initial NixOS version for compatibility with older application data. # Do NOT change this value after installation without careful consideration. system.stateVersion = "24.11"; # Did you read the comment? }