Using NFS to provide extra disk to a Raspberry PI

As the Raspberry PI uses an SD Card for it’s boot device there are times when you need either more space than is available on that device or a device that’s faster – writing to flash is slow and flash cards do have a limited number of writes that can be made to them.

Now there’s several ways to accomplish this:

  • Use an external USB drive (the common route)
  • Use a network shared drive

Using a USB drive is simple and is the faster option but it means it’s dedicated to the PI whilst it’s in use, hence this article on using a network drive – in this instance a directory on another Linux box in the network.

Also having it shared on the network means that multiple machines could use it at the same time. Imagine if you are a teacher with a collection of PI’s being used by your students. You could setup a central read-only directory with your class work which they can all access as if it’s installed locally.

Our aims

For this article I’m going to show how to setup a directory on a server and the raspberry pi as the client.

  • tabitha – Ubuntu server that will host the directory
  • lindesfarne – Raspberry PI client running the stock Debian SD Image
  • kell – second Raspberry PI client also running Debian.

Although the examples will show tabitha and lindesfarne at the end I’ll also show how to copy files between two Raspberry PI’s via the share, kell being the second pi.

Also although I’m using a linux box in this setup if you wanted to use a PI as the server (sharing a usb drive for example) then it’s exactly the same.

Setting up the server

First I presume you are running a current Linux distribution. In this example I’m setting this up on a machine running Ubuntu but these instructions will work on Linux Mint or Debian as well.

First you need to pick a directory which you want to use as shared space. For the purpose of this article I’m going to use /srv/public

tabitha:~$ sudo mkdir -p /srv/public
tabitha:~$ sudo chmod 777 /srv/public

Now first we have to use sudo as /srv is under the root directory so only root can create it. Most distributions have a /srv directory already but the -p attribute means that mkdir will create it as well if it doesn’t exist.

Also the chmod is a cheat for this article – it means that any user can not just read but write to that directory. Normally you would limit it to a specific user or group but that’s outside the scope of this article.

Next we need to install the NFS server.

tabitha:~$ sudo apt-get install nfs-kernel-server nfs-common portmap

Now you may already have a couple of these installed but usually nfs-kernel-server isn’t installed by default.
Next you need to configure nfs by adding the directory to /etc/exports

tabitha:~$ sudo vi /etc/exports

and add the following line to the end of the file:


Now what this does is declare that the /srv/public directory is Read Write (rw) and it’s accessible by any machine within the local network – 192.168.2.x in my instance.

Now you could replace the nework definition with a * which means any machine but if it’s accessible from the public internet that’s not a good idea.

/srv/public *(rw,sync,no_subtree_check)

Alternatively you could specify a user name instead but this is a bit tricky to set unless your user’s are configured the same on both the server and the client.

/srv/public pi(rw,sync,no_subtree_check)

Now entries within ( ) are options specific to this share. common entries are:

  • rw : Allow clients to read as well as write access
  • ro : Read only access
  • insecure : Tells the NFS server to use unpriveledged ports (ports > 1024).
  • no_subtree_check : If the entire volume (/users) is exported, disabling this check will speed up transfers.
  • async : async will speed up transfers.

Now you just need to restart nfs-server:

tabitha:~$ sudo service nfs-kernel-server restart

Now your NFS sever is sharing /srv/public

Mounting the directory on the PI

Now we are going to mount this share on the PI.

First you need to install NFS. If you are using the standard Debian image then you have enough to mount nfs. If in doubt then simply install it as we did for the server – if it’s already there it will just tell you it’s already installed.

Next decide where to mount it. Now you can mount it anywhere you want but I’m going to use the same /srv/public location – an alternative location for example is /mnt/public.

First make the directory as you did on the server.

pi@lindesfarne:~$ sudo mkdir -p /srv/public
pi@lindesfarne:~$ sudo chmod 777 /srv/public

Next we’ll mount the share:

pi@lindesfarne:~$ sudo mount tabitha:/srv/public /srv/public

Here tabitha:/srv/public defines the server and the directory on the server whilst the /srv/public on the right is your local mount point. Now it should return almost immediately so next lets look at what we now have mounted:

pi@lindesfarne:~$ df -h
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                  94M     0   94M   0% /lib/init/rw
udev                   10M  180K  9.9M   2% /dev
mpfs                  94M     0   94M   0% /dev/shm
rootfs                1.6G  1.3G  257M  83% /
/dev/mmcblk0p1         75M   28M   47M  38% /boot
/dev/mmcblk0p4        2.0G   42M  1.8G   3% /home
tabitha:/srv/public   141G  5.8G  128G   5% /srv/public

Now the machine has 128Gb of space available to it under /srv/public

Right lets test it. First we’ll create a file on the server and see if we can read it on the PI.

peter@tabitha:~$ uname -nmo
tabitha i686 GNU/Linux
peter@tabitha:~$ uname -nmo >/srv/public/tabitha

Now can we read it:

pi@lindesfarne:~$ cat /srv/public/tabitha
tabitha i686 GNU/Linux

Now that one would always work as were reading so next we want to write from the client:

pi@lindesfarne:~$ uname -nmo
lindesfarne armv6l GNU/Linux
pi@lindesfarne:~$ uname -nmo >/srv/public/lindesfarne

And on the server?

peter@tabitha:~$ cat /srv/public/lindesfarne
lindesfarne armv6l GNU/Linux

Using the drive on more than one PI

Ok now to bring in the second pi (kell) and we will copy a file from lindesfarne to it via the share.

First follow the instructions for mounting the drive above on the second pi – you should now have both attached to the server.

Next select a file to copy. For this article we’ll create a dummy file but if you have another locally you could use that instead:

pi@lindesfarne:~$ ( uname -a;df -h) > dummy
pi@lindesfarne:~$ cat dummy
Linux lindesfarne 3.1.9+ #90 Wed Apr 18 18:23:05 BST 2012 armv6l GNU/Linux
Filesystem            Size  Used Avail Use% Mounted on
tmpfs                  94M     0   94M   0% /lib/init/rw
udev                   10M  180K  9.9M   2% /dev
tmpfs                  94M     0   94M   0% /dev/shm
rootfs                1.6G  1.3G  256M  83% /
/dev/mmcblk0p1         75M   28M   47M  38% /boot
/dev/mmcblk0p4        2.0G   42M  1.8G   3% /home
tabitha:/srv/public   141G  5.8G  128G   5% /srv/public

Next copy it to the drive & on the second pi copy it into the home directory

pi@lindesfarne:~$ cp dummy /srv/public/dummy
pi@kell:~$ cp /srv/public/dummy

That’s it. View that file and you should see it’s exactly the same.

Unmounting the drive

If you want to unmount the drive then it’s simply a case of:

pi@lindesfarne:~$ sudo umount /srv/public

Mounting the drive on boot

Now this article shows how to mount the drive on the pi – but what if you want to mount it automatically every time you want to boot?

Well all you need to do is to add an entry to /etc/fstab

pi$lindesfarne:~$ sudo vi /etc/fstab

And add the following entry at the end of the file:

tabitha:/srv/public /srv/public nfs defaults 0 0

Thats it. The next time you reboot the pi it will automatically mount that drive.

Personally for the pi’s I leave that out and manually mount it – simply because I might be doing something else with the pi – possibly not connected to the network, but that’s how to do it.

18 thoughts on “Using NFS to provide extra disk to a Raspberry PI

  1. I have two Pis and have one as a server for developing program’s for the second to use.
    I tried to install the nfs server files and was successful except the Pi told me it would install rpcbind instead of portmap.
    When I started the server it reported that it wouldn’t start because portmap permits not running.

    I am running the “wheezy” kernel.. Apt-get needed me to update before it was ok..

    Any thoughts ?


  2. I didn’t try installing the server on the PI but it might be something specific to wheezy – when I did it on the server it didn’t have a problem.

    Later this evening I’ll give it a go using both wheezy & raspian to see if I can replicate it.

  3. Thank you for this article, it’s well explained and can be understand by beginners, too!
    I found a type in two places that you may fix: /src/public instead of /srv/public.

  4. I have a server on my lan, placed the correct info in the /set/fstab and can manually mount the drive using “sudo mount -a”.

    I cannot figure out why it will not automatically mount this on boot. Is it a timing issue? My PI is using DHCP and i have its mac address associated with on my router and can reliably find it on that address. What is not set correctly that keeps it from mounting the nfs share at boot?

    When I parse the dmesg, it mounts root before it loads the ethernet module then remounts these devices:
    [ 14.895203] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
    [ 15.413996] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)
    There is no mention of the nfs during boot.

    What am I missing?


    1. Hmmm, interesting.

      I’ve just setup mimas (my development PI) to mount a public mount on my NAS, rebooted and it’s worked.

      All I did was:

      apt-get install nfs-common
      service rpcbind start
      mkdir /mnt/discovery

      Then added the following to /etc/fstab: /mnt/discovery nfs rw,_netdev,auto 0 0

      then mount -a and I saw the partition mounted:

      root@mimas:~# df -H /mnt/discovery
      Filesystem Size Used Avail Use% Mounted on 2.0T 6.8G 1.8T 1% /mnt/discovery

      Then I just did a reboot and once the pi came back then the partition was already there.

  5. I have nfs-common installed, rpcbind is running, my mount point is /tmp/motion

    My /etc/fstab line was this (based on a hint I found on the net): /tmp/motion nfs rsize=8192,wsize=8192,timeo=14,intr 0 0
    I tried yours: /tmp/motion nfs rw,_netdev,auto 0 0
    and get the same result. I can mount it with sudo mount -a, but it will not mount at boot.

    after booting df returns this:
    $ df
    Filesystem 1K-blocks Used Available Use% Mounted on
    rootfs 7579104 4231088 2963168 59% /
    /dev/root 7579104 4231088 2963168 59% /
    devtmpfs 110544 0 110544 0% /dev
    tmpfs 23764 560 23204 3% /run
    tmpfs 5120 0 5120 0% /run/lock
    tmpfs 47520 0 47520 0% /run/shm
    /dev/mmcblk0p1 57288 18544 38744 33% /boot
    $ sudo mount -a
    $ df
    Filesystem 1K-blocks Used Available Use% Mounted on
    rootfs 7579104 4231104 2963152 59% /
    /dev/root 7579104 4231104 2963152 59% /
    devtmpfs 110544 0 110544 0% /dev
    tmpfs 23764 560 23204 3% /run
    tmpfs 5120 0 5120 0% /run/lock
    tmpfs 47520 0 47520 0% /run/shm
    /dev/mmcblk0p1 57288 18544 38744 33% /boot 3824382144 742773824 3081608320 20% /tmp/motion

    Any ideas?

    1. It does sound like a timing issue…

      I’m wondering, is your dhcp responding fast enough or could that be delaying the network long enough?

      Like you I’m using dhcp for IPv4 networking (IPv6 is different) and it’s fine here but then the firewall which also has dhcp etc on it is pretty powerful so it could be your dhcp server being slow.

      One thing to try is to give your PI a static address & see if that helps. If it does then that’s a pointer, if not then I’m stumped.

      From a service point of view everything is up and running as mount -a works once the pi finishes booting.

  6. Still no joy with a static IP address. I need to figure out how to delay the nfs mount. THis is a v1 raspberry pi and I am using the ethernet interface.

  7. I have this set up on 3 pi’s. One as the server and two clients. I am able to see the contents of the folder on the client side, but i dont have write access. The server pi can write to files though. I have the proper ‘rw’ in the /etc/exports on the server

    Somthing else i am missing?

    1. It’s been a while (need to revisit this again soon myself though) but IIRC you have to add the rw mount option to the client as well, ether -o rw on the command line or add it to the column in /etc/fstab

      1. Thanks for the quick reply! I un-mounted it from the command line and tried
        sudo mount PiCL0:/srv/public /srv/public -o rw
        It again mounted the drive, but did not allow me access to write.
        Still missing somthing

      2. Sorry for the late reply… Looking at the config of one instance I have:

        sudo mount -t nfs -o rw,_netdev,auto server:/path /path

        That said _netdev & auto shouldn’t affect this. The only other thing it could be is permissions, the uid’s don’t match on the server & client.

        That said, I wrote this a couple of years ago so possibly something recent in Raspian has changed. I’ll be revisiting NFS on the PI again as I’m in the middle of setting up a PI based Docker cluster & I’ll need to have nfs working for that, so if it was a change I’ll soon find out.

    2. Still no luck, I noticed that all the files in that new drive belong to root, (and i did try sudo when attemping to edit or create a new file) but is it a permissions thing? should i create a group with all three user accounts and assign that folder to that group?

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s