NFS: Difference between revisions

From NixOS Wiki
imported>Garbas
mNo edit summary
imported>Patryk27
No edit summary
Line 2: Line 2:
== Server ==
== Server ==


The setup is very similar as it would be done in regular config file. I will use my setup as an example.
Let's say that we've got one server-machine with 4 directories that we want to share: <code>/mnt/kotomi</code>, <code>/mnt/mafuyu</code>, <code>/mnt/sen</code> and <code>/mnt/tomoyo</code>.


I wish to share 4 mount-points (/mnt/kotomi, /mnt/mafuyu, /mnt/sen, /mnt/tomoyo) with my other computers which will run NFS clients.
First, we have to create a dedicated directory from which our NFS server will access the data:


First I created a separate directory for NFS shares:
<syntaxhighlight lang="console">
$ mkdir /export
</syntaxhighlight>


<syntaxhighlight lang="console">$ mkdir /export</syntaxhighlight>
Then we have to either move our already-existing directories inside <code>/export</code> or bind-mount them there:
Then I mount (bind) the locations inside of /export from my config. Normally one would put it in /etc/fstab but nix generates that for us:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
Line 34: Line 35:
}
}
</syntaxhighlight>
</syntaxhighlight>
Next we have to tell nix how we want to export these and to whom:
 
Having the filesystem ready, we can proceed to configure our NFS server:


<syntaxhighlight lang="nix">{
<syntaxhighlight lang="nix">{
   services.nfs.server.enable = true;
   services.nfs.server.enable = true;
   services.nfs.server.exports = ''
   services.nfs.server.exports = ''
     /export                 192.168.1.10(rw,fsid=0,no_subtree_check) 192.168.1.15(rw,fsid=0,no_subtree_check)
     /export         192.168.1.10(rw,fsid=0,no_subtree_check) 192.168.1.15(rw,fsid=0,no_subtree_check)
     /export/kotomi         192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/kotomi 192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/mafuyu         192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/mafuyu 192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/sen             192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/sen     192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/tomoyo         192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
     /export/tomoyo 192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
   '';
   '';
}</syntaxhighlight>
}</syntaxhighlight>
Here I export all my bound shares to 2 local IPs. For various flags, you can check the [https://wiki.gentoo.org/wiki/NFSv4#Server Gentoo wiki NFSv4 article] which has a nice coverage.
This configuration exports all our shares to 2 local IPs; Gentoo's wiki has a great article [https://wiki.gentoo.org/wiki/NFSv4#Server Gentoo wiki NFSv4 article] that covers typical settings, so we won't repeat them here.


Other options are available on the [https://search.nixos.org/options?query=nfs NixOS option page] or via the <code>nixos-option</code> command
Other options are available on the [https://search.nixos.org/options?query=nfs NixOS option page] or via the <code>nixos-option</code> command.


Please remember that NixOS by default has a firewall turned on! Add rules to allow NFS traffic or switch it off if you don't need it.
If your server-machine has a firewall turned on (as NixOS does by default, for instance), don't forget to open appropriate ports; e.g. for NFSv4:
<syntaxhighlight lang="nix">
networking.firewall.allowedTCPPorts = [ 2049 ];
</syntaxhighlight>


== Client ==
== Client ==


Setting up the client is very easy. To follow from the server example, say I want to mount the now exposed ''tomoyo'' share on another box, call it ''server'', to ''/mnt/tomoyo''.
Continuing the server example, mounting the now-exposed ''tomoyo'' share on another box (on a client) is as simple as:


All I have to do is to put
<syntaxhighlight lang="nix">
 
{
<syntaxhighlight lang="nix">{
   fileSystems."/mnt/tomoyo" = {
   fileSystems."/mnt/tomoyo" = {
     device = "server:/tomoyo";
     device = "server:/tomoyo";
     fsType = "nfs";
     fsType = "nfs";
   };
   };
}</syntaxhighlight>
}
Note that clients see the exposed shares as if they were exposed at the root level: ''/export/foo'' becomes ''/foo'' when client is concerned with mounting it. Regular '''fileSystems''' options apply.
</syntaxhighlight>
Note that clients see exposed shares as if they were exposed at the root level - i.e. ''/export/foo'' becomes ''/foo'' (in the <code>device</code> option). Other, regular '''fileSystems''' options apply.
 
Tip: you can specify NFS version by adding the <code>"nfsvers="</code> option:
<syntaxhighlight lang="nix">
{
  fileSystems."/mnt/tomoyo" = {
    /* ... */
    options = [ "nfsvers=4.2" ];
  };
}
</syntaxhighlight>
 
Tip: by default, all shares will be mounted right when your machine starts - apart from being simply unwanted sometimes, this may also cause issues when your computer doesn't have a stable network connection or uses WiFi; you can fix this by telling systemd to mount your shares the first time they are ''accessed'' (instead of keeping them mounted at all times):
 
<syntaxhighlight lang="nix">
{
  fileSystems."/mnt/tomoyo" = {
    /* ... */
    options = ["x-systemd.automount" "noauto"];
  };
}
</syntaxhighlight>


If you experience trouble with NFS mounts failing on boot because the network is not ready, try adding the following line in your fileSystems mount definition:
Tip: you can also tell systemd to disconnect your NFS-client from the NFS-server when the directory has not been accessed for some time:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{
{
   # ...
   fileSystems."/mnt/tomoyo" = {
  options = ["x-systemd.automount" "noauto"];
    /* ... */
    options = ["x-systemd.idle-timeout=600"]; # disconnects after 10 minutes (i.e. 600 seconds)
  };
}
}
</syntaxhighlight>
</syntaxhighlight>
That way, the NFS mount action won't actually be performed until the first time the mountpoint is accessed.


== Nix store on NFS ==
== Nix store on NFS ==


In a single-user setup ('''not on Nixos''') the nix store can be also exported over NFS (common in HPC clusters) to share package over the networks. The only requirement is to also pass <code>local_lock=flock</code> or <code>local_lock=all</code> as mount option to allow the nix packages to take locks on modifications. Example entry in <code>fstab</code>:
In a single-user setup ('''not on Nixos''') the Nix store can be also exported over NFS (common in HPC clusters) to share package over the networks. The only requirement is to also pass <code>local_lock=flock</code> or <code>local_lock=all</code> as mount option to allow the nix packages to take locks on modifications. Example entry in <code>fstab</code>:


<syntaxhighlight lang="console"><host_or_ip>/nix /nix nfs nofail,x-systemd.device-timeout=4,local_lock=all 0 0</syntaxhighlight>
<syntaxhighlight lang="console"><host_or_ip>/nix /nix nfs nofail,x-systemd.device-timeout=4,local_lock=all 0 0</syntaxhighlight>

Revision as of 13:49, 17 October 2020

Server

Let's say that we've got one server-machine with 4 directories that we want to share: /mnt/kotomi, /mnt/mafuyu, /mnt/sen and /mnt/tomoyo.

First, we have to create a dedicated directory from which our NFS server will access the data:

$ mkdir /export

Then we have to either move our already-existing directories inside /export or bind-mount them there:

{
  fileSystems."/export/mafuyu" = {
    device = "/mnt/mafuyu";
    options = [ "bind" ];
  };

  fileSystems."/export/sen" = {
    device = "/mnt/sen";
    options = [ "bind" ];
  };

  fileSystems."/export/tomoyo" = {
    device = "/mnt/tomoyo";
    options = [ "bind" ];
  };

  fileSystems."/export/kotomi" = {
    device = "/mnt/kotomi";
    options = [ "bind" ];
  };
}

Having the filesystem ready, we can proceed to configure our NFS server:

{
  services.nfs.server.enable = true;
  services.nfs.server.exports = ''
    /export         192.168.1.10(rw,fsid=0,no_subtree_check) 192.168.1.15(rw,fsid=0,no_subtree_check)
    /export/kotomi  192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
    /export/mafuyu  192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
    /export/sen     192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
    /export/tomoyo  192.168.1.10(rw,nohide,insecure,no_subtree_check) 192.168.1.15(rw,nohide,insecure,no_subtree_check)
  '';
}

This configuration exports all our shares to 2 local IPs; Gentoo's wiki has a great article Gentoo wiki NFSv4 article that covers typical settings, so we won't repeat them here.

Other options are available on the NixOS option page or via the nixos-option command.

If your server-machine has a firewall turned on (as NixOS does by default, for instance), don't forget to open appropriate ports; e.g. for NFSv4:

networking.firewall.allowedTCPPorts = [ 2049 ];

Client

Continuing the server example, mounting the now-exposed tomoyo share on another box (on a client) is as simple as:

{
  fileSystems."/mnt/tomoyo" = {
    device = "server:/tomoyo";
    fsType = "nfs";
  };
}

Note that clients see exposed shares as if they were exposed at the root level - i.e. /export/foo becomes /foo (in the device option). Other, regular fileSystems options apply.

Tip: you can specify NFS version by adding the "nfsvers=" option:

{
  fileSystems."/mnt/tomoyo" = {
    /* ... */
    options = [ "nfsvers=4.2" ];
  };
}

Tip: by default, all shares will be mounted right when your machine starts - apart from being simply unwanted sometimes, this may also cause issues when your computer doesn't have a stable network connection or uses WiFi; you can fix this by telling systemd to mount your shares the first time they are accessed (instead of keeping them mounted at all times):

{
  fileSystems."/mnt/tomoyo" = {
    /* ... */
    options = ["x-systemd.automount" "noauto"];
  };
}

Tip: you can also tell systemd to disconnect your NFS-client from the NFS-server when the directory has not been accessed for some time:

{
  fileSystems."/mnt/tomoyo" = {
    /* ... */
    options = ["x-systemd.idle-timeout=600"]; # disconnects after 10 minutes (i.e. 600 seconds)
  };
}

Nix store on NFS

In a single-user setup (not on Nixos) the Nix store can be also exported over NFS (common in HPC clusters) to share package over the networks. The only requirement is to also pass local_lock=flock or local_lock=all as mount option to allow the nix packages to take locks on modifications. Example entry in fstab:

<host_or_ip>/nix /nix nfs nofail,x-systemd.device-timeout=4,local_lock=all 0 0