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.

LXD (System Container)Host OSShared Linux KernelContainerFull Guest OS (systemd, etc)Apps + ServicesDocker (Application Container)Host OSShared Linux KernelContainer 1App 1 + LibsContainer 2App 2 + LibsPhysical Hardware

2. Installation & Initialization

2.1 Installation

First, ensure your system has snap installed and enabled.

snap version

Install LXD via snap (the officially recommended method, which handles automatic updates and all dependencies).

sudo snap install lxd
snap info lxd

Note: 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 -y

2.2 Initialization

After installation, run the interactive initialization wizard to configure LXD.

sudo lxd init

The wizard will guide you through configuring storage pools, networking, image servers, and more. Here are some common recommendations:

  • Storage: For beginners, dir is recommended (the simplest, uses a directory directly), or zfs (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 lxdbr0 and 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 -- bash

4.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-container

5. 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-base

6. 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.

Host Machineeth0192.168.1.10To LANNATlxdbr0 Bridge10.0.1.1/24Outbound OKInbound BlockedInternetContainer 110.0.1.11Container 210.0.1.12

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:80

6.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.

Host Machineeth0192.168.1.10Container 1 (macvlan)192.168.1.11Container 2 (macvlan)192.168.1.12Physical Network Switch (LAN)⚠️ No Host-Container Link
# Replace 'eno1' with your host's physical network interface name
lxc config device add my-container eth0 nic nictype=macvlan parent=eno1

7. 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.

Host MachineFolder/datafile.txtContainerMount Point/mnt/datafile.txtmounts
# Mounts /data on the host to /mnt/data inside the container
lxc config device add my-container data-disk disk source=/data path=/mnt/data

8. 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=2GiB

8.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=true

8.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.0

9. 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-only

10. 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=true when absolutely necessary.
  • Network Security: When exposing services to the public internet, it's recommended to use a proxy device or place a reverse proxy in front.

12. FAQ & Troubleshooting

Container can't access the internet?
Check lxdbr0 DHCP; check if the host firewall (ufw) is blocking forwarding. Try: sudo ufw allow in on lxdbr0, or set DEFAULT_FORWARD_POLICY="ACCEPT" in /etc/default/ufw.
Port forwarding not working?
Check the listen address; 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 install openssh-server inside 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/html

13.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-smi

14. Recommended Learning Path

  1. Getting Started: Run through the basic flow: Install -> lxd init -> Create Container/VM.
  2. Core Skills: Master proxy port forwarding, mounting storage directories, and snapshots/restoration.
  3. Advanced: Learn to use Profiles + cloud-init to standardize and automate your environment deployments.
  4. Expansion: Understand the concept of Projects for multi-project isolation.
  5. On-demand Deep Dive: When specific needs arise, explore topics like GPU passthrough, multi-node clustering, etc.