LXC vs Docker: When Containers Need a Full OS (And When They Don't)

SYSTEM CONTAINER
systemd / init
multiple processes
own network stack
full filesystem
LXC / Incus
vs
APP CONTAINER
PID 1 = app
single process
shared kernel net
layered FS (OCI)
Docker / Podman

The word "container" gets thrown around constantly, but Docker containers and LXC system containers are architecturally very different. Understanding the difference will help you pick the right tool — and stop you from forcing an application container where a system container belongs (or vice versa).

The Core Architectural Difference

Docker containers (and OCI containers in general) are designed around one process. Your container runs a single application as PID 1. The container's filesystem is a layered OCI image. The network stack is a virtual ethernet pair managed by Docker. When your process exits, the container exits.

LXC system containers are designed to look and behave like a complete Linux system. PID 1 is systemd (or another init). You can install packages, run cron jobs, have multiple services, log in over SSH — everything a VM can do, at near-native speed.

CharacteristicLXC (Incus)Docker
Init systemsystemd / OpenRCApplication binary (no init)
Multiple processesYes — naturalNeeds supervisor (s6, tini)
SSH accessNativeWorkaround required
Package managementapt, dnf, apk work nativelyWorks inside image build only
KernelShared with hostShared with host
Network namespaceFully isolated (own stack)Shared or bridge
Image formatRootfs tarballs (LXC images)OCI layers
Startup time~1–2 seconds~200ms
Memory overhead~50–200 MB (with systemd)~10–50 MB
Registry ecosystemlinuxcontainers.orgDocker Hub, GHCR, etc.

When LXC Wins

1. Multi-Service Applications

Old-school applications that expect a full Linux environment — Apache + PHP + cron + a local PostgreSQL — are painful to containerize with Docker. You'd need multiple containers, a compose file, shared volumes, and you'd still fight init system dependencies. In an LXC container, just install everything the same way you would on a VM. Done.

2. Development Environments

LXC containers make perfect isolated dev environments. Spin up a container per project, SSH in, install your dependencies, run your build tools. No Dockerfile. No image rebuilds. Feels like a VM, starts in 2 seconds.

# Create a dev environment
incus launch ubuntu:22.04 my-dev-env
incus exec my-dev-env -- bash

# Inside: completely full Ubuntu environment
apt install nodejs python3 postgresql -y

3. Legacy Application Migration

Migrating a legacy app from bare metal? Put it in an LXC container first. No code changes needed. It gets isolation, resource limits, and snapshots — while keeping all its assumptions (multiple processes, init, cron, etc.) intact.

4. CI/CD Runner Isolation

Each CI job in its own LXC container — full OS, fast start, destroyed after the job. Much safer than runners sharing a host, and faster to provision than VMs.

When Docker Wins

1. Single-Purpose Microservices

If your application is a single binary or process (a web API, a worker, a proxy), Docker is the natural fit. The OCI image format gives you reproducible builds, a huge registry ecosystem, and tooling (Compose, Kubernetes, Helm) that assumes OCI.

2. Teams with Docker Expertise

Your team writes Dockerfiles. Your CI builds Docker images. Your deployment target is Kubernetes. Don't introduce LXC — Docker is right for this workflow.

3. Immutable Infrastructure

The OCI layer model excels at immutable infrastructure — build an image, test it, deploy it. LXC containers are more mutable by nature (you SSH in and run apt upgrade). If immutability is a principle you care about, Docker/OCI is the better model.

💡

You can mix both. It's common to run Docker inside an LXC container. A system container gives you the full OS environment, and Docker inside it manages your app containers. VeloxaHost instances support this pattern out of the box.

What About VMs?

Incus also manages QEMU/KVM virtual machines with the same API and CLI as LXC containers. Use a VM when:

  • You need a different kernel (custom kernel, Windows, BSD)
  • You need kernel modules that can't run in a container
  • You need complete hardware isolation (payment processing, regulated workloads)
  • Your workload is untrusted code that should not share kernel with anything

Everything else — system containers are faster, lighter, and just as isolated at the namespace level.

Decision Guide

  • Single app / microservice / immutable build → Docker
  • Multi-service / legacy app / full OS needed → LXC container
  • Untrusted workload / different kernel / regulated → VM
  • Already on Docker and it works → Don't change it

VeloxaHost gives you all three: LXC containers, VMs, and you can run Docker inside either. Try free for 14 days →