LXD on Ubuntu Quickstart
This guide focuses on the most essential commands and operations to help you get started with LXD in the shortest amount of time.
Default Environment: Ubuntu 22.04/24.04 | LXD Version: snap (officially recommended)
1. What is LXD & Use Cases
LXD is a modern, secure, and powerful system container and lightweight VM manager. Its core underlying technologies are LXC (for containers) and QEMU (for virtual machines).
Core Differences from Docker
LXD is more like a "lightweight virtual machine manager". The instances it creates have a full operating system environment (independent init, systemd, SSH services, etc.), making it feel like managing a real physical machine or cloud server. In contrast, Docker focuses more on "packaging and running a single process or application", where the container's lifecycle is tied to the application process, aiming for extreme lightness and portability.
2. Installation & Initialization
2.1 Installation
First, ensure your system has snap installed and enabled.
snap versionInstall LXD via snap (the officially recommended method, which handles automatic updates and all dependencies).
sudo snap install lxd
snap info lxdNote: Clean Up Old Versions
If your system previously had the apt package version of LXD installed, be sure to uninstall it completely to avoid conflicts.
sudo apt remove --purge lxd lxd-client -y
sudo apt autoremove -y2.2 Initialization
After installation, run the interactive initialization wizard to configure LXD.
sudo lxd initThe wizard will guide you through configuring storage pools, networking, image servers, and more. Here are some common recommendations:
- Storage: For beginners,
diris recommended (the simplest, uses a directory directly), orzfs(powerful, with high performance for snapshots/copies). If you don't have a separate disk partition, the wizard can create a loop-based ZFS pool for you. - Network: Choose to create the default bridge
lxdbr0and enable automatic NAT and DHCP. This is the most hassle-free, out-of-the-box option. - Images: Keep the default to use the official
images:remote source. - VM Support: It's recommended to enable this (yes), which will be very convenient if you need to create virtual machines later.
3. Quick Glossary of Basic Concepts
- Instance
- A generic term for containers and virtual machines (VMs).
- Image
- The template for creating instances, e.g.,
ubuntu/22.04. - Profile
- A reusable set of configurations, like network cards, storage, resource limits, etc.
- Storage Pool
- Defines where instance disks are stored and the backend driver (zfs/btrfs/dir).
- Network
- Network resources managed by LXD, such as bridged NAT, macvlan, etc.
- Project
- An isolated namespace for resources, suitable for multi-tenant or multi-project scenarios.
4. Getting Started Quickly (Containers & VMs)
4.1 Creating and Accessing a Container
# Find an Ubuntu image
lxc image list images: ubuntu
# Launch a container named 'my-container' from an Ubuntu 22.04 image
lxc launch images:ubuntu/22.04 my-container
# List all running instances
lxc list
# Get a shell inside the container
lxc exec my-container -- bash4.2 Creating and Using a VM
# Launch a VM (note the --vm flag and 'cloud' image variant)
lxc launch images:ubuntu/22.04/cloud my-vm --vm
# Access the VM's console
lxc console my-vm
# Push a local file into the container
lxc file push ./local.txt my-container/root/
# Pull a file from the container to the current directory
lxc file pull my-container/etc/os-release .4.3 Basic Lifecycle Management
lxc stop my-container
lxc start my-container
lxc restart my-container
lxc delete my-container
# Get detailed info about an instance
lxc info my-container5. Image Management
# List available remotes (image sources)
lxc remote list
# List available ubuntu images from the 'images:' remote
lxc image list images: ubuntu
# Create a new image from an existing container
lxc publish my-container --alias my-base-image --compression=xz
# Export an image to a file
lxc image export my-base-image ./my-base.tar.xz
# Import an image from a file
lxc image import ./my-base.tar.xz --alias my-new-base6. Networking & Port Forwarding
6.1 Default Bridge Network (NAT)
The lxdbr0 created by lxd init is a NAT network. Instances can access the external network, but the outside world cannot directly access the instances.
6.2 Port Forwarding (proxy device)
This is the common method for mapping a host port to a service inside an instance. Example: Forward the host's port 8080 to port 80 of the my-container container.
lxc config device add my-container webproxy proxy \
listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:806.3 macvlan (Connecting Instances Directly to the Physical Network)
Using macvlan mode, an instance can obtain an IP address on the same subnet as the host, just like an independent physical machine. This is suitable for scenarios requiring direct access from the local network.
# Replace 'eno1' with your host's physical network interface name
lxc config device add my-container eth0 nic nictype=macvlan parent=eno17. Storage
7.1 Creating a Storage Pool
# Create a new 50GB ZFS storage pool
lxc storage create zpool zfs size=50GB
# Make the new pool the default for new instances
lxc profile device set default root disk pool=zpool path=/7.2 Mounting a Host Directory
This is a very useful feature for easily sharing data.
# Mounts /data on the host to /mnt/data inside the container
lxc config device add my-container data-disk disk source=/data path=/mnt/data8. Configuration & Profiles
8.1 Resource Limits
# Limit to 2 CPU cores
lxc config set my-container limits.cpu=2
# Limit to 2GB of memory
lxc config set my-container limits.memory=2GiB8.2 cloud-init (Automated Initialization)
With cloud-init, you can automatically perform initial setup tasks like updates, software installation, and running commands when creating an instance.
lxc launch images:ubuntu/22.04 my-web -c user.user-data="$(cat <<'EOF'
#cloud-config
package_update: true
packages:
- nginx
runcmd:
- [ systemctl, enable, --now, nginx ]
EOF
)"8.3 Nested Containers (Nesting)
lxc config set my-container security.nesting=true
# Required for running Docker inside
lxc config set my-container security.privileged=true8.4 GPU Passthrough (NVIDIA)
Allows an instance to directly use the host's NVIDIA GPU. The host machine must have the NVIDIA drivers pre-installed.
# For containers
lxc config device add my-container gpu gpu
# For VMs (example PCI address)
lxc config device add my-vm gpu0 gpu pci=0000:01:00.09. Backups, Snapshots & Migration
# Create a snapshot
lxc snapshot my-container snap1
# Restore from a snapshot
lxc restore my-container snap1
# Create a full backup
lxc export my-container ./my-container-backup.tar.gz
# Add another LXD server as a remote
lxc remote add target-server 10.0.0.2:8443
# Copy/move an instance to another server
lxc copy my-container target-server:my-container-copy --instance-only10. Multi-node Clustering (Optional)
LXD supports grouping multiple physical machines into a cluster to manage resources across all nodes centrally. This is an advanced feature suitable for production environments or large-scale deployments.
# On the first node, initialize as a cluster
sudo lxd init --preseed ...
# On other nodes, join the cluster
lxc cluster add node2
...11. Security & Isolation
- Unprivileged Containers (Default): This is a core security feature of LXD. Through uid/gid mapping, the root user inside a container is just a regular user on the host, greatly enhancing isolation.
- Kernel Security Modules: LXD enables multiple layers of Linux kernel security mechanisms by default, such as seccomp, AppArmor, namespaces, and cgroups.
- Privileged Containers: Only set
security.privileged=truewhen absolutely necessary. - Network Security: When exposing services to the public internet, it's recommended to use a
proxydevice or place a reverse proxy in front.
12. FAQ & Troubleshooting
- Container can't access the internet?
- Check
lxdbr0DHCP; check if the host firewall (ufw) is blocking forwarding. Try:sudo ufw allow in on lxdbr0, or setDEFAULT_FORWARD_POLICY="ACCEPT"in/etc/default/ufw. - Port forwarding not working?
- Check the
listenaddress; check if the host port is already in use (sudo ss -tulpn); check the service's listening address inside the container. - How to SSH into a container?
- The preferred method is
lxc exec. If you need SSH, you must installopenssh-serverinside the container and set up port forwarding.
13. Practical Examples
13.1 Launch an Nginx Website in 5 Minutes
lxc launch images:ubuntu/22.04 my-web
lxc exec my-web -- apt update && apt install -y nginx
lxc config device add my-web web proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
sudo mkdir -p /srv/webroot && echo "Hello from LXD" > /srv/webroot/index.html
lxc config device add my-web www disk source=/srv/webroot path=/var/www/html13.2 Run Docker in a Lightweight VM
lxc launch images:ubuntu/24.04/cloud docker-vm --vm -c limits.cpu=2 -c limits.memory=4GiB
lxc exec docker-vm -- bash -c "apt update && apt install -y docker.io"13.3 GPU Inference (Container)
lxc launch images:ubuntu/22.04 llm-container
lxc config device add llm-container gpu gpu
lxc exec llm-container -- apt update && apt install -y nvidia-utils-535
lxc exec llm-container -- nvidia-smi14. Recommended Learning Path
- Getting Started: Run through the basic flow: Install ->
lxd init-> Create Container/VM. - Core Skills: Master proxy port forwarding, mounting storage directories, and snapshots/restoration.
- Advanced: Learn to use Profiles + cloud-init to standardize and automate your environment deployments.
- Expansion: Understand the concept of Projects for multi-project isolation.
- On-demand Deep Dive: When specific needs arise, explore topics like GPU passthrough, multi-node clustering, etc.