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.
| Characteristic | LXC (Incus) | Docker |
|---|---|---|
| Init system | systemd / OpenRC | Application binary (no init) |
| Multiple processes | Yes — natural | Needs supervisor (s6, tini) |
| SSH access | Native | Workaround required |
| Package management | apt, dnf, apk work natively | Works inside image build only |
| Kernel | Shared with host | Shared with host |
| Network namespace | Fully isolated (own stack) | Shared or bridge |
| Image format | Rootfs tarballs (LXC images) | OCI layers |
| Startup time | ~1–2 seconds | ~200ms |
| Memory overhead | ~50–200 MB (with systemd) | ~10–50 MB |
| Registry ecosystem | linuxcontainers.org | Docker 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 →