Skip to content

14 - NFS Setup

Date: 2026-02-11 Updated: 2026-04-08 (replace SSHFS automount with systemd service) Updated: 2026-08-11 (add Windows SMB client section) Hostname: pve IP address: 192.168.0.109


Overview

NFS is used in both directions:

  • Proxmox → LAN: exports the media storage pool so Nobara (and others) can mount it
  • Nobara → Proxmox: exports a backup HDD so Proxmox can rsync LXC backups onto it

The Windows side of the dual-boot machine uses SMB instead - see Windows Client (SMB) below.


Proxmox as NFS Server

Proxmox exports its storage to the local network.

Install NFS server

apt update
apt install nfs-kernel-server

/etc/exports

/mnt/storage 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash,fsid=1)
/mnt/disk1 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash,fsid=2)
/mnt/disk2 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash,fsid=3)
/mnt/disk3 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash,fsid=4)
/mnt/disk4 192.168.0.0/24(rw,sync,no_subtree_check,no_root_squash,fsid=5)

Apply and verify

exportfs -a
systemctl restart nfs-server
exportfs -v

Enable NFS server at boot

systemctl enable nfs-server

Note: the service name is nfs-server (not nfs-kernel-server) on recent Debian/Proxmox versions.


Nobara PC as NFS Server (backup target)

Nobara exports its backup HDD so Proxmox can rsync LXC dump files onto it.

Nobara /etc/exports

/mnt/hdd/Backup 192.168.0.109(rw,sync,no_subtree_check,no_root_squash)

Only the Proxmox host (192.168.0.109) has access - not the whole LAN.

Apply on Nobara

sudo exportfs -ra

Proxmox mounts it in /etc/fstab

192.168.0.100:/mnt/hdd/Backup /mnt/pve/nobara-backup nfs soft,timeo=30,retrans=3,_netdev,x-systemd.automount 0 0
  • soft + timeo=30 + retrans=3 - times out gracefully if Nobara is offline, does not freeze Proxmox
  • x-systemd.automount - mounts on first access, not at boot

Nobara as NFS Client (mounts Proxmox storage)

Do not use /etc/fstab for these mounts. Hard fstab NFS entries freeze Nobara's boot if Proxmox is offline. Use systemd automount instead.

Install NFS client on Nobara

sudo dnf install nfs-utils

Create mount points

sudo mkdir -p /mnt/storage /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4

Create systemd mount + automount units

Run as root (sudo -i) to avoid heredoc indentation issues:

for share in storage disk1 disk2 disk3 disk4; do
cat > /etc/systemd/system/mnt-${share}.mount << EOF
[Unit]
Description=NFS /mnt/${share} from Proxmox
After=network-online.target
Wants=network-online.target

[Mount]
What=192.168.0.109:/mnt/${share}
Where=/mnt/${share}
Type=nfs
Options=noauto,nfsvers=4,soft,timeo=30,retrans=3,_netdev

[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/mnt-${share}.automount << EOF
[Unit]
Description=Automount /mnt/${share}

[Automount]
Where=/mnt/${share}
TimeoutIdleSec=600

[Install]
WantedBy=multi-user.target
EOF
done

Enable and start

systemctl daemon-reload
systemctl enable --now mnt-storage.automount mnt-disk1.automount mnt-disk2.automount mnt-disk3.automount mnt-disk4.automount

Verify

ls /mnt/storage
df -h | grep mnt/

The first ls triggers the automount. All 5 shares should appear in df -h.

How it works

  • The .automount unit watches the directory
  • First access triggers the mount automatically
  • After 600 seconds (10 min) of inactivity it unmounts
  • If Proxmox is offline: soft + timeo=30 + retrans=3 means mount attempt times out after ~90 seconds - Nobara does not freeze

Nobara SSHFS Mount (LXC 109 claude-mgmt)

Nobara mounts /root from LXC 109 (claude-mgmt) via SSHFS. NFS server cannot run inside an unprivileged LXC, so SSHFS is used instead.

Prerequisites

Root's SSH key on Nobara must be in LXC 109's authorized_keys. Since LXC 109 has password auth disabled, add it via the existing user key:

sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N ""
sudo cat /root/.ssh/id_ed25519.pub | ssh root@192.168.0.204 "cat >> /root/.ssh/authorized_keys"

Also add LXC 109 to root's known_hosts on Nobara:

sudo ssh-keyscan 192.168.0.204 | sudo tee -a /root/.ssh/known_hosts

Create mount point

sudo mkdir -p /mnt/claudemgmt

Note: no hyphen in claudemgmt - systemd unit file names encode hyphens as \x2d which causes shell escaping issues.

Create systemd service

A service unit is used instead of mount+automount. The automount approach caused Dolphin and the KDE desktop to lag/freeze for up to 15 seconds on each access attempt when LXC 109 was offline (the mount unit blocked D-Bus via systemd-hostnamed). The service approach with reconnect mounts once and maintains the connection in the background.

sudo tee /etc/systemd/system/mnt-claudemgmt.service << 'EOF'
[Unit]
Description=SSHFS /root from LXC 109 claude-mgmt
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStartPre=/bin/bash -c 'ssh -o ConnectTimeout=3 -o BatchMode=yes root@192.168.0.204 exit 2>/dev/null'
ExecStart=/usr/bin/sshfs root@192.168.0.204:/root /mnt/claudemgmt \
    -f \
    -o allow_other \
    -o IdentityFile=/home/nex/.ssh/id_ed25519 \
    -o reconnect \
    -o ServerAliveInterval=5 \
    -o ServerAliveCountMax=2
ExecStop=/bin/fusermount3 -u /mnt/claudemgmt
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
EOF

Enable and start

sudo systemctl daemon-reload
sudo systemctl enable --now mnt-claudemgmt.service
ls /mnt/claudemgmt

Should show: homelab learning youtube

How it works

  • At boot: ExecStartPre checks SSH connectivity (3s timeout). If LXC 109 is down, fails fast and retries every 30 seconds.
  • When connected: SSHFS runs in foreground (-f), systemd owns the process.
  • If LXC 109 goes down: reconnect + ServerAliveInterval=5, ServerAliveCountMax=2 detects the drop in 10 seconds, retries in background. File accesses return I/O errors immediately - no desktop freeze.
  • When LXC 109 comes back: reconnect re-establishes automatically, no manual intervention needed.
  • If reconnect gives up: process exits, Restart=on-failure restarts the service after 30 seconds.

Windows Client (SMB)

The dual-boot desktop (192.168.0.100) reaches the same storage over SMB when booted to Windows, not over NFS.

Why SMB and not NFS

The Windows "Client for NFS" is an optional feature, speaks NFSv2/v3 only, and has no real UID mapping - every write lands as an anonymous UID unless you set AnonymousUid/AnonymousGid in the registry. Samba was already running on the Proxmox host, so the Windows side needed no new server component at all.

Shares on the Proxmox host

Defined in /etc/samba/smb.conf:

Share Path Access
Storage /mnt/storage smbuser, normal permissions
Media /mnt/storage/media smbuser, normal permissions
Downloads /mnt/storage/media/downloads smbuser, normal permissions
AllDisks /mnt smbuser, runs as root - full access everywhere

The AllDisks share

The default shares cannot write everywhere: /mnt/storage itself is root:root 755, and the immich/ and syncthing/ subtrees are owned by UID 100000/101000 because unprivileged LXCs use a +100000 offset. AllDisks solves this by running as root:

[AllDisks]
   comment = All Disks (disk1-4, storage) - full access
   path = /mnt
   browseable = yes
   read only = no
   valid users = @users
   force user = root
   force group = root
   inherit owner = unix only
   create mask = 0664
   directory mask = 0775

inherit owner = unix only is the part that matters. Without it, everything created from Windows would be owned by host root, which appears as nobody inside an unprivileged container - the Immich and Syncthing containers could then read but not modify their own files. With it, new files inherit the parent directory's owner, so container-owned subtrees stay container-owned.

This is a root-equivalent share. Anyone who can authenticate as smbuser can overwrite or delete anything under /mnt, including .snapraid.content. It is LAN-only and guest access is denied (valid users blocks the map to guest = bad user fallback).

Mounting from Windows

In an Administrator prompt:

net use Z: \\192.168.0.109\AllDisks /user:smbuser <password> /persistent:yes

The password is not in this repository - it is in private/.env, which is gitignored. The same smbuser account is used by the Home Assistant backup job writing to \\192.168.0.109\Storage\backup\proxmox, so resetting it with smbpasswd -a smbuser requires updating the HA side too, or those backups fail silently.

To store the credential separately instead of passing it inline:

cmdkey /add:192.168.0.109 /user:smbuser /pass:<password>
net use Z: \\192.168.0.109\AllDisks /persistent:yes

If net use still prompts for a username after cmdkey, the stored credential was rejected - Windows falls back to prompting rather than reporting the failure. Clear it with cmdkey /delete:192.168.0.109 and verify the password from the Proxmox host before retrying:

smbclient //192.168.0.109/AllDisks -U "smbuser%<password>" -c "ls"

NT_STATUS_LOGON_FAILURE there means the password is wrong. To rule out a disabled account rather than a bad password, check the flags - [U] is a normal enabled user, [D] is disabled:

pdbedit -L -v smbuser | grep -i flags

Applying smb.conf changes

smbd re-reads smb.conf when a client opens a new connection, so a share edit takes effect on the next mount without a restart. systemctl reload smbd only matters for sessions that are already open. Validate first:

testparm -s

Notes

  • fsid= is required for non-root filesystem exports on Proxmox
  • no_root_squash allows root access from the client
  • Nobara runs NFSv4 only (no rpcbind) - showmount -e will fail from Proxmox, but mounts work fine
  • Nobara is not always on - the soft mount on Proxmox ensures it never freezes the host
  • If NFS shares stop working after a Proxmox reboot: check systemctl status nfs-server on the Proxmox host - it may need systemctl start nfs-server
  • Automount units must not have After=network-online.target - this creates an ordering cycle with local-fs.target on Fedora/Nobara and causes the unit to silently fail at boot. Network dependency belongs only in the .mount unit, not the .automount unit. Access-triggered automounts work correctly without it since the network is already up when the user first accesses the path.