HAS — Hegarty Advanced Solutions
← All guides

HAS guides / Platforms / Free to read

Containers or VMs?
Choose per workload.

The useful question is not which technology wins. It is which environment gives this application the compatibility, separation, and recovery path it needs.

Start with what is actually isolated

A typical Linux application container packages an application and its userspace dependencies while sharing a Linux kernel with its host. Namespaces, control groups, permissions, and other controls provide separation and resource management. A container is not simply a small virtual machine with its own independent kernel.

A virtual machine presents virtual hardware to a guest operating system, which runs its own kernel. The hypervisor manages access to the underlying host. That makes VMs useful for separate operating systems, kernel requirements, and environments you want to manage as complete machines.

Neither boundary is absolute protection against every mistake or vulnerability. Privileged containers, host mounts, Docker-socket access, shared folders, device passthrough, and network configuration can change the practical separation. Keep the host, hypervisor, guest systems, and applications maintained according to the layers you use.

Packaging is not the whole decision

An application having a container image does not mean every container configuration is suitable. Read its supported deployment instructions, required privileges, data paths, and upgrade process before choosing where to run it.

Match the environment to the job

A Linux web application with a documented container setup
A container can make dependencies and repeatable deployment easier to manage. Check CPU architecture, required mounts, database compatibility, and persistence. Confirm that the image is maintained by a source you trust.
A Windows application or a different operating system
A VM is often the appropriate starting point when you need a guest OS different from the host. A Linux container cannot provide a Windows kernel. Check operating-system licensing and application support requirements.
A system-level learning environment
A VM lets you practise changes to boot configuration, kernels, package management, or a whole OS without treating the main host as the experiment. Use a separate test network and disposable data when appropriate.
A specialised appliance
Follow its supported image and platform guidance. An appliance distributed as a VM may depend on assumptions that do not translate cleanly into a container.

For one simple application on one machine, a direct installation may also be a reasonable option. The goal is a system you can update and recover—not adding a virtualisation layer merely because it is available.

Containers inside a VM can be a useful compromise

You do not have to choose one approach for the whole homelab. A hypervisor can host a Linux VM that runs a group of containerised applications, alongside separate VMs for different operating systems or experiments.

Illustrative mixed layout

Physical host / hypervisor
  ├─ Linux VM: household applications
  │    ├─ application container
  │    └─ database container
  ├─ Linux VM: disposable experiments
  └─ guest OS: separate learning workload

This can group services by their role and change schedule. Updating or rebuilding the experimental guest need not require changing the household applications’ guest OS. However, all guests on that physical host still share its power, hardware, storage, and maintenance events.

Putting applications into separate VMs on one host is not the same as making them highly available. If the host fails, those guests can fail together. The configuration also adds guest-OS maintenance, backup layers, and resource overhead. Choose those costs because they solve a real requirement.

Budget for the workloads that run together

Containers can share a kernel and avoid running a full guest OS for every application. That can reduce overhead, but the application’s actual work still consumes memory, processor time, storage, and network capacity. A database does not become inexpensive merely because it runs in a container.

Set resource limits or reservations where appropriate and verify how your runtime applies them. Without deliberate controls, one busy workload can put pressure on neighbours. Limits also need enough room for normal peaks such as indexing, backup, or startup.

For VMs, account for the host’s needs, guest operating systems, and concurrent workloads. Assigning more virtual CPUs does not create more physical CPU capacity. Memory overcommit and ballooning have platform-specific behaviour; do not rely on them without understanding what happens when demand rises.

Storage contention can be the limiting factor even when processor graphs look quiet. Several VMs or containers sharing one disk can compete during database writes, downloads, and backup jobs. Measure real workloads before assuming that more CPU allocation will resolve the bottleneck.

Check hardware access before buying the machine

Applications that need a GPU, USB radio, accelerator, or storage controller introduce another set of requirements. Container access usually depends on host drivers, device permissions, and runtime support. VM passthrough can depend on hardware capabilities, firmware settings, IOMMU grouping, and guest drivers.

Do not assume a device can be shared between guests or moved freely after passthrough. Some configurations assign a device exclusively to one guest. Migration and recovery can also become tied to the availability of compatible hardware on the destination.

CPU architecture matters independently of the container-versus-VM decision. An x86 image is not automatically native on an ARM host. Emulation may be available, but its support and performance need separate evaluation. Use the application’s documented architecture support rather than assuming that a downloadable image will run well everywhere.

Make data and rebuild instructions explicit

For a containerised application, record the image version or digest, deployment configuration, protected secrets, persistent volumes, and external dependencies. The image is not the only component you need to recover. Replacing the container should not discard required data stored only in its writable layer.

For a VM, record guest configuration, virtual disks, network settings, firmware requirements, and any passed-through devices. A VM backup can capture a broad environment, but the application still needs a consistent state. Use the platform’s guest coordination and application-aware procedures where required.

Snapshots can help with certain short-term rollback tasks. A snapshot on the same storage remains dependent on that storage and can grow as data changes. It is not an independent backup. Do not assume an application is consistent simply because a disk or VM snapshot completed.

Practise restoring into a separate environment. Keep copied services from sending real messages or controlling devices while you test. For either platform, check the application’s data and user path—not just whether the container starts or the guest reaches a login screen.

Write down the reason

A workload placement checklist

  • Compatibility: Required OS, kernel, CPU architecture, and supported deployment method are known.
  • Separation: The workload’s trust level and maintenance schedule fit the chosen boundary.
  • Resources: Host overhead, guest overhead, and concurrent application demand fit the hardware.
  • Devices: Required drivers, passthrough, sharing, and replacement hardware are understood.
  • Data: Persistent files, configuration, credentials, and dependencies are inventoried.
  • Updates: You know which host, guest, runtime, and application layers need maintenance.
  • Recovery: An independent backup and a tested rebuild path exist for important services.
  • Complexity: Every extra layer solves a requirement you can explain.

For each workload, finish the sentence: “We chose this environment because it needs…” If the answer is only that the platform is popular, revisit the requirement before committing the data.