2023-06-30 11:00:03 +02:00
|
|
|
# Distributed Building
|
2023-06-27 04:53:11 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Distributed building can significantly speed up the build process by utilizing multiple
|
|
|
|
machines. However, for ordinary NixOS users, distributed building may not be very useful
|
|
|
|
since `cache.nixos.org` provides a vast majority of caches for the `x86_64` architecture.
|
|
|
|
|
|
|
|
Distributed building is particularly valuable in scenarios where no cache is available,
|
|
|
|
such as:
|
|
|
|
|
|
|
|
1. Users of `RISC-V` or `ARM64` architectures, especially `RISC-V`, as there are very few
|
|
|
|
caches for these architectures in the official cache repository. Local compilation is
|
|
|
|
often required.
|
|
|
|
2. Users who heavily customize their systems. The packages in the official cache
|
|
|
|
repository are built with default configurations. If you modify the build parameters,
|
|
|
|
the official cache is not applicable, and local compilation is necessary. For example,
|
|
|
|
in embedded scenarios, customization of the underlying kernel, drivers, etc., is often
|
|
|
|
required, leading to the need for local compilation.
|
2023-06-27 04:53:11 +02:00
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
## Configuring Distributed Building
|
2023-06-27 04:53:11 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
Currently, there is no official documentation for distributed building. However, I have
|
|
|
|
provided a sample distributed build configuration (a NixOS module) below, along with some
|
|
|
|
recommended reference documents at the end of this section.
|
2023-06-27 04:53:11 +02:00
|
|
|
|
|
|
|
```nix
|
|
|
|
{ ... }: {
|
|
|
|
|
|
|
|
####################################################################
|
|
|
|
#
|
|
|
|
# NixOS's Configuration for Remote Building / Distributed Building
|
|
|
|
#
|
|
|
|
####################################################################
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
# Set local's max-jobs to 0 to force remote building (disable local building).
|
2023-06-27 04:53:11 +02:00
|
|
|
# nix.settings.max-jobs = 0;
|
|
|
|
nix.distributedBuilds = true;
|
2023-06-28 11:41:46 +02:00
|
|
|
nix.buildMachines =
|
2023-06-27 04:53:11 +02:00
|
|
|
let
|
|
|
|
sshUser = "ryan";
|
2023-07-04 06:18:46 +02:00
|
|
|
# Path to the SSH key on the local machine.
|
2023-06-27 04:53:11 +02:00
|
|
|
sshKey = "/home/ryan/.ssh/ai-idols";
|
|
|
|
systems = [
|
2023-07-04 06:18:46 +02:00
|
|
|
# Native architecture.
|
2023-06-27 04:53:11 +02:00
|
|
|
"x86_64-linux"
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
# Emulated architecture using binfmt_misc and qemu-user.
|
2023-06-27 04:53:11 +02:00
|
|
|
"aarch64-linux"
|
|
|
|
"riscv64-linux"
|
|
|
|
];
|
2023-07-04 06:18:46 +02:00
|
|
|
# All available system features are poorly documented here:
|
|
|
|
# https://github.com/NixOS/nix/blob/e503ead/src/libstore/globals.hh#L673-L687
|
2023-06-27 04:53:11 +02:00
|
|
|
supportedFeatures = [
|
|
|
|
"benchmark"
|
|
|
|
"big-parallel"
|
|
|
|
"kvm"
|
|
|
|
];
|
|
|
|
in
|
|
|
|
[
|
2023-07-04 06:18:46 +02:00
|
|
|
# Nix seems to always prioritize remote building.
|
|
|
|
# To make use of the local machine's high-performance CPU, do not set the remote builder's maxJobs too high.
|
2023-06-27 04:53:11 +02:00
|
|
|
{
|
2023-07-04 06:18:46 +02:00
|
|
|
# Some of my remote builders are running NixOS
|
|
|
|
# and have the same sshUser, sshKey, systems, etc.
|
2023-06-27 04:53:11 +02:00
|
|
|
inherit sshUser sshKey systems supportedFeatures;
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
# The hostName should be:
|
|
|
|
# 1. A hostname that can be resolved by DNS.
|
|
|
|
# 2. The IP address of the remote builder.
|
|
|
|
# 3. A host alias defined globally in /etc/ssh/ssh_config.
|
2023-06-27 04:53:11 +02:00
|
|
|
hostName = "aquamarine";
|
2023-07-04 06:18:46 +02:00
|
|
|
# Remote builder's max-jobs.
|
2023-06-27 04:53:11 +02:00
|
|
|
maxJobs = 3;
|
2023-07-04 06:18:46 +02:00
|
|
|
# SpeedFactor is a signed integer,
|
|
|
|
# but it seems that it's not used by Nix and has no effect.
|
2023-06-27 04:53:11 +02:00
|
|
|
speedFactor = 1;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
inherit sshUser sshKey systems supportedFeatures;
|
|
|
|
hostName = "ruby";
|
|
|
|
maxJobs = 2;
|
|
|
|
speedFactor = 1;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
inherit sshUser sshKey systems supportedFeatures;
|
|
|
|
hostName = "kana";
|
|
|
|
maxJobs = 2;
|
|
|
|
speedFactor = 1;
|
|
|
|
}
|
|
|
|
];
|
2023-07-04 06:18:46 +02:00
|
|
|
# Optional: Useful when the builder has a faster internet connection than yours.
|
2023-06-27 04:53:11 +02:00
|
|
|
nix.extraOptions = ''
|
2023-07-06 05:04:52 +02:00
|
|
|
builders-use-substitutes = true
|
2023-06-27 04:53:11 +02:00
|
|
|
'';
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
# Define the host aliases for remote builders.
|
|
|
|
# This configuration will be written to /etc/ssh/ssh_config.
|
2023-06-27 04:53:11 +02:00
|
|
|
programs.ssh.extraConfig = ''
|
|
|
|
Host ai
|
|
|
|
HostName 192.168.5.100
|
|
|
|
Port 22
|
2023-06-28 11:41:46 +02:00
|
|
|
|
2023-06-27 04:53:11 +02:00
|
|
|
Host aquamarine
|
|
|
|
HostName 192.168.5.101
|
|
|
|
Port 22
|
2023-06-28 11:41:46 +02:00
|
|
|
|
2023-06-27 04:53:11 +02:00
|
|
|
Host ruby
|
|
|
|
HostName 192.168.5.102
|
|
|
|
Port 22
|
|
|
|
|
|
|
|
Host kana
|
|
|
|
HostName 192.168.5.103
|
|
|
|
Port 22
|
|
|
|
'';
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
# Define the host keys for remote builders so that Nix can verify all the remote builders.
|
|
|
|
# This configuration will be written to /etc/ssh/ssh_known_hosts.
|
2023-06-27 04:53:11 +02:00
|
|
|
programs.ssh.knownHosts = {
|
|
|
|
# 星野 愛久愛海, Hoshino Aquamarine
|
|
|
|
aquamarine = {
|
|
|
|
hostNames = [ "aquamarine" "192.168.5.101" ];
|
|
|
|
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDnCQXlllHoLX5EvU+t6yP/npsmuxKt0skHVeJashizE";
|
|
|
|
};
|
|
|
|
|
|
|
|
# 星野 瑠美衣, Hoshino Rubii
|
|
|
|
ruby = {
|
|
|
|
hostNames = [ "ruby" "192.168.5.102" ];
|
|
|
|
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE7n11XxB8B3HjdyAsL3PuLVDZxWCzEOUTJAY8+goQmW";
|
|
|
|
};
|
|
|
|
|
|
|
|
# 有馬 かな, Arima Kana
|
|
|
|
kana = {
|
|
|
|
hostNames = [ "kana" "192.168.5.103" ];
|
|
|
|
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ3dDLOZERP1nZfRz3zIeVDm1q2Trer+fWFVvVXrgXM1";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
## Limitations
|
2023-06-27 04:53:11 +02:00
|
|
|
|
2023-07-04 06:18:46 +02:00
|
|
|
Here are some observed issues and limitations:
|
2023-06-27 04:53:11 +02:00
|
|
|
|
2024-03-16 12:29:05 +01:00
|
|
|
1. You cannot specify which hosts to use at build time. You can only specify a list of
|
|
|
|
hosts in the configuration file, and Nix automatically selects available hosts.
|
|
|
|
2. When choosing a host, Nix always prefers the remote host over the local host, even if
|
|
|
|
the local host has better performance. This can result in underutilization of the local
|
|
|
|
host's CPU.
|
|
|
|
3. The smallest unit of distributed building is a derivation. When building large
|
|
|
|
packages, other machines may remain idle for a long time, waiting for the large package
|
|
|
|
to be built. This can lead to resource wastage.
|
2023-06-27 04:53:11 +02:00
|
|
|
|
|
|
|
## References
|
|
|
|
|
2024-05-10 03:40:43 +02:00
|
|
|
- [Distributed build - NixOS Wiki](https://wiki.nixos.org/wiki/Distributed_build)
|
2023-06-27 04:53:11 +02:00
|
|
|
- [Document available system features - nix#7380](https://github.com/NixOS/nix/issues/7380)
|
2023-07-04 06:18:46 +02:00
|
|
|
- [Distributed builds seem to disable local builds - nix#2589](https://github.com/NixOS/nix/issues/2589)
|
2023-06-27 04:53:11 +02:00
|
|
|
- [Offloading NixOS builds to a faster machine](https://sgt.hootr.club/molten-matter/nix-distributed-builds/)
|
2024-03-16 11:07:01 +01:00
|
|
|
- [tests/nixos/remote-builds.nix - Nix Source Code](https://github.com/NixOS/nix/blob/713836112/tests/nixos/remote-builds.nix#L46)
|