Read-only NFS exports let a Linux server publish shared files while preventing clients from changing the exported path. They fit installer mirrors, reports, reference data, and other content that should be consumed from many hosts but updated only on the server.

Linux NFS servers load export rules from /etc/exports and from files ending in .exports under /etc/exports.d. The ro option denies write operations through the export, while exportfs loads the saved rule into the active export table that clients actually use.

Server-side ownership still controls which files exist and who can update them locally. After the rule is loaded, a client-side smoke test should show one readable file and one denied write from a host allowed by the selector.

Steps to create a read-only NFS export:

  1. Open a shell on the NFS server with an account that can use sudo.
  2. Create the server directory for the shared read-only content.
    $ sudo install -d -o root -g root -m 0755 /srv/nfs/projects

    Replace /srv/nfs/projects with the directory clients should read. Add or update files from the server side before relying on the export; clients will not be able to write through this rule.

  3. Create the export drop-in directory.
    $ sudo install -d -o root -g root -m 0755 /etc/exports.d

    exportfs reads files in /etc/exports.d only when their names end with .exports.

  4. Open the export definition file.
    $ sudoedit /etc/exports.d/projects.exports
  5. Add the read-only export rule.
    /srv/nfs/projects 192.0.2.0/24(ro,sync,no_subtree_check,root_squash)

    Keep no whitespace between the client selector and its option list. 192.0.2.0/24(ro,sync) applies those options to that subnet, while 192.0.2.0/24 (ro,sync) changes how exports(5) parses the rule.

  6. Review the client selector before loading the export.

    Use a specific host, subnet, or netgroup instead of * unless every reachable client is allowed to read the content.

  7. Reload the active export table from the saved files.
    $ sudo exportfs -rv
    exporting 192.0.2.0/24:/srv/nfs/projects

    exportfs -r reconciles the active table with saved export files, including option changes and removed entries.

  8. Verify that the active export includes ro for the intended selector.
    $ sudo exportfs -v
    /srv/nfs/projects
    		192.0.2.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,ro,root_squash,no_all_squash)

    exportfs may show defaults such as wdelay, hide, sec=sys, and no_all_squash in addition to the options saved in the file.

  9. Confirm the NFS server unit is active.
    $ sudo systemctl is-active nfs-server
    active

    On current Ubuntu packages, nfs-kernel-server.service is an alias for nfs-server.service.

  10. Create the client mount point on an allowed Linux client.
    $ sudo mkdir --parents /mnt/projects

    Files already inside /mnt/projects become hidden while the NFS filesystem is mounted there.

  11. Mount the export from the allowed client.
    $ sudo mount -t nfs4 files.example.net:/srv/nfs/projects /mnt/projects

    Replace files.example.net with the NFS server name. The client must match the host, subnet, or netgroup used in the export rule.

  12. Verify that the client mounted the expected source.
    $ findmnt -o TARGET,SOURCE,FSTYPE /mnt/projects
    TARGET        SOURCE                               FSTYPE
    /mnt/projects files.example.net:/srv/nfs/projects nfs4
  13. Read a known file from the mounted export.
    $ cat /mnt/projects/README.txt
    reference build

    Use a file that should already exist in the exported directory. A successful read proves the client can consume the shared content.

  14. Confirm that a client write fails.
    $ touch /mnt/projects/client-write-test
    touch: cannot touch '/mnt/projects/client-write-test': Read-only file system

    The write denial is expected for an export loaded with ro. If the command succeeds, check whether the client mounted a different path or whether the active export table still shows rw.

  15. Unmount the temporary client test mount.
    $ sudo umount /mnt/projects