Every homelab needs centralized file storage. Windows machines need network shares for backups, media servers need a library location, and configuration files need a home you can reach from any device. Running a full NAS VM — TrueNAS, OMV, or Unraid — eats 4-8GB of RAM and adds unnecessary overhead for a container that only serves files.
The sweet spot is combining Samba inside a Proxmox LXC with a ZFS dataset passthrough. The LXC gives you near-native file I/O with sub-1GB RAM usage. ZFS provides data integrity, compression, and snapshot-based backups. Samba serves CIFS/SMB shares to any client on your network.
This guide walks through the complete setup: creating the LXC, passing through a ZFS dataset, configuring Samba for performance, and integrating with ZFS snapshots for backup.
Why LXC + Samba + ZFS Instead of a VM
The alternatives each make trade-offs that matter in a homelab:
- NAS VM (TrueNAS, OMV, Unraid) — Full OS kernel, 4-8GB RAM minimum, separate storage stack. Excellent features but heavy for a single-purpose file server.
- Docker Samba containers — dperson/samba or similar images. They work, but Docker’s networking adds translation overhead for CIFS, and bind-mounting ZFS datasets into Docker requires careful permission mapping. Kernel-level CIFS in an LXC outperforms containerized Samba by a measurable margin on sequential reads.
- Samba on the Proxmox host directly — Works, but violates the principle of isolating services from the hypervisor. Updates, reboots, or a config mistake can affect running VMs.
LXC hits the sweet spot: a full userspace with kernel-native SMB performance, 256MB-1GB RAM footprint, and complete isolation from the Proxmox host.
Prerequisites
- Proxmox VE 8.x or 9.x with a ZFS pool (e.g.,
tankorrpool/data) - Root or sudo access on the Proxmox host
- Debian 12 (bookworm) container template available locally
Verify your templates are downloaded:
|
|
If no Debian template exists, download one:
|
|
Step 1 — Create the LXC Container
Create a Debian 12 LXC with a static IP on your storage VLAN. Adjust the CTID, IP, and storage pool to match your environment:
|
|
Key flags explained:
--unprivileged 0— Creates a privileged LXC. Important for Samba + ZFS compatibility, discussed in detail below.--rootfs local-zfs:16— 16GB root filesystem on your ZFS storage pool. Your data dataset is separate.--memory 1024— 1GB RAM. Samba typically uses 200-400MB under load.
Start and enter the container:
|
|
Step 2 — Privileged vs Unprivileged LXC — The Right Choice for Samba
This is the most common question when setting up Samba in LXC. Here is the trade-off:
Unprivileged containers use UID/GID mapping (subuid/subgid) to isolate the container’s root from the host. This is more secure — a container breakout from root maps to a non-privileged user on the host. However, Samba’s interaction with ZFS ACLs and Windows permission models becomes painful. File ownership on passthrough ZFS datasets will show as nobody:nogroup unless you configure complex UID mappings. Windows ACLs (NTFS-style) are nearly impossible to maintain correctly.
Privileged containers run as root on the host. This is less isolated — a container compromise means host root. However, for Samba with ZFS passthrough, it “just works”:
- File ownership from the container maps directly to the ZFS dataset
- ZFS ACLs are natively supported
- Windows permission inheritance functions correctly
- No UID mapping headaches
The risk is manageable when you isolate the container on a storage-only VLAN (10.0.30.0/24 in this guide) and apply firewall rules.
If you must use unprivileged containers, you can work around UID mapping with lxc.idmap entries in the container config, but expect ongoing maintenance.
Step 3 — Create and Pass Through the ZFS Dataset
Back on the Proxmox host, create a dedicated ZFS dataset for your Samba data:
|
|
Mount the dataset into the LXC. From the Proxmox host (not the container):
|
|
This creates a bind mount from the host path /tank/fileserver to the container’s /srv/fileserver. Verify it worked:
|
|
You should see the ZFS filesystem mounted inside the container with the size and usage of your dataset.
Step 4 — Install and Configure Samba
Inside the container, install Samba:
|
|
Back up the default configuration:
|
|
Write the Samba configuration:
|
|
Create a Samba user and set directory permissions:
|
|
Restart Samba:
|
|
Test the Samba configuration:
|
|
Step 5 — Performance Tuning for Maximum Throughput
Beyond ZFS settings, tune the Linux kernel network stack for Samba workloads. Add these to /etc/sysctl.conf on the LXC container:
|
|
Verify BBR is available:
|
|
If BBR is not available, load the module:
|
|
Run a quick throughput test from a Linux client:
|
|
On a modern homelab with 1GbE networking and SSDs, expect 110-118 MB/s sequential reads. With 2.5GbE, you should saturate the link at ~280 MB/s.
Step 6 — Accessing Shares from Clients
Windows
- Open File Explorer
- Right-click This PC → Map network drive
- Folder:
\\10.0.30.10\shares - Check Connect using different credentials
- Enter the
smbusercredentials you created - Click Finish
The share appears as a mapped drive. For persistent unmapped access, add the credentials to Windows Credential Manager.
Linux Clients
Install cifs-utils and mount:
|
|
macOS
- Open Finder → Go → Connect to Server
- Enter:
smb://10.0.30.10/shares - Click Connect
- Enter the
smbusercredentials - The share mounts on your desktop and in
/Volumes/shares
Step 7 — Backup Integration with ZFS Snapshots
The real power of this setup is ZFS-native backups. Since the data lives on a ZFS dataset, you can snapshot and replicate it independently of the container.
Automated Snapshots on the Proxmox Host
Create a snapshot script:
|
|
Create a systemd timer to run it daily:
|
|
Send Snapshots to Proxmox Backup Server
If you run Proxmox Backup Server, use proxmox-backup-client to send the dataset snapshot off-host:
|
|
Alternatively, replicate directly to a remote ZFS pool:
|
|
The LXC itself is also backed up via Proxmox’s standard container backup:
|
|
Step 8 — Security Hardening
Isolate the file server on a dedicated storage VLAN. In your MikroTik or managed switch:
- VLAN 30: Storage (LXC file server, NFS clients)
- Firewall rule: only allow SMB (TCP 445) and ICMP from client VLANs
In the LXC itself, add these lines to the [global] section of /etc/samba/smb.conf:
|
|
Enable UFW in the LXC:
|
|
Additional settings to verify or add to /etc/samba/smb.conf:
|
|
Monitoring and Logging
Samba logs to /var/log/samba/. Keep an eye on authentication failures:
|
|
Monitor active connections:
|
|
Sample output showing connected clients and open files:
Samba version 4.17.12
PID Username Group Machine
12345 smbuser smbuser 10.0.20.50 (192.168.1.50)
Service pid Machine Connected at Encryption Signing
shares 12345 10.0.20.50 Mon Jun 15 12:34:56 2026 AST - -
Conclusion
Samba in a Proxmox LXC with ZFS dataset passthrough gives you a file server that is:
- Lightweight — 256MB-1GB RAM, no separate OS to manage
- Fast — kernel-level CIFS with BBR congestion control, tuned ZFS recordsize, and sendfile
- Backed up — ZFS snapshots, PBS integration, and standard container backups
- Simple — one LXC config line for the mount, one smb.conf for the share
Start by creating a Debian 12 privileged LXC, pass your ZFS dataset through as a mount point, configure Samba with the performance settings above, and set up daily ZFS snapshots. Your clients will see a fast SMB share, your Proxmox host will see minimal overhead, and your backups will be handled by ZFS automation.
For the homelab that needs centralized storage without running a full NAS VM, the LXC + Samba + ZFS combination is the most efficient path to a reliable file server.