infra/docs/runbooks/nfs-prerequisites.md
Viktor Barzin fd0f4a0365 fix: restore tree dropped by 6d224861; land stem95su gdrive-sync (10m) [ci skip]
6d224861 came from a --no-checkout worktree whose empty index made the
commit drop every file except two. This restores 05b50d2b's full tree and
correctly adds stacks/stem95su/gdrive-sync.tf + the service-catalog stem95su
entry. Forward-only (parent=6d224861, no force-push); [ci skip] since the
live infra was never applied from the broken commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 08:45:33 +00:00

2.8 KiB

NFS Prerequisites for modules/kubernetes/nfs_volume

The nfs_volume Terraform module creates a PersistentVolume pointing at a path on the Proxmox NFS server (192.168.1.127). It does not create the underlying directory on the server.

If the path does not exist, the first pod that tries to mount the resulting PVC gets stuck in ContainerCreating with the kubelet event:

MountVolume.SetUp failed for volume "<name>" : mount failed: exit status 32
mount.nfs: mounting 192.168.1.127:/srv/nfs/<path> failed, reason given by
server: No such file or directory

Bootstrap before first apply

Before adding a new nfs_volume consumer (backup CronJob, data PV, etc.), create the export root on the PVE host:

# Replace <app> with the backup stack name, e.g. mailserver-backup,
# roundcube-backup, immich-backup, etc.
ssh root@192.168.1.127 'mkdir -p /srv/nfs/<app> && chmod 755 /srv/nfs/<app>'

# Confirm exports are live (no change to /etc/exports needed — `/srv/nfs`
# is already exported via the root entry in pve-nfs-exports).
ssh root@192.168.1.127 exportfs -v | grep '/srv/nfs\b'

/srv/nfs is exported with the root entry. Subdirectories inherit the export automatically; they just have to exist on disk.

Known consumers

Consumer NFS path Owning stack
mailserver-backup /srv/nfs/mailserver-backup stacks/mailserver/
roundcube-backup /srv/nfs/roundcube-backup stacks/mailserver/
mysql-backup /srv/nfs/mysql-backup stacks/dbaas/
postgresql-backup /srv/nfs/postgresql-backup stacks/dbaas/
vaultwarden-backup /srv/nfs/vaultwarden-backup stacks/vaultwarden/

Use grep -rn 'nfs_volume' infra/stacks/ to find all active consumers.

Why not auto-create?

Two options were considered for automating this:

  1. null_resource + local-exec SSH mkdir in the nfs_volume module — works but adds an SSH dependency to every Terraform run, makes the module non-hermetic, and fails if the operator does not have SSH to the PVE host.
  2. nfs-subdir-external-provisioner — handles subdirs automatically but changes the PV/PVC shape and would require migrating all existing consumers.

Neither is worth the churn for a one-time operation per new backup stack. Document + checklist is the current call; re-evaluate if we start adding one NFS consumer per week.

  • code-yo4 — this runbook
  • code-z26 — mailserver backup CronJob (first-time setup hit this)
  • code-1f6 — Roundcube backup CronJob (also hit this)