Appearance
🔐 LXC Storage Sharing & UID/GID Mapping
Storage sharing across unprivileged LXC containers on PVE-1 does not rely on slow network file systems (NFS/CIFS). Instead, it uses direct host ZFS Bind Mounts paired with POSIX ACLs.
🧩 How Unprivileged LXC ID Mapping Works
Proxmox unprivileged containers isolate root and users by shifting container IDs into an unprivileged namespace starting at 100000 on the host:
$$\text{Host ID} = 100000 + \text{Container ID}$$
| Entity | Container ID (Inside LXC) | Host ID (On PVE-1 Host) | Account Name / Purpose |
|---|---|---|---|
| Container Root | UID 0 / GID 0 | UID 100000 / GID 100000 | Unprivileged root |
Standard User (rayman-ssh) | UID 1000 / GID 1000 (or 1001) | UID 101000 (or 101001) | Primary admin/docker user |
Standard User (admin-ssh) | UID 1001 / GID 1001 (or 1000) | UID 101001 (or 101000) | Secondary admin user |
| Shared Storage Group | GID 10000 | GID 110000 | nas_shares group |
👥 Dual-User Access Policy (rayman-ssh & admin-ssh)
IMPORTANT
Operational Requirement: Both rayman-ssh AND admin-ssh must have full rwx permissions across all files and folders in /mnt/media_root.
Because UID 1000 vs 1001 varies between containers (e.g. rayman-ssh is UID 1000 on docker-media but UID 1001 on docker-edge and docker-admin), permissions cannot rely on file ownership (USER_OBJ). Full dual-user access is guaranteed by:
- Giving both users membership in group
nas_shares(GID 10000). - The POSIX ACL on
tank/media_rootwhich grantsGROUP:110000:rwxon access and default inheritance.
📜 POSIX ACL Implementation
On the PVE-1 host, tank/media_root has default and access POSIX ACLs configured:
text
system.posix_acl_access:
USER_OBJ::rwx
USER:<smbuser_uid_on_host>:rwx
USER:<nfsuser_uid_on_host>:rwx
GROUP_OBJ::rwx
GROUP:110000:rwx <--- Maps to GID 10000 inside unprivileged LXCs (nas_shares)
MASK::rwx
OTHER::r-x
system.posix_acl_default:
USER_OBJ::rwx
USER:<smbuser_uid_on_host>:rwx
USER:<nfsuser_uid_on_host>:rwx
GROUP_OBJ::rwx
GROUP:110000:rwx <--- Automatically inherited by all newly created files & directories
MASK::rwx
OTHER::r-xApplying Host ACLs
To apply or restore these ACL permissions recursively on PVE-1:
bash
# On PVE-1 Host:
setfacl -R -m u:100000:rwx,d:u:100000:rwx,g:110000:rwx,d:g:110000:rwx /tank/media_root⚠️ LXC GID Consistency Note
- Inside an unprivileged LXC,
nas_sharesmust always be GID10000(which maps to host110000). - If an LXC mistakenly set
sudo groupmod -g 110000 nas_shares, inside the unprivileged container that maps to host GID210000, losing the group ACL pass-through. - Always verify that
getent group nas_sharesreports GID10000.
Container Verification Commands
Inside any LXC guest:
bash
# 1. Verify GID is 10000:
getent group nas_shares
# 2. Add users to nas_shares:
sudo usermod -aG nas_shares rayman-ssh
sudo usermod -aG nas_shares admin-ssh
# 3. Test write access:
touch /mnt/media_root/test_rw && rm /mnt/media_root/test_rw