Distributed build: Difference between revisions

m Make ssh connection path setting easier to understand
 
(10 intermediate revisions by 5 users not shown)
Line 1: Line 1:
When your '''local machine''' is too slow or doesn't have the right CPU architecture or operating system for the Nix derivation you want to build, you can delegate the build to some other '''remote machine'''. You only '''need SSH access to the remote machine''' and both machines need to have the [https://nixos.org/download/ Nix package manager installed]; but the machines '''don't need to run NixOS''', any operating system like Debian, Ubuntu, Arch or others where the Nix package manager can be installed, should work.
When your '''local machine''' is too slow or doesn't have the right CPU architecture or operating system for the Nix derivation you want to build, you can delegate the build to some other '''remote machine'''. For this you need
 
# the '''Nix package manager installed on both machines'''; just follow the [https://nixos.org/download/ official installation instructions] and prefer the normal "multi-user" install. You don't need to run NixOS; any operating system like Debian, Ubuntu, Arch, MacOS or others where the Nix package manager can be installed, should work.
# '''SSH access from the local to the remote machine'''.
# '''modify the local machine's Nix config to know about the remote machine'''.


There is a dedicated chapter in the [https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html Nix Manual] but it may be difficult to follow for beginners.
There is a dedicated chapter in the [https://nixos.org/manual/nix/stable/advanced-topics/distributed-builds.html Nix Manual] but it may be difficult to follow for beginners.
Line 5: Line 9:
This is an easier, step-by-step guide to setting up a "'''remote builder'''" machine to create distributed builds, and includes some SSH tips that are out of scope for the Nix Manual chapter.
This is an easier, step-by-step guide to setting up a "'''remote builder'''" machine to create distributed builds, and includes some SSH tips that are out of scope for the Nix Manual chapter.


== Prerequisites ==
== Setting up SSH ==


The main tool to connect to a remote builder, exchange files and trigger builds is SSH.
The main tool to connect to a remote builder, exchange files and trigger builds is SSH.
Line 23: Line 27:
! SSH Connection Requirements
! SSH Connection Requirements
|-
|-
| '''Multi-user'''  || '''Multi-user''' || '''Local''' machine's {{ic|root}} user needs SSH access to ''a'' user on the '''remote''' machine. '''(most frequent case)'''
| '''Multi-user'''  || '''Multi-user''' || '''Local:''' {{ic|root}} user ------------SSH----> '''Remote''': ''any'' user '''(most frequent case)'''
|-
|-
| Single-user || Multi-user || ''Your'' user on your '''Local''' machine needs SSH access to ''a'' user on the '''remote''' machine.
| Single-user || Multi-user || '''Local:''' ''Your'' single-user -----SSH----> '''Remote''': ''any'' user
|-
|-
| Multi-user || Single-user || '''Local''' machine's {{ic|root}} user needs SSH access to the user on the '''remote''' machine, with Nix installed with their UID (see [https://nixos.org/manual/nix/stable/installation/single-user.html Nix manual page]).
| Multi-user || Single-user || '''Local:''' {{ic|root}} user ------------SSH----> '''Remote''': ''your'' single-user for which Nix is installed with their UID (see [https://nixos.org/manual/nix/stable/installation/single-user.html Nix manual page]).
|-
|-
| Single-user || Multi-user || ''Your'' user on your '''Local''' machine needs SSH access to the user on the '''remote''' machine, with Nix installed with their UID (see [https://nixos.org/manual/nix/stable/installation/single-user.html Nix manual page]).
| Single-user || Single-user || '''Local:''' ''Your'' single-user -----SSH----> '''Remote''': ''your single-user'' each of which Nix is installed for with their UID (see [https://nixos.org/manual/nix/stable/installation/single-user.html Nix manual page]).
|}
|}


The thing to know about the '''"Multi-user"''' installation is that '''Nix is installed with a "nix-daemon" background process that runs as root''' and actually manages the builds on your behalf. So when you call '''"nix build ..." as a non-root user, this is delegated to the nix-daemon''' process, which runs as root. And this process can further delegate the build to a remote builder; that's why the '''local machine's root user''' needs the SSH access.
The thing to know about the '''"Multi-user"''' installation is that '''Nix is installed with a "nix-daemon" background process that runs as root''' and actually manages the builds on your behalf. So when you call '''"nix build ..." as a non-root user, this is delegated to the nix-daemon''' process, which runs as root. And this process can further delegate the build to a remote builder; that's why the '''local machine's root user''' needs the SSH access.


In any case, the good test for Nix SSH access, that takes this into account, is:
{{Tip|The best test to check that the SSH access works for Nix is to run on your local machine:


{{Commands|nix store ping --store ssh://<REMOTE-BUILDER>}}
<code>nix store ping --store ssh://<REMOTE-BUILDER></code>


Where {{ic|<REMOTE-BUILDER>}} is the remote builder's IP address, host address or whatever name you configure in {{ic|~/.ssh/config}} or {{ic|/root/.ssh/config}}, including the {{ic|user@}} prefix.
Where <code><REMOTE-BUILDER></code> is the remote builder's IP address, host address or whatever name you configure in ~/.ssh/config or /root/.ssh/config, including the user@ prefix.}}


An alternative check is:
An alternative check is:
Line 62: Line 66:
For the common case where your local Nix is installed system-wide in multi-user mode, create a user on the '''remote''' machine that will have an unwriteable home directory, with a {{ic|~/.ssh/authorized_keys}} in it, that will allow SSH access to that user without a passphrase. The steps are:
For the common case where your local Nix is installed system-wide in multi-user mode, create a user on the '''remote''' machine that will have an unwriteable home directory, with a {{ic|~/.ssh/authorized_keys}} in it, that will allow SSH access to that user without a passphrase. The steps are:


- {{ic|ssh}} to the remote builder.
* {{ic|ssh}} to the remote builder.
- Run (requires privileges) {{ic|useradd -m -L nixremote}} where {{ic|-L}} locks the user such that nobody will be able to {{ic|su}} to it, and {{ic|-m}} makes sure a home directory is created for the {{ic|nixremote}} user.
* Run (requires privileges) {{ic|useradd -m nixremote}}; {{ic|-m}} makes sure a home directory is created for the {{ic|nixremote}} user.
- Run (requires privileges) {{ic|mkdir ~nixremote/.ssh}}.
* Run (requires privileges) {{ic|usermod nixremote -L}}; {{ic|-L}} locks the user such that nobody will be able to {{ic|su}} to it
* Run (requires privileges) {{ic|mkdir ~nixremote/.ssh}}. Make sure to run this command as {{ic|nixremote}} user or {{ic|chown}} it afterwards


If your '''remote builder''' has Nix installed system-wide in multi-user mode, but you're not running NixOS, '''you may need to add something like the following to your''' {{ic|/etc/ssh/sshd_config}}:
If your '''remote builder''' has Nix installed system-wide in multi-user mode, but you're not running NixOS, '''you may need to add something like the following to your''' {{ic|/etc/ssh/sshd_config}} on this remote machine:


{{file|/etc/ssh/sshd_config|text|
{{file|/etc/ssh/sshd_config|text|
Line 107: Line 112:
You may also want to make nix on '''the remote machine''' trust that new user by adding it to {{ic|nix.settings.trusted-users}} if it's using NixOS, or by manually adding <code><nowiki>trusted-users = nixremote</nowiki></code> to {{ic|/etc/nix/nix.conf}}.
You may also want to make nix on '''the remote machine''' trust that new user by adding it to {{ic|nix.settings.trusted-users}} if it's using NixOS, or by manually adding <code><nowiki>trusted-users = nixremote</nowiki></code> to {{ic|/etc/nix/nix.conf}}.


You may also want to tell Nix '''on your local machine''' that the remote builder is available, and tell it what are its ''supported features'' (see [https://github.com/NixOS/nix/issues/7380 missing nix documentation issue]). If your '''local machine''' uses NixOS, you can use the documented [https://search.nixos.org/options?channel=unstable&from=0&size=15&sort=relevance&type=packages&query=nix.buildmachine {{ic|nix.buildMachines}}] NixOS option.
== Modify the local machine's Nix config to know about the remote machine. ==
The Nix package manager '''on your local machine''' '''needs to know that the remote builder exists''' and what its ''supported features'' are. See [https://nixos.org/manual/nix/stable/command-ref/conf-file#conf-system-features official supportedFeatures documentation].  


Here's an example NixOS configuration that may be a useful inspiration:
If your '''local machine''' uses NixOS, you can mention the remote builder within a NixOS [https://search.nixos.org/options?channel=unstable&from=0&size=15&sort=relevance&type=packages&query=nix.buildmachine {{ic|nix.buildMachines}}] section. For example:


{{file|/etc/nixos/configuration.nix|nix|<nowiki>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
Line 135: Line 141:
     # systems = ["x86_64-linux" "aarch64-linux" "riscv64-linux"];
     # systems = ["x86_64-linux" "aarch64-linux" "riscv64-linux"];
     system = "x86_64-linux";
     system = "x86_64-linux";
    # Nix custom ssh-variant that avoids lots of "trusted-users" settings pain
     protocol = "ssh-ng";
     protocol = "ssh-ng";
     # default is 1 but may keep the builder idle in between builds
     # default is 1 but may keep the builder idle in between builds
Line 146: Line 153:
   nix.distributedBuilds = true;
   nix.distributedBuilds = true;
   # optional, useful when the builder has a faster internet connection than yours
   # optional, useful when the builder has a faster internet connection than yours
   nix.extraOptions = ''
   nix.settings = {
     builders-use-substitutes = true
     builders-use-substitutes = true;
   '';
   };
}
}
</nowiki>}}
</nowiki>}}
Line 194: Line 201:
Now ssh will transparently run nix-user-chroot when you connect to the remote builder with the specified ssh key.
Now ssh will transparently run nix-user-chroot when you connect to the remote builder with the specified ssh key.


== Using remote builders ==
== Further use of remote builders ==


==== Local builder ====
==== Force builds on remote builder ====


Your local machine is still a builder, so when connecting to remote builders fails, nix will fall back to building locally.
Your local machine is also a builder, so when connecting to remote builders fails, Nix will fall back to building locally.
To never use the local machine, set the <code>max-jobs</code> nix option to 0:
To never use the local machine, set the <code>--max-jobs <n>/-j<n></code> Nix option to 0 as follows:
{{Commands|$ nix-build -j0 blah}}
{{Commands|$ nix-build -j0 blah}}


Line 244: Line 251:


== See also ==
== See also ==
* [https://github.com/NixOS/nix/blob/master/tests/remote-builds.nix#L46-L58 The NixOS Remote Builds Test Case]
* [https://github.com/NixOS/nix/blob/a6e6da3b0c579fc540acb00748fe3fd1858b9d99/tests/nixos/remote-builds.nix#L11-L21 The NixOS Remote Builds Test Case]
* [https://nixos.org/nix-dev/2015-September/018255.html Mail to nixos-dev about setting up remote builds by Russell O'Connor]
* [https://nixos.org/nix-dev/2015-September/018255.html Mail to nixos-dev about setting up remote builds by Russell O'Connor]
* [https://gist.github.com/danbst/09c3f6cd235ae11ccd03215d4542f7e7 A step-by-step guide on remote Firefox building through bastion host]
* [https://gist.github.com/danbst/09c3f6cd235ae11ccd03215d4542f7e7 A step-by-step guide on remote Firefox building through bastion host]