# sudo nixos-rebuild switch --flake .#builder --target-host root@192.168.3.118 # or # deploy .#builder { config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ../common/global/fish.nix # fish for admin ../common/global/locale.nix ../common/global/nix.nix ../common/global/sops.nix ../common/global/root.nix ]; networking.hostName = "builder"; system.stateVersion = "23.11"; networking.nameservers = [ "192.168.3.252" "172.30.20.10" "1.1.1.1" ]; users.mutableUsers = false; users.users.nix = { isNormalUser = true; description = "Nix"; extraGroups = [ "networkmanager" "wheel" "docker" ]; }; nix.settings.experimental-features = [ "nix-command" "flakes" ]; # Setup binary caches nix.settings = { substituters = [ "https://nix-community.cachix.org" "https://cache.nixos.org/" "https://hyprland.cachix.org" "https://devenv.cachix.org" ]; trusted-public-keys = [ "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=" ]; trusted-users = ["nix"]; max-jobs = "auto"; cores = 0; # Ensure we can still build when missing-server is not accessible fallback = true; }; # system.autoUpgrade = { # enable = true; # flake = "git+https://gitlab.julian-mutter.de/julian/dotfiles"; # flags = [ # "--recreate-lock-file" # update lock file # ]; # dates = "02:13"; # }; # optimize store by hardlinking store files nix.optimise.automatic = true; nix.optimise.dates = ["03:15"]; # nix.gc.automatic = true; # nix.gc.dates = "daily"; # nix.gc.options = "--delete-old"; # nix.settings.keep-derivations = false; # nix.settings.keep-outputs = true; # Garbage collect up to 100 GiB when only 20 GiB storage left nix.extraOptions = '' min-free = ${toString (20 * 1024 * 1024 * 1024)} max-free = ${toString (100 * 1024 * 1024 * 1024)} ''; nix.nrBuildUsers = 64; # prevent memory to get filled systemd.services.nix-daemon.serviceConfig = { MemoryAccounting = true; MemoryMax = "90%"; OOMScoreAdjust = 500; }; # Ollama used by open-webui as llm backend # services.ollama = { # enable = true; # # acceleration = "rocm"; # }; # services.open-webui = { # enable = true; # port = 8080; # openFirewall = true; # host = "builder.julian-mutter.de"; # }; networking.firewall.allowedTCPPorts = [ 80 ]; services.openssh = { enable = true; # require public key authentication for better security settings.PasswordAuthentication = false; settings.KbdInteractiveAuthentication = false; settings.PermitRootLogin = "yes"; # Add older algorithms for jenkins ssh-agents-plugin to be compatible settings.Macs = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" "umac-128-etm@openssh.com" "hmac-sha2-512" "hmac-sha2-256" "umac-128@openssh.com" ]; settings.KexAlgorithms = [ "diffie-hellman-group-exchange-sha1" "diffie-hellman-group14-sha1" "mlkem768x25519-sha256" "sntrup761x25519-sha512" "sntrup761x25519-sha512@openssh.com" "curve25519-sha256" "curve25519-sha256@libssh.org" "diffie-hellman-group-exchange-sha256" ]; }; users.users."root".openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjSZYdoF/51F+ykcBAYVCzCPTF5EEigWBL1APiR0h+H julian@aspi" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGFcS+3d1tNgHmYCjueymCV9Bd2LcJcKGhVobrDe3r0s julian@kardorf" ]; users.users."nix".openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFjSZYdoF/51F+ykcBAYVCzCPTF5EEigWBL1APiR0h+H julian@aspi" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAIQ+qMuXvyoxO1DuCR3/x+IQRfSA2WyMuzuotWZjCye root@aspi" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHnfLJnS2SKUs47J0qpLTkk0LQA5quOuAhnxE6yppUDm root@kardorf" ]; # security.pam.sshAgentAuth.enable = true; # enable sudo via ssh services.hydra = { enable = true; hydraURL = "http://hydra.julian-mutter.de"; # externally visible URL port = 3000; notificationSender = "hydra@julian-mutter.de"; # e-mail of hydra service # a standalone hydra will require you to unset the buildMachinesFiles list to avoid using a nonexistant /etc/nix/machines # buildMachinesFiles = [ ]; # you will probably also want, otherwise *everything* will be built from scratch useSubstitutes = true; minimumDiskFree = 5; # in GB minimumDiskFreeEvaluator = 4; # in GB }; # add builder itself as build machine so system emulation is properly supported # nix.distributedBuilds = true; nix.buildMachines = [ { hostName = "localhost"; protocol = null; # sshUser = "nix"; systems = [ "x86_64-linux" "aarch64-linux" ]; maxJobs = 4; speedFactor = 3; supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; } ]; # Uris allowed as flake inputs, otherwise hydra does not fetch them nix.settings.allowed-uris = [ "github:" "gitlab:" "git+https://github.com/hyprwm/Hyprland" "https://github.com/hyprwm/Hyprland" "https://github" "https://gitlab" "https://gitlab.julian-mutter.de" "git+https://gitlab.julian-mutter.de" ]; services.nginx = { enable = true; recommendedProxySettings = true; # recommendedTlsSettings = true; # other Nginx options virtualHosts."hydra.julian-mutter.de" = { # enableACME = true; # forceSSL = true; locations."/" = { proxyPass = "http://127.0.0.1:3000"; # proxyWebsockets = true; # needed if you need to use WebSocket # extraConfig = # # required when the target is also TLS server with multiple hosts # "proxy_ssl_server_name on;" + # # required when the server wants to use HTTP Authentication # "proxy_pass_header Authorization;" # ; }; }; virtualHosts."binarycache.julian-mutter.de" = { locations."/".proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}"; }; clientMaxBodySize = "2G"; virtualHosts."cache.julian-mutter.de" = { locations."/".proxyPass = "http://127.0.0.1:8080"; }; }; # =========== Gitea actions ========== services.gitea-actions-runner.instances."builder" = { enable = true; url = "https://gitlab.julian-mutter.de"; name = "builder"; tokenFile = config.sops.secrets."gitea_token".path; labels = [ # provide a debian base with nodejs for actions "debian-latest:docker://node:18-bullseye" # fake the ubuntu name, because node provides no ubuntu builds "ubuntu-latest:docker://node:18-bullseye" # devenv "devenv:docker://ghcr.io/cachix/devenv/devenv:latest" # provide native execution on the host "nixos:host" ]; }; virtualisation.docker.enable = true; # TODO: podman fails with: "cannot resolve hostname" # virtualisation.podman = { # enable = true; # dockerCompat = true; # defaultNetwork.settings.dns_enabled = true; # }; sops.secrets."gitea_token" = { owner = config.users.users.nix.name; sopsFile = ./secrets.yaml; }; # =========== Binary Cache ========== services.nix-serve = { enable = true; secretKeyFile = "/var/cache-priv-key.pem"; }; # =========== Binary Cache with attic ========== sops.secrets."attic_token".sopsFile = ./secrets.yaml; services.atticd = { enable = true; environmentFile = config.sops.secrets."attic_token".path; settings = { listen = "[::]:8080"; jwt = {}; # Data chunking # # Warning: If you change any of the values here, it will be # difficult to reuse existing chunks for newly-uploaded NARs # since the cutpoints will be different. As a result, the # deduplication ratio will suffer for a while after the change. chunking = { # The minimum NAR size to trigger chunking # # If 0, chunking is disabled entirely for newly-uploaded NARs. # If 1, all NARs are chunked. nar-size-threshold = 64 * 1024; # 64 KiB # The preferred minimum size of a chunk, in bytes min-size = 16 * 1024; # 16 KiB # The preferred average size of a chunk, in bytes avg-size = 64 * 1024; # 64 KiB # The preferred maximum size of a chunk, in bytes max-size = 256 * 1024; # 256 KiB }; }; }; services.gitlab-runner.enable = true; # runner for everything else # sops.secrets."gitlab_runner_token".sopsFile = ./secrets.yaml; services.gitlab-runner.services.default = { # File should contain at least these two variables: authenticationTokenConfigFile = config.sops.secrets."gitlab_runner_token".path; dockerImage = "alpine:latest"; dockerVolumes = [ "/var/run/docker.sock:/var/run/docker.sock" ]; }; ### Jenkins node users.users.jenkins = { createHome = true; home = "/var/lib/jenkins"; group = "jenkins"; isNormalUser = true; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ36sQhVz3kUEi8754G7r3rboihhG4iqFK/UvQm6SING jenkins@home" ]; packages = with pkgs; [ git devenv ]; extraGroups = [ "docker" ]; }; users.groups.jenkins = {}; programs.java = { enable = true; package = pkgs.jdk21; # Same as jenkins version on home }; }