In my software architecture overviews for Axiom and Forge, you might have noticed a deliberate infrastructure choice: I opted for LXD instead of the standard Docker and Kubernetes stack.

Whenever people see this, the immediate question is almost always: Why?

Docker and Kubernetes have become the de facto default for modern software deployment. Deviating from that stack usually raises eyebrows. But when you examine how the cloud-native ecosystem evolved—and the massive operational overhead it introduced—the case for system-level virtualization becomes impossible to ignore.

1. The Core Flaw: Process Wrappers vs. System Containers

It is quite simple: Docker was never designed for the way the software industry forces it to work today.

Docker was built as an application process wrapper. Premature optimizations, such as the layer-based union filesystem, were designed around static deployment assumptions. In real-world CI/CD pipelines and local development environments, those immutable layers introduce constant disk bloat, cache invalidation headaches, and unnecessary rebuild overhead.

Worse, Docker on its own does not fulfill enterprise operational requirements. It lacks native multi-host networking, storage pooling, and tenant isolation. To make it usable at scale, the industry built a fragile tower of third-party tools, package managers, and overlay abstractions on top of it: Kubernetes, Helm, custom operators, and a endless mix of Container Networking Interfaces (CNIs) like Calico, Flannel, and Cilium.

You end up spending more time managing, debugging, and updating the orchestration stack than you do writing actual application logic.

LXD approaches virtualization from a completely different angle: system containerization. Instead of wrapping a single isolated process, LXD provides a lightweight Linux system that behaves like a full virtual machine—complete with its own init system, process space, and device management—while running directly on the host kernel with near-zero performance overhead.


2. Infrastructure as Code Without the Abstraction Bloat

One of the greatest ironies of the modern DevOps landscape is the complexity of “Infrastructure as Code” (IaC). To deploy a modern cloud application, teams are expected to learn domain-specific languages (HCL for Terraform), complex templating engines (Helm charts), and heavy automation frameworks (Ansible).

With LXD, orchestration does not require another proprietary DSL or heavy agent binary. Orchestration is handled natively using apt and idempotent Bash shell scripts.

Because LXD containers present as full, standard Linux environments, your shell scripts act as true, readable source code for your infrastructure:

 1#!/usr/bin/env bash
 2set -euo pipefail
 3
 4# Example: Idempotent LXD System Provisioning Script
 5CONTAINER_NAME="axiom-node-01"
 6
 7if ! lxc info "$CONTAINER_NAME" >/dev/null 2>&1; then
 8    echo "[+] Launching LXD instance: $CONTAINER_NAME"
 9    lxc launch images:ubuntu/24.04 "$CONTAINER_NAME" -c security.nesting=true
10fi
11
12echo "[+] Provisioning dependencies inside $CONTAINER_NAME..."
13lxc exec "$CONTAINER_NAME" -- bash -c "
14    export DEBIAN_FRONTEND=noninteractive
15    apt-get update -y
16    apt-get install -y --no-install-recommends curl git build-essential
17"

There are no hidden state files to corrupt, no Helm releases to get stuck in pending-rollback, and no complex CNI drivers to troubleshoot. If a engineer knows basic Linux system administration and shell scripting, they already know how to manage, audit, and automate the entire infrastructure fabric.


3. Key Architectural Advantages of LXD

LXD natively builds in the exact features enterprise architectures require, eliminating the need for an external tool ecosystem:

  • True System Containers and VMs: LXD manages lightweight system containers alongside full QEMU-based virtual machines under a single, unified API and CLI. If a tenant workload requires a custom kernel or a non-Linux OS, you use the exact same commands and profiles.
  • Unprivileged Nested Virtualization: Running nested containers or tenant Docker daemons inside Kubernetes typically requires mounting the host socket or running with --privileged flags—effectively destroying host security. LXD handles nested, unprivileged system containers natively out of the box using kernel user namespaces (subuid/subgid mapping).
  • Native Fan Networking & SDN: LXD includes native support for Fan Networking—an elegant overlay network mechanism that automatically maps subnets across cluster nodes using simple IP encapsulation. Coupled with Open Virtual Network (OVN) integration, you can define isolated bridge networks and multi-tenant firewalls without installing a CNI plugin.
  • First-Class Storage Pools (ZFS & Ceph): LXD integrates directly with ZFS and Ceph at the block level. You get instant container copy-on-write cloning, snapshots, storage quotas, and remote dataset replication natively.
  • Zero Control-Plane Tax: Multi-node LXD clustering relies on an embedded dqlite (distributed SQLite) database for consensus. There are no heavy master control planes, API servers, or etcd clusters consuming gigabytes of idle RAM—just pure bare-metal execution.

4. Architectural Comparison: LXD vs. Docker + Kubernetes

The following table breaks down how these two operational paradigms stack up across critical enterprise infrastructure capabilities:

Feature / MetricLXD / Incus ArchitectureDocker + Kubernetes Stack
Virtualization ScopeFull System Containers + QEMU VMsSingle Application Process (OCI Containers)
Orchestration ToolingNative apt + Idempotent Bash ScriptsHelm, Terraform, Kustomize, Operators
Multi-Node NetworkingBuilt-in Fan Networking & Native OVNRequires 3rd-Party CNIs (Calico, Cilium, Flannel)
Nested IsolationNative Unprivileged Nesting (Kernel User Namespaces)Insecure (--privileged or Docker-in-Docker hacks)
Storage DriversDirect ZFS / Ceph Block Level StorageCSI Drivers + Local Volume Provisioners
Idle OverheadNear-Zero (Lightweight dqlite Consensus)Significant (etcd, kube-apiserver, kubelet, cppo)
Learning CurveStandard Linux Sysadmin & Shell ScriptingHigh (YAML abstractions, K8s API, Helm syntax)
Upstream DependenciesLinux Kernel + LXD Daemon10+ Microservice Components & Controllers

5. When Should You Use What?

This architectural choice is not about dogma; it is about choosing the right tool for your platform’s operational goals:

  • Choose Docker + Kubernetes if: You are deploying standard, ephemeral stateless microservices across massive public cloud infrastructure (AWS/GCP), your organization already employs dedicated DevOps teams to maintain Kubernetes control planes, and your applications do not require nested containerization or bare-metal storage efficiency.
  • Choose LXD if: You are building sovereign, multi-tenant workspace platforms, high-performance edge infrastructure, or developer tools where resource efficiency, nested security, low latency, and operational simplicity are paramount.

You do not need an ecosystem of seven different abstractions to run secure, scalable, multi-tenant workloads. You just need the Linux kernel, idempotent scripts, and LXD.