Preface
During the process of building a home data center, three types of virtualization technologies are involved, namely traditional Virtual Machines (VM), Linux Containers (LXC), and the Docker technology we mainly use when building applications.
Why do I use all three of these virtualization technologies at the same time?
To answer this question, we first need to understand the relationship between these three technologies. Actually, there is a “nested” size relationship among these three technologies, as shown in the figure below (drawn casually, quite informal, as long as it's understandable):

Strictly speaking, the nesting relationship in the figure above represents the amount of virtualized content; the larger the circle, the more content needs to be virtualized.
Virtual Machine (hereinafter referred to as VM)
VM technology needs to virtualize a complete set of hardware, including CPU, memory, network card, hard disk, graphics card, etc. This level of virtualization consumes a certain amount of system resources, but the benefit it brings is complete resource isolation, which is particularly important in actual production environments to ensure complete isolation between critical services. Normally, virtual machines built using VM technology are bare hardware and require manual installation of the operating system, though deployment efficiency can be improved by creating templates.
In essence, a VM is virtualized hardware.
Linux Containers (LXC)
VM technology trades resource consumption for complete resource isolation. However, sometimes we might not care as much about complete resource isolation but rather about resource consumption. For example, in my case: an Intel CPU mini-host with an i5-13400 CPU (only 10 cores, and split into performance/efficient cores~) and 64GB of RAM. With these resources, every additional virtual machine means extra consumption—even the smallest bit of savings counts. So in this situation, unless absolutely necessary, I will not use a Virtual Machine to build a VM.
At this point, LXC technology becomes particularly practical: if your host operating system is Linux, LXC technology can provide you with virtual machines of various Linux distributions (including choices of different versions) with almost zero overhead. Moreover, creating a new virtual machine takes only a few seconds, and it even includes many basic component libraries. Isn't that amazing?
In essence, LXC is a virtualized Linux system (by sharing the host kernel).
Docker
Virtual machines built using VMs are bare hardware, and virtual machines built using LXC are bare Linux systems (with requirements on the host operating system). However, most people do not care about the hardware or the host operating system used (Windows, Linux, macOS), but only care about the applications that need to be deployed. In this case, Docker is the most ideal choice. The biggest advantage of Docker is that as long as the runtime environment can be successfully deployed, it can run regardless of whether the hardware is a PC, NAS, server, software router, or any other random hardware. In terms of lineage, Docker is actually the product of LXC enhanced with cgroups and namespaces.
Choosing Virtualization Technologies in Different Environments
Having explained the pros and cons of the three virtualization technologies, let's return to the choice in building a home data center.
Since I wanted to repurpose a "beggar's version" M1 Mac mini (with only 8GB of RAM, which is too small for almost anything), after much thought, I installed Docker Desktop for Mac as the main Docker runtime environment. At the same time, it serves as a Tailscale relay server (which I will cover in a dedicated article later), an Apple caching server, a proxy publishing server, and a VNC remote maintenance server, making full use of it.
The Intel CPU mini-host has a PVE virtualization environment installed (ESXi is paid software, which goes against our philosophy of keeping the home data center free; crucially, the host system cannot be tinkered with, such as installing Tailscale). Its free version supports cluster deployment and migration features, and natively supports LXC. Plus, PVE 7.4 itself is based on Debian 11, offering high playability. Is there any other choice besides this...?
In the PVE virtualization environment, two types of virtual machines (VM and LXC) are deployed simultaneously. All applications that need to be deployed via source code are separated into different LXCs, which provides a certain level of isolation (for example, different LXCs can be restarted separately). There are two virtual machines built via VMs: one is Win11 (serving as an RDP remote maintenance server and an Emby demonstration server)—there's no way around this, a VM must be used; the other is Debian 12.
Why is there a Debian 12 VM? This is related to some limitations of LXC. As mentioned earlier, LXC essentially shares the kernel with the host Linux. For security reasons, it restricts certain permissions for calling root on the host by default (which can be enabled by turning on privileged mode containers, but this is generally not recommended). Therefore, if you run Docker inside LXC (“container in container”), a few applications that require host root privileges will throw errors (such as SafeLine WAF and the Baota Cloud Control Platform). To address this, I specifically created a Debian 12 VM to serve as a backup Docker environment, leaving LXC to focus on running source-code-deployed applications. Actually, running Docker in LXC is best as long as Docker doesn't have special permission requirements, but I have OCD and didn't want to deploy a bunch of Docker containers in LXC and another bunch in the Debian 12 VM, so I simply put all the backup environment's Docker containers on the Debian 12 VM.
In summary, use Docker for what is suitable for Docker deployment, use LXC for what is suitable for source code deployment, and use VMs when absolutely necessary.