Build Custom Hardware Kernel on build Server

I am trying to build a custom kernel for my Microsoft Surface device on a build server (which is also a binary cache) to improve turnaround times in setting up my laptop.

I have added the hardware channel as an unprivileged user on my build server and I also ran nix-channel --update as the same user.

I have tried to nix-build '<nixos-hardware/microsoft/surface>' but it errors with:

error: cannot auto-call a function that has an argument without a default value ('config')

People in the telegram group are telling me I should clone the hardware repo and remove the config parameter, but that seems excessive to me. When used in an os config environment "${builtins.fetchGit { url = ""; }}/microsoft/surface" it also builds somehow.
How can I make this build manually?

<nixos-hardware/microsoft/surface> looks to be a NixOS module and those can’t be used directly with nix-build. You have to have a full OS configuration and then you can go through <nixpkgs/nixos>.

When I say a full OS configuration I just mean a functioning configuration.nix and all files it depends on.

Then if you just want what is normally linked in /run/current-system you can build that by calling
nix-build --arg configuration ./configuration.nix '<nixpkgs/nixos>' -A system

That worked out nicely. Thanks a lot.
I have also found this thread which is basically what I am trying to do. But instead of preloading the built OS closure into a live-iso I am trying to host it on my own nix cache.

If I want to install that system I will probably have to call nixos-install with the --system option and give it the path of the built closure from the above nix-build command, right?
Or does it just compare the config hashes and work out the system path on its own?

To use --system you run into a bit of a chicken or egg problem with the disk partitioning. For a configuration to be usable with the --system option it needs to exactly fit that machine and that means it needs to be built with the info normally stored in /etc/nixos/hardware-configuration.nix which is generated by nixos-generate-config in a normal installation. There are ways to generalize the partition info by using labels instead of UUID for disks and if you are going to install many machines on identical hardware it might be worth your while. But there is also a different approach.

Have you considered using your build server as a remote builder instead of just a cache? With a setup like that the machine you want to install on just needs SSH access to the build server and some configuration and then it will offload either all building or just some of the building to the build server.

The remote builder is a good call. Unfortunately the cache is on a relatively week VM which is on our storage host while my build machine is on a shelf in my flats hallway, also serves as my gaming machine and I have to connect to it via wireguard.
Currently I use nix-copy-closure to get stuff from the build machine onto the cache. Eventually I would like to set up CI to build a new kernel whenever a new release is tagged.

I basically discovered nixos because I set up a similar system for debian. I have a custom install script that is supposed to run from a debian live stick which partitions the disk of my laptop and then installs debian and my preferred desktop environment.

I have now replicated the same setup for a nix live iso usb stick which pulls the machines configuration based on its machine id from a git repository.

You can do some pretty advanced/weird things with remote builders. SSH JumpHosts, ProxyCommand and your remote builder can even have its own pool of remote builders that it forwards builds to. So if your weak VM can SSH to the build server you could have it forward the actual building to the more powerfull machine.

Thanks for telling me that. I was actually searching for something like that for quite some time and even started learning kubernetes to run builds.
I have access to quite a lot of machines, all of which have some resources left over some of the time, so ideally I would like the one with the least load to run my builds.
I am starting to like nixos more and more.