Docker is great for most self-hosted apps — but a handful of them genuinely need what only a hypervisor can give them.
If you've been self-hosting for a while, you've probably heard some version of "just Dockerize it" for every single app on your network. Most of the time that's solid advice. But there's a small group of self-hosted applications that actually get worse, not better, when you cram them into a container — because what they need isn't more CPU or RAM, it's direct access to hardware, a real kernel, or a network stack a container can't fully control.
In this guide I'm covering the specific self-hosted apps where I've personally seen Proxmox (a free, open-source hypervisor that combines KVM virtual machines, LXC containers, ZFS storage, and built-in backups) outperform a Docker-only setup, why each one benefits, and the exact hardware requirement that trips up most people the first time they try USB or GPU passthrough. I'm also including a simple decision rule for when to reach for a full VM versus an LXC container, since that's the question I get asked most often.
I'm Mostafa Amaan, and on Valley4Techs I write practical, tested guides on networking, virtualization, and home labs — no fluff, just what actually worked when I built it myself. Let's get into it.
Why Docker Isn't Always the Answer
Docker Compose, one-click app stores, and container-focused distros have made self-hosting easier than it's ever been. For the vast majority of apps — a note-taking tool, a bookmark manager, a simple dashboard — a container is genuinely the right call: lightweight, fast to redeploy, and easy to update.
The problem shows up when an app needs one of these things, which containers either can't do at all or can only do with fragile workarounds:
- Full snapshots and instant rollback — not just "restart the container," but reverting an entire OS state in seconds if an upgrade goes wrong.
- GPU or PCI passthrough — giving one workload exclusive, driver-level access to a graphics card or a USB controller, without fighting the host OS for it.
- Its own kernel and networking stack — firewalls, network simulators, and nested virtualization tools are built to own the box's networking, not share it politely with a host.
- Filesystem-level features — ZFS snapshots, replication, and storage flexibility that sit below the container layer entirely.
Proxmox happens to bundle KVM virtualization, LXC containers, ZFS, software-defined networking, and backups into one platform, which is exactly why it keeps coming up as the go-to answer for these specific cases. Below are the apps where I've found that difference actually matters in day-to-day use — not just in theory.
Quick Reference: What Each App Actually Needs From Proxmox
| App | Best deployed as | Why it needs Proxmox |
|---|---|---|
| Home Assistant OS | VM | Stable USB passthrough for Zigbee/Z-Wave, safe snapshot before every update |
| pfSense / OPNsense | VM | Needs to own the network stack and multiple NICs directly |
| Jellyfin (with GPU) | VM | Exclusive GPU passthrough avoids driver conflicts seen in containers |
| Immich | LXC | ZFS snapshots protect your photo library before ML re-indexing |
| Nextcloud | LXC or VM | ZFS replication for off-site backup, easy to resize storage later |
| Kali Linux / security labs | VM | Full kernel access, instant snapshot revert after testing exploits |
| GNS3 / EVE-NG | VM | Requires nested virtualization and multiple virtual NICs |
| Kubernetes cluster | VM (one per node) | Isolated kernels and networking mirror real production clusters |
Before You Start: The Hardware Check Everyone Skips
Almost every guide on this topic jumps straight into "assign the GPU to the VM" without mentioning the one setting that causes 90% of failed passthrough attempts: IOMMU (Input-Output Memory Management Unit) support. This is what lets Proxmox isolate a PCI device — a GPU, a USB controller, a network card — and hand it to a single VM exclusively.
Always verify IOMMU is active in your host's BIOS before configuring VMs.
Before attempting GPU or USB passthrough for any app on this list, check:
- Your CPU supports it. Intel VT-d or AMD-Vi — check your CPU model on the manufacturer's spec page if you're not sure.
- It's enabled in your BIOS/UEFI, not just supported. It's usually off by default and hides under "Advanced" or "Chipset" settings, often labeled VT-d, IOMMU, or SVM Mode.
- It's enabled in Proxmox itself, by editing the GRUB config
(
intel_iommu=onoramd_iommu=on) and rebooting before you touch any VM settings.
8 Self-Hosted Apps That Are Genuinely Better on Proxmox
Each app below hit a specific wall when I ran it in Docker — unstable USB mappings, driver conflicts, or a networking stack that containers simply can't own. Here's what I moved to Proxmox, why, and whether it belongs in a full VM or an LXC container.
1. Home Assistant OS — Stable Hardware Access and Safe Upgrades
Running Home Assistant OS as a Proxmox VM ensures stable USB passthrough for smart home coordinators.
Once you go past the basics with Home Assistant, you'll almost certainly add a USB Zigbee, Z-Wave, or Thread coordinator. Docker can technically pass a USB device through, but the mapping tends to shift when you replug the dongle, update the container, or move to a new host — I've had a Zigbee stick silently disappear from a container after a routine reboot more than once.
Proxmox assigns the USB or PCI device directly to the Home Assistant OS VM, so it behaves almost identically to running on dedicated hardware. Just as valuable: taking a full VM snapshot before installing a new integration or updating Home Assistant core. If something breaks your automations, restoring the previous state takes seconds instead of a frustrating evening of rollback commands.
2. pfSense or OPNsense — A Fully Virtualized Network Lab
Virtualizing pfSense or OPNsense on Proxmox gives you direct NIC passthrough and instant snapshot rollback.
Running a firewall inside a VM sounds backwards until you see it in practice. With multiple NICs or PCI passthrough, pfSense and OPNsense get direct access to physical network interfaces, letting you build VLANs, test VPN configurations, or run an entire virtual networking lab without buying extra hardware.
Snapshots make this genuinely low-risk: test an aggressive firewall rule set, and if it locks you out of your own network, roll back the VM in seconds rather than physically resetting a router. If you're new to firewall concepts before jumping into pfSense specifically, our comprehensive firewall guide covers the fundamentals first.
3. Jellyfin With GPU Passthrough — No More Driver Fights
Exclusive GPU passthrough eliminates the driver conflicts that plague container-based transcoding setups.
GPU acceleration works in Docker too, but I've lost more evenings than I'd like to admit chasing driver version mismatches between the host and the container. Passing an Intel iGPU or NVIDIA GPU directly to a dedicated Jellyfin VM gives it exclusive hardware access — no sharing the driver stack with the host OS or other containers, which removes most of the permission and codec headaches people run into.
It also isolates your media stack cleanly: codec packages, transcoding drivers, and supporting software stay inside that one VM. If you ever migrate to new hardware, a Proxmox backup restores the whole environment — drivers included — without reconfiguring anything from scratch.
4. Immich — Snapshot Protection Before Every ML Re-Index
ZFS snapshots protect your Immich photo library from metadata corruption during ML re-indexing jobs.
Immich, the self-hosted Google Photos alternative, periodically re-runs machine learning jobs to re-index faces and objects across your entire photo library. That's exactly the kind of bulk operation where a bad update or a corrupted database write can quietly damage months of metadata. Running Immich in an LXC container on top of ZFS storage means you can snapshot the container before a major version upgrade and roll back instantly if the re-index goes sideways.
This is a gap I don't see covered elsewhere: most Immich guides focus on the initial Docker Compose setup and skip what happens when a library re-index corrupts thumbnails mid-run. A pre-upgrade snapshot habit solves that in seconds instead of a restore-from-backup ordeal.
5. Nextcloud — Storage Flexibility That Grows With You
Running Nextcloud on Proxmox with ZFS lets you expand storage and replicate data off-site without downtime.
Nextcloud is one of those apps that starts small and quietly becomes your entire personal cloud. Running it on Proxmox with ZFS underneath means you can expand storage without downtime, use ZFS snapshots as an additional safety net on top of Nextcloud's own versioning, and set up ZFS send/receive replication to a second machine for genuine off-site backup — something that's far more fiddly to bolt onto a container-only setup.
6. Kali Linux and Security Labs — Disposable, Isolated Environments
Isolated Kali VMs on Proxmox let you test exploits safely and restore to a clean state in seconds.
Penetration testing and malware analysis workflows need two things containers struggle with: unrestricted kernel access and true network isolation. On Proxmox, an isolated Kali VM can talk to intentionally vulnerable targets like Metasploitable or OWASP Juice Shop inside a private virtual network that never touches your production LAN.
Snapshots are the real win here. After running an exploit or analyzing a malware sample, you restore the VM to a clean state in moments instead of manually undoing whatever the test changed — which matters a lot when "whatever the test changed" might include a rootkit.
7. GNS3 and EVE-NG — Certification-Grade Network Simulations
Proxmox's nested virtualization support makes it ideal for running complex GNS3 and EVE-NG lab topologies.
If you're studying for a networking certification or building enterprise topologies at home, GNS3 and EVE-NG typically need nested virtualization, several virtual network adapters, and meaningful CPU and memory headroom per lab. Proxmox handles all of that natively, and you can run multiple isolated labs side by side, each with its own virtual switches and hardware allocation — then snapshot a complex topology right before a practice exam so a mistake doesn't force you to rebuild it from scratch.
8. Kubernetes Clusters — Production-Like Testing at Home
Cloning VM templates lets you spin up production-like Kubernetes nodes in minutes instead of hours.
Lightweight distributions like k3s run fine on a single host or even inside containers, but if you're practicing for real production scenarios, a multi-node cluster on separate VMs is far more representative. Each node gets its own kernel, dedicated resources, and independent networking — closer to how a real cluster behaves than several k3s instances sharing one Docker host ever will.
Proxmox VM templates make this practical rather than tedious: clone a prepared node image in minutes to expand the cluster, and experiment with storage classes, MetalLB, or Longhorn without worrying about breaking your only copy of the environment.
VM or LXC Container? The Rule I Actually Use
This is the question I get asked most after "how do I fix passthrough," and most guides gloss over it. Here's the practical shortcut, not the textbook definition:
- Choose a VM when the app needs its own kernel, direct hardware access (GPU, USB, PCI), or you genuinely don't trust it enough to share a kernel with your other workloads — firewalls, GPU transcoding, security labs, and anything doing nested virtualization.
- Choose an LXC container when the app is a well-behaved Linux service that doesn't need exclusive hardware — it starts faster, uses a fraction of the RAM, and still gets ZFS snapshot protection. Immich, Nextcloud, and most web apps fit here comfortably.
- Don't default to VM "just to be safe." I made this mistake early on — running everything as a VM "just in case" wastes RAM you'll want later for the apps that actually need it.
Making the Switch: Migration and Resource Overhead
Transitioning your services from Docker to Proxmox brings up two major questions for most people: "Will this consume all my server's RAM?" and "How difficult is it to move my data?" Let's break down both concerns so you know exactly what to expect.
Docker vs LXC vs VM: The True Performance Cost
If you are migrating away from Docker, your biggest concern is probably resource overhead. Running everything as a VM will quickly consume all your RAM, but LXC is surprisingly efficient. Here is the realistic breakdown:
- Docker Containers: Minimal overhead. They share the host kernel and only use the RAM required by the app.
- Proxmox LXC Containers: Almost identical to Docker. An LXC container running Debian might only use 30-50MB of RAM at idle. You can comfortably run dozens of LXC containers on modest hardware.
- Full KVM Virtual Machines: High overhead. Each VM requires its own complete OS (typically 1-2GB of RAM just to boot) and reserves its allocated memory. This is why the VM vs LXC rule above is so critical.
LXC containers offer Docker-like efficiency while integrating natively with Proxmox ZFS and snapshots.
How Hard is it to Migrate from Docker?
Moving an app from Docker to a Proxmox LXC container or VM isn't as daunting as it sounds, but there is no magic "convert" button. The general process involves:
- Exporting Data: Back up your Docker volumes and any database dumps (e.g., exporting a PostgreSQL database).
- Provisioning in Proxmox: Spin up your new LXC or VM. Tools like the popular Proxmox Helper Scripts can install services like Nextcloud or Jellyfin in seconds.
- Importing Data: Transfer your files and restore your database dumps into the new environment.
While it takes a bit of manual work, the long-term benefits of native snapshots and Proxmox Backup Server (PBS) integration make the one-time migration effort well worth it.
5 Mistakes I See People Make When Moving From Docker to Proxmox
- Skipping the IOMMU check. Covered above, but it bears repeating — this single setting causes more failed passthrough attempts than everything else on this list combined.
- Running every app as a full VM. It's simpler mentally, but you'll burn through RAM fast. Reserve VMs for apps that actually need dedicated hardware or kernel access.
- Forgetting to snapshot before major upgrades. The whole point of moving to Proxmox is the safety net — skipping the habit of snapshotting before a risky update defeats the purpose.
- Not setting up Proxmox Backup Server early. Snapshots protect you from bad updates; backups protect you from a dead drive. You need both, and it's much easier to configure PBS before you have 15 VMs to retroactively cover.
- Passing through the only GPU in the host. If you assign your sole GPU to a VM, Proxmox's own web console can lose local video output on that machine. Use a secondary GPU or iGPU for passthrough if you also need to use the host directly.
Final Thoughts
The real advantage of Proxmox isn't that it's "better than Docker" — it's that it stops forcing every workload into the same box. A firewall gets to own its network stack, a media server gets exclusive GPU access, and a photo library gets ZFS snapshots before every risky operation, while your simple web apps still run as lightweight LXC containers using barely any resources at all.
You don't need to migrate everything at once. Start with whichever app on this list is causing you the most friction in Docker right now — for most people, that's either Home Assistant's USB stability or Jellyfin's GPU driver headaches — and build from there.
Building out your home lab?
Join hundreds of subscribers and get practical networking, virtualization, and self-hosting guides — tested setups, not theory — delivered to your inbox.
Yes, Subscribe Me! ✉️🔒 No spam, ever. We respect your inbox.
We'd love to hear your thoughts! Leave a comment below
and share your experience or questions.