I’v experimented with all the permutations and my verdict: 100% ZFS on the host. Don’t run it inside the VM.
ZFS wants to talk to the disks directly. If you put it in a VM it’s sitting on a virtual disk, so it can’t see the hardware properly, and you end up with copy-on-write on top of copy-on-write.
My Proxmox box is ZFS root and that’s where all the real data lives. Each service gets its own dataset, rpool/sage//, which gets mounted into an LXC at /opt/services/-, and the Docker container mounts that. So it goes ZFS to LXC to container, and every service gets its own snapshots without the guest knowing ZFS exists. Sanoid runs recursively over rpool/sage, so new datasets get picked up on their own.
My other machines are bare metal linux boxes with a disposable root and OS and persistent data for services in the same ZFS layout. I backup all the config and .files. The important datasets snapshot locally and syncoid pushes to the Proxmox box every night.
For your setup:
VMs can’t bind mount datasets the way LXCs can. For a VM you’d use a zvol (whole-disk snapshots only) or virtiofs. I use virtuofs on my GPU VM (I pass the GPU through wholesale).
LXC is the easy way to get per-service snapshots.You just bind the mount for the dataset into the container. Irritatingly, you cant pass an empty root dataset, you have to pass each individual dataset in. All this forces you to manage the snapshots yourself - proxmox won’t snapshot and lxc with binds. And you need to be comfortable with making drive-access containers privileged.
Passing a whole NVMe to the VM works, but then the host and your second VM can’t use it. I wouldn’t bother unless that VM is basically your NAS.
If you want ZFS managed in Nix, honestly I’d skip Proxmox. Run NixOS on bare metal with ZFS set up in your config (sanoid and syncoid are both NixOS modules), and run VM 2 in libvirt on its own zvol. Same idea, ZFS on the host, and the whole thing lives in one config you can rebuild from.
It took a while to get here, but this system, for me at least, is totally seamless. Its definately overkill for 2 containers/VMs, hence the last paragraph, but leaves a lot of room to grow.