Skip to content
Back to Blog
Linux

LXC/LXD Containers on Linux: System Container Virtualization

Deploy and manage LXC/LXD system containers for lightweight virtualization: networking, storage pools, profiles, and cluster setup.

Sep 2025
14 min read

Introduction

LXC (Linux Containers) and LXD (a hypervisor for LXC) allow you to run full Linux system containers — lighter than VMs but more isolated than Docker. LXD adds a REST API, a CLI, clustering, and storage/network management on top of LXC.

LXC vs Docker vs VM

FeatureDockerLXC/LXDVM
IsolationProcessSystemFull hardware
OS kernelSharedSharedSeparate
Boot timeSecondsSecondsMinutes
Use caseAppsFull Linux systemsFull isolation
SystemdNoYesYes

Installing LXD

BASH
# Ubuntu (snap)
snap install lxd

# Initialize LXD (interactive)
lxd init
# Answer: storage pool=dir or zfs, networking=yes (creates lxdbr0), clustering=no for single node

Basic Container Operations

BASH
# Launch a container
lxc launch ubuntu:22.04 web-server-1

# List containers
lxc list

# Enter container shell
lxc exec web-server-1 -- bash

# Stop/start
lxc stop web-server-1
lxc start web-server-1

# Delete
lxc delete web-server-1 --force

Container Configuration

BASH
# Set memory limit
lxc config set web-server-1 limits.memory 2GB

# Set CPU limit
lxc config set web-server-1 limits.cpu 2

# View all config
lxc config show web-server-1

# Resource limits persist across reboots

Networking

BASH
# View container IP
lxc list  # Shows IPv4/IPv6

# Add a bridged NIC (direct access to physical network)
lxc config device add web-server-1 eth1 nic nictype=bridged parent=eth0

# Port forwarding from host to container
lxc config device add web-server-1 myport proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80

Storage

BASH
# Create a disk device
lxc storage create data-pool dir source=/data/lxd

# Add disk to container
lxc config device add web-server-1 data disk source=/data/websites path=/var/www

# Or create a new volume
lxc storage volume create default web-data
lxc config device add web-server-1 web-data disk pool=default source=web-data path=/var/www

Snapshots and Migration

BASH
# Take snapshot
lxc snapshot web-server-1 before-upgrade

# List snapshots
lxc info web-server-1 | grep Snapshots -A 20

# Restore snapshot
lxc restore web-server-1 before-upgrade

# Copy container to another host
lxc copy web-server-1 web-server-2
lxc move web-server-1 remote-host:web-server-1

Profiles (Templates)

Profiles let you reuse configuration:

BASH
# Create profile for web servers
lxc profile create webserver
lxc profile set webserver limits.memory 2GB
lxc profile set webserver limits.cpu 2
lxc profile device add webserver eth0 nic nictype=bridged parent=lxdbr0

# Apply profile to new container
lxc launch ubuntu:22.04 new-web --profile default --profile webserver

Production Hardening

BASH
# Prevent container from seeing host processes
lxc config set web-server-1 security.idmap.isolated true

# Disable nesting (prevents container-in-container)
lxc config set web-server-1 security.nesting false

# Enable AppArmor
lxc config set web-server-1 raw.lxc "lxc.apparmor.profile=generated"

# Restrict capabilities
lxc config set web-server-1 linux.kernel_modules ""

LXD Clustering (Multi-Host)

BASH
# On node 1 (first node)
lxd init --preseed << EOF
cluster:
  enabled: true
  server_name: node1
  server_address: 192.168.1.10:8443
EOF

# On node 2 (join existing cluster)
lxd init --preseed << EOF
cluster:
  enabled: true
  server_name: node2
  server_address: 192.168.1.11:8443
  cluster_address: 192.168.1.10:8443
  cluster_token: TOKEN_FROM_NODE1
EOF

# View cluster members
lxc cluster list

# Launch on specific node
lxc launch ubuntu:22.04 container1 --target node2