Binary Cache: Difference between revisions

imported>Tfc
Incorporate musicmatze
imported>Mth
No edit summary
Line 1: Line 1:
Every machine with nix installed can be a configured to be a binary cache for another nix machine - no matter if it is a NixOS, other Linux distro, or MacOS machine.
A binary cache builds Nix packages and caches the result for other machines. Any machine with Nix installed can be a binary cache for another one, no matter the operating system.


== Setting up a NixOS Machine as Binary Cache for Others ==
== Setting up a binary cache ==


This tutorial assumes:
This tutorial explains how to setup a server running NixOS as a binary cache for other machines, serving the store on TCP port 80 with signing turned on. It assumes that an {{ic|[[nginx]]}} service is already running, that port 80 is open,<ref group="cf."> {{manual:nixos|sec=#sec-firewall|chapter=11.5. Firewall}}</ref> and that the hostname {{ic|binarycache.example.com}} resolves to the server.<ref group="cf.">{{nixos:option|networking.hostName}}</ref>


* NixOS on the serving machine
=== 1. Generating a private/public keypair ===
* You want to serve the nix store via port 80 and already have an nginx service running (See here how to configure nginx [https://nixos.wiki/wiki/Nginx])
* The store is served with signing activated
* Firewall rules (port 80) are already set up (See firewall settings in NixOS manual[https://nixos.org/nixos/manual/index.html#sec-firewall])
* The hostname "binarycache.mydomain.com" points to the server (see <code>networking.hostName</code>[https://nixos.org/nixos/manual/options.html#opt-networking.hostName])


This tutorial explains the following steps one by one in the following:
A keypair is necessary to sign Nix packages.


# Generate a private/public keypair for signing packages
{{bc|
#* This step is not mandatory, but we are going to serve signed nix packages
$ nix-store --generate-binary-cache-key binarycache.example.com cache-priv-key.pem cache-pub-key.pem
# Activate <code>nix-serve</code>
# mv cache-priv-key.pem /var/cache-priv-key.pem
#* This is the service that speaks the binary cache protocol via HTTP.  
# chown nix-store /var/cache-priv-key.pem
#* It will use the private key to sign the packages
# chmod 600 /var/cache-priv-key.pem
# Create a virtual hostname in <code>nginx</code>
}}
#* It will redirect the HTTP(s) traffic from port 80 to <code>nix-serve</code>
# Rebuild the NixOS config and test


=== 1. Generate a private/public keypair ===
It is important that only {{ic|nix-serve}} can access the private key.
The location {{ic|/var/cache-priv-key.pem}} is just an example.


<syntaxhighlight lang="bash">
=== 2. Activating {{ic|nix-serve}} ===
$ nix-store --generate-binary-cache-key binarycache.mydomain.com1 cache-priv-key.pem cache-pub-key.pem
$ sudo mv cache-priv-key.pem /var/cache-priv-key.pem
$ sudo chown nix-store /var/cache-priv-key.pem
$ sudo chmod 600 /var/cache-priv-key.pem
</syntaxhighlight>


It is important that only <code>nix-serve</code> can access the private key.
{{ic|nix-serve}} is the service that speaks the binary cache protocol via HTTP.
The location <code>/var/cache-priv-key.pem</code> is just an example.
 
=== 2. Activate <code>nix-serve</code> ===


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 43: Line 30:
</syntaxhighlight>
</syntaxhighlight>


<code>nix-serve</code> will by default serve on port 5000. We are not going to open a firewall port for it, because we will let <code>nginx</code> redirect to it.
{{ic|nix-serve}} will by default serve on port 5000. We are not going to open a firewall port for it, because we will let {{ic|nginx}} redirect to it.


=== 3. Create a virtual hostname in <code>nginx</code> ===
=== 3. Creating a virtual hostname in {{ic|nginx}} ===
 
We redirect the HTTP(s) traffic from port 80 to {{ic|nix-serve}}.


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 52: Line 41:
   virtualHosts = {
   virtualHosts = {
     # ... existing hosts config etc. ...
     # ... existing hosts config etc. ...
     "binarycache.mydomain.com" = {
     "binarycache.example.com" = {
       serverAliases = [ "binarycache" ];
       serverAliases = [ "binarycache" ];
       locations."/".extraConfig = ''
       locations."/".extraConfig = ''
Line 65: Line 54:
</syntaxhighlight>
</syntaxhighlight>


Add HTTPS settings to this config if possible. The tutorial will simply continue with unsecure HTTP. (See NixOS manual on how to set up HTTPS with letsencrypt[https://nixos.org/nixos/manual/index.html#module-security-acme-nginx])
Add HTTPS settings to this config if possible.<ref group="cf.">{{manual:nixos|sec=#module-security-acme-nginx|chapter=26.3. Using ACME certificates in Nginx}}</ref> This tutorial will simply continue with insecure HTTP.


=== 4. Rebuild the NixOS config and test ===
=== 4. Rebuilding and testing ===


<syntaxhighlight lang="bash">
{{bc|# nixos-rebuild switch}}
sudo nixos-rebuild switch
</syntaxhighlight>


Check the general availability:
Check the general availability:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ curl http://binarycache.mydomain.com/nix-cache-info
$ curl http://binarycache.example.com/nix-cache-info
StoreDir: /nix/store
StoreDir: /nix/store
WantMassQuery: 1
WantMassQuery: 1
Line 87: Line 74:
</syntaxhighlight>
</syntaxhighlight>


On some other machine, test if nix can realize the same package via the binary cache (the content of the <code>trusted-public-keys</code> is the content of the file <code>cache-pub-key.pem</code> which you should share with users of the binary cache!):
Next, with the public key that was generated to {{ic|cache-pub-key.pem}}, setup another machine to use the binary cache, and see if Nix successfully fetches the cached package.
 
== Using a binary cache ==
 
To configure Nix to use a certain binary cache, refer to the Nix manual.<ref group="cf.">[https://nixos.org/nix/manual/#ch-files Nix Manual, 21. Files]</ref> Add the binary cache as substituter (see the options {{ic|substituters}} and {{ic|extra-substituters}}) and the public key to the trusted keys (see {{ic|trusted-public-keys}}).
 
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
$ nix-store -r /nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10 --option substituters http://binarycache.mydomain.com --option trusted-public-keys binarycache.mydomain.com1:dsafdafDFW123fdasfa123124FADSAD
$ nix-store -r /nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10 --option substituters http://binarycache.example.com --option trusted-public-keys binarycache.example.com:dsafdafDFW123fdasfa123124FADSAD
these paths will be fetched (0.00 MiB download, 24.04 MiB unpacked):
these paths will be fetched (0.00 MiB download, 24.04 MiB unpacked):
   /nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27
   /nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27
   /nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10
   /nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10
copying path '/nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27' from 'http://binarycache.mydomain.com'...
copying path '/nix/store/7gx4kiv5m0i7d7qkixq2cwzbr10lvxwc-glibc-2.27' from 'http://binarycache.example.com'...
copying path '/nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10' from 'http://binarycache.mydomain.com'...
copying path '/nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10' from 'http://binarycache.example.com'...
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10
/nix/store/gdh8165b7rg4y53v64chjys7mbbw89f9-hello-2.10
</syntaxhighlight>
</syntaxhighlight>


It works, great! Now you can configure your nix machines to look up packages always/also on this server.
== See also ==
For that, have a look into the Nix manual [https://nixos.org/nix/manual/#name-11] and the following settings:


* substituters
<references group="cf."/>
* extra-substituters
* trusted-public-keys