Root cause of the NFS shares never mounting on lxc-docker, found by live-diagnosing the redeployed VMID 105 container after the earlier DNS/FQDN fix (#25, already merged) landed but shares still didn't mount.
The kernel's NFS client filesystem doesn't set FS_USERNS_MOUNT, so mounting NFS from inside any non-init user namespace -- exactly what an unprivileged LXC container's UID-mapped root runs in -- is rejected at the VFS layer with EPERM, regardless of Proxmox's mount=nfs;nfs4 container feature (which only patches the AppArmor layer, confirmed by reading PVE::LXC::make_apparmor_config directly on the node). Confirmed live: TCP to the NFS server's port 2049 succeeds, the server's export table (192.168.2.0/24) matches the container's current IP, and mount.nfs: Operation not permitted fires immediately with no corresponding denial anywhere in the server's own logs -- a kernel-level rejection that no amount of DNS/automount/export tweaking could ever fix.
Fix:modules/platforms/lxc.nix now keys proxmoxLXC.privileged off hostName ("docker" -> true) instead of a blanket false, since modules/build-types/docker.nix is also composed for linode-docker/proxmox-docker, which don't import proxmox-lxc.nix at all -- setting this option there would break their eval. create-proxmox-resource.sh now reads the value back via a new flake_target_lxc_privileged helper instead of hardcoding --unprivileged 1, so the two stay in sync automatically for every lxc-* target.
Validated: nix eval confirms proxmoxLXC.privileged is true only for lxc-docker and false for every other lxc-* target (server/gui/minimal/nix-cache/pxe-boot/tailscale-exit-node/tor-relay), and every affected target's config.system.build.toplevel evaluates cleanly.
Deploy note: privilege level is set at container-creation time, not something a NixOS rebuild alone can change -- VMID 105 will need to be recreated via create-proxmox-resource.sh (which will now correctly pass --unprivileged 0 for this target) rather than just rebuilt in place.
Root cause of the NFS shares never mounting on lxc-docker, found by live-diagnosing the redeployed VMID 105 container after the earlier DNS/FQDN fix (#25, already merged) landed but shares still didn't mount.
The kernel's NFS client filesystem doesn't set `FS_USERNS_MOUNT`, so mounting NFS from inside any non-init user namespace -- exactly what an unprivileged LXC container's UID-mapped root runs in -- is rejected at the VFS layer with `EPERM`, regardless of Proxmox's `mount=nfs;nfs4` container feature (which only patches the AppArmor layer, confirmed by reading `PVE::LXC::make_apparmor_config` directly on the node). Confirmed live: TCP to the NFS server's port 2049 succeeds, the server's export table (`192.168.2.0/24`) matches the container's current IP, and `mount.nfs: Operation not permitted` fires immediately with no corresponding denial anywhere in the server's own logs -- a kernel-level rejection that no amount of DNS/automount/export tweaking could ever fix.
**Fix:** `modules/platforms/lxc.nix` now keys `proxmoxLXC.privileged` off `hostName` (`"docker"` -> `true`) instead of a blanket `false`, since `modules/build-types/docker.nix` is also composed for `linode-docker`/`proxmox-docker`, which don't import `proxmox-lxc.nix` at all -- setting this option there would break their eval. `create-proxmox-resource.sh` now reads the value back via a new `flake_target_lxc_privileged` helper instead of hardcoding `--unprivileged 1`, so the two stay in sync automatically for every `lxc-*` target.
Validated: `nix eval` confirms `proxmoxLXC.privileged` is `true` only for `lxc-docker` and `false` for every other `lxc-*` target (server/gui/minimal/nix-cache/pxe-boot/tailscale-exit-node/tor-relay), and every affected target's `config.system.build.toplevel` evaluates cleanly.
**Deploy note:** privilege level is set at container-creation time, not something a NixOS rebuild alone can change -- VMID 105 will need to be recreated via `create-proxmox-resource.sh` (which will now correctly pass `--unprivileged 0` for this target) rather than just rebuilt in place.
The kernel's NFS client filesystem doesn't set FS_USERNS_MOUNT, so mounting
NFS from inside any non-init user namespace -- exactly what an unprivileged
LXC container's UID-mapped root runs in -- is rejected at the VFS layer
with EPERM, regardless of Proxmox's mount=nfs;nfs4 container feature (which
only patches the AppArmor layer). Confirmed live on the redeployed lxc-docker
container: TCP to the NFS server's port 2049 succeeds, the server's export
table matches the container's IP, and mount.nfs: Operation not permitted
still fires immediately with no corresponding denial anywhere in the
server's own logs -- a kernel-level rejection that no amount of DNS/
automount/export tweaking (this branch's earlier commits) could ever fix.
modules/platforms/lxc.nix now keys proxmoxLXC.privileged off hostName
("docker" -> true) rather than a blanket false, since build-types/docker.nix
is also composed for linode-docker/proxmox-docker, which don't import
proxmox-lxc.nix at all -- setting this option there would break their eval.
create-proxmox-resource.sh reads the value back via a new
flake_target_lxc_privileged helper instead of hardcoding --unprivileged 1,
so the two stay in sync automatically for every lxc-* target.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T48qgH3VTvs8wvwj44FEbE
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Root cause of the NFS shares never mounting on lxc-docker, found by live-diagnosing the redeployed VMID 105 container after the earlier DNS/FQDN fix (#25, already merged) landed but shares still didn't mount.
The kernel's NFS client filesystem doesn't set
FS_USERNS_MOUNT, so mounting NFS from inside any non-init user namespace -- exactly what an unprivileged LXC container's UID-mapped root runs in -- is rejected at the VFS layer withEPERM, regardless of Proxmox'smount=nfs;nfs4container feature (which only patches the AppArmor layer, confirmed by readingPVE::LXC::make_apparmor_configdirectly on the node). Confirmed live: TCP to the NFS server's port 2049 succeeds, the server's export table (192.168.2.0/24) matches the container's current IP, andmount.nfs: Operation not permittedfires immediately with no corresponding denial anywhere in the server's own logs -- a kernel-level rejection that no amount of DNS/automount/export tweaking could ever fix.Fix:
modules/platforms/lxc.nixnow keysproxmoxLXC.privilegedoffhostName("docker"->true) instead of a blanketfalse, sincemodules/build-types/docker.nixis also composed forlinode-docker/proxmox-docker, which don't importproxmox-lxc.nixat all -- setting this option there would break their eval.create-proxmox-resource.shnow reads the value back via a newflake_target_lxc_privilegedhelper instead of hardcoding--unprivileged 1, so the two stay in sync automatically for everylxc-*target.Validated:
nix evalconfirmsproxmoxLXC.privilegedistrueonly forlxc-dockerandfalsefor every otherlxc-*target (server/gui/minimal/nix-cache/pxe-boot/tailscale-exit-node/tor-relay), and every affected target'sconfig.system.build.toplevelevaluates cleanly.Deploy note: privilege level is set at container-creation time, not something a NixOS rebuild alone can change -- VMID 105 will need to be recreated via
create-proxmox-resource.sh(which will now correctly pass--unprivileged 0for this target) rather than just rebuilt in place.The kernel's NFS client filesystem doesn't set FS_USERNS_MOUNT, so mounting NFS from inside any non-init user namespace -- exactly what an unprivileged LXC container's UID-mapped root runs in -- is rejected at the VFS layer with EPERM, regardless of Proxmox's mount=nfs;nfs4 container feature (which only patches the AppArmor layer). Confirmed live on the redeployed lxc-docker container: TCP to the NFS server's port 2049 succeeds, the server's export table matches the container's IP, and mount.nfs: Operation not permitted still fires immediately with no corresponding denial anywhere in the server's own logs -- a kernel-level rejection that no amount of DNS/ automount/export tweaking (this branch's earlier commits) could ever fix. modules/platforms/lxc.nix now keys proxmoxLXC.privileged off hostName ("docker" -> true) rather than a blanket false, since build-types/docker.nix is also composed for linode-docker/proxmox-docker, which don't import proxmox-lxc.nix at all -- setting this option there would break their eval. create-proxmox-resource.sh reads the value back via a new flake_target_lxc_privileged helper instead of hardcoding --unprivileged 1, so the two stay in sync automatically for every lxc-* target. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T48qgH3VTvs8wvwj44FEbE