Getting Started with Linux Containers (LXD/LXC)
LXD provides lightweight Linux containers that behave like full VMs but share the host kernel. Learn to install, configure, launch, manage, and snapshot containers with LXD.
LXD is a container manager for Linux that lets you run isolated Linux environments — each behaves like a full virtual machine but shares the host's kernel, making them much lighter than traditional VMs. Unlike Docker (which runs application processes), LXD containers run a full Linux init system, making them ideal for development environments, testing, and running services that need a complete OS context.
LXC vs LXD
- LXC — the low-level container technology (kernel namespaces + cgroups)
- LXD — the user-friendly management layer built on top of LXC, with a REST API and the
lxcCLI
When you run lxc launch, you're using LXD's CLI (confusingly also called lxc) to manage LXD containers.
Installation
sudo snap install lxd
Add your user to the lxd group so you don't need sudo for every command:
sudo usermod -aG lxd $USER
newgrp lxd
Initial Configuration
Run the interactive setup:
lxd init
For a quick local setup, accept all defaults. For production, you'll configure storage pools and networks. A minimal non-interactive setup:
lxd init --minimal
Launching Containers
# Ubuntu 22.04
lxc launch ubuntu:22.04 my-ubuntu
# Debian 12
lxc launch images:debian/12 my-debian
# Alpine Linux
lxc launch images:alpine/3.19 my-alpine
# Syntax: lxc launch <image> <container-name>
Browse available images:
lxc image list ubuntu: # Ubuntu images
lxc image list images: # community images (many distros)
Managing Containers
lxc list # list all containers and their state
lxc info my-ubuntu # detailed info (IP, PID, resources)
lxc start my-ubuntu
lxc stop my-ubuntu
lxc restart my-ubuntu
lxc delete my-ubuntu # delete stopped container
lxc delete my-ubuntu --force # delete even if running
Accessing a Container
# Open a shell inside the container
lxc exec my-ubuntu -- bash
# Run a single command
lxc exec my-ubuntu -- apt update
# Connect as a specific user
lxc exec my-ubuntu -- su --login ubuntu
File Transfer
# Copy a file into the container
lxc file push local-file.txt my-ubuntu/root/file.txt
# Copy a file out of the container
lxc file pull my-ubuntu/etc/hosts ./hosts-copy
# Edit a file directly
lxc file edit my-ubuntu/etc/hosts
Resource Limits
# Limit memory
lxc config set my-ubuntu limits.memory 512MB
# Limit CPU cores
lxc config set my-ubuntu limits.cpu 2
# Limit CPU time (50% of one core)
lxc config set my-ubuntu limits.cpu.allowance 50%
# View all config
lxc config show my-ubuntu
Snapshots
Snapshots capture the current state of a container so you can roll back if something goes wrong.
# Create a snapshot
lxc snapshot my-ubuntu clean-install
# List snapshots
lxc info my-ubuntu | grep -A5 Snapshots
# Restore a snapshot
lxc restore my-ubuntu clean-install
# Delete a snapshot
lxc delete my-ubuntu/clean-install
Networking
By default, LXD creates a bridged network (lxdbr0) and assigns containers private IPs in the 10.x.x.x range. Containers can reach the internet through NAT; the host can reach containers by their IP.
# View container IP addresses
lxc list --format=table
# Access a web service running in a container from the host
curl http://$(lxc list my-ubuntu --format csv -c 4 | cut -d' ' -f1)
Profiles
Profiles are reusable configuration templates. The default profile is applied to all new containers.
lxc profile list
lxc profile show default
lxc profile create webserver
lxc profile edit webserver # edit in $EDITOR
lxc launch ubuntu:22.04 web01 --profile webserver
Conclusion
LXD containers are an efficient middle ground between bare-metal processes and full virtual machines — full OS isolation with minimal overhead. They're particularly good for running multiple services in separate environments on a single machine without the startup time or memory cost of VMs. For application container workflows, Docker remains the standard; for OS-level isolation, LXD is the right tool.