โ† Back to Tutorials
27 May 2026ยท4 min read

LXD/LXC Containers on Ubuntu: A Hands-On Guide

Install LXD on Ubuntu 24.04 and launch lightweight system containers: networking, storage, snapshots, resource limits, and how LXC differs from Docker.

LXD gives you system containers: lightweight instances that behave like a full Linux machine โ€” their own init system, users, and services โ€” but share the host kernel, so they boot in seconds and use a fraction of a VM's resources. On Ubuntu 24.04, LXD is the native, Canonical-supported way to run them, sitting neatly between heavyweight KVM VMs and single-process Docker containers.

This hands-on guide installs LXD, launches your first container, and covers the everyday operations: networking, storage, snapshots, and resource limits. Along the way it explains how system containers differ from application containers like Docker, so you know which tool fits which job.

LXC vs LXD vs Docker

LXC is the low-level Linux container runtime. LXD is the modern management layer on top of it โ€” an image store, a REST API, and the friendly lxc client. Docker, by contrast, packages a single application process per container. Rule of thumb: reach for LXD when you want a persistent, VM-like environment; reach for Docker when you want to ship a stateless app, and for KVM when you need a different kernel or hard isolation.

Prerequisites

You need Ubuntu 24.04 with a sudo-capable user and a few gigabytes of free disk. LXD ships as a snap on Ubuntu, which is the supported install path here (unlike Docker, where the snap is best avoided).

Step 1: Install and initialise LXD

Install the LXD snap and add yourself to the lxd group so you can run the client without sudo:

sudo snap install lxd
sudo usermod -aG lxd $USER
newgrp lxd

Run the guided initialiser. The defaults are sensible for a single host โ€” it sets up a storage pool (ZFS or dir) and a default bridge network:

lxd init --minimal

For full control over storage backend, networking, and clustering, run lxd init without --minimal and answer the prompts.

Step 2: Launch your first container

Launch an Ubuntu 24.04 system container named web1 from the official image server:

lxc launch ubuntu:24.04 web1
lxc list

Expected output shows the container RUNNING with an IPv4 address from the LXD bridge:

+------+---------+----------------------+------+-----------+-----------+
| NAME |  STATE  |         IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+----------------------+------+-----------+-----------+
| web1 | RUNNING | 10.x.x.10 (eth0)     |      | CONTAINER | 0         |
+------+---------+----------------------+------+-----------+-----------+

Step 3: Work inside the container

Get an interactive shell, or run one-off commands without entering the container:

lxc exec web1 -- bash
lxc exec web1 -- apt update

Copy files in and out, and push a whole directory:

lxc file push ./index.html web1/var/www/html/index.html
lxc file pull web1/etc/hostname ./hostname.txt

Step 4: Networking

By default containers sit behind a NAT bridge (lxdbr0). To expose a service, forward a host port to the container, or attach the container to your LAN with a bridged profile:

lxc config device add web1 http proxy \
  listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80

lxc network list

For direct LAN access, attach the container to a host bridge โ€” see our guide on Linux bridge networking for the bridge setup itself.

Step 5: Storage and resource limits

List storage pools and add a dedicated data volume to a container:

lxc storage list
lxc storage volume create default web1-data
lxc config device add web1 data disk 
pool=default source=web1-data path=/data

Cap CPU and memory so one container cannot starve the host โ€” applied live:

lxc config set web1 limits.cpu 2
lxc config set web1 limits.memory 1GiB
lxc config show web1 | grep limits

Step 6: Snapshots and restore

Snapshots are instant and cheap on a copy-on-write backend. Take one before a risky change, list them, and restore:

lxc snapshot web1 before-upgrade
lxc info web1 | grep -A3 Snapshots
lxc restore web1 before-upgrade

To clone a container into a ready-made template for repeatable environments:

lxc copy web1 web1-template
lxc publish web1 --alias web-baseline

Step 7: Lifecycle and cleanup

Stop, start, and delete containers cleanly:

lxc stop web1
lxc start web1
lxc delete web1 --force

Troubleshooting and pitfalls

  • โ€˜permission deniedโ€™ running lxc โ€” you have not re-logged in after the group change; run newgrp lxd or start a new session.
  • No IPv4 on the container โ€” lxdbr0 did not get a subnet; re-run lxd init or check lxc network show lxdbr0.
  • โ€˜storage pool not foundโ€™ โ€” you skipped initialisation; LXD needs at least one pool from lxd init.
  • Trying to run a different kernel โ€” system containers share the host kernel; if you need a different one, use a KVM VM instead.

Where to go next

System containers are one of three complementary tools. For stateless application packaging continue to installing Docker on Ubuntu 24.04; for full hardware-level isolation see installing KVM/QEMU.

Conclusion

LXD delivers VM-like environments at container speed, with snapshots, storage, and networking managed through one clean CLI โ€” ideal for dev environments, CI runners, and consolidating lightweight services. Choosing and operating the right mix of containers and VMs across a fleet is part of what a private cloud platform does for you. clouditiv runs a sovereign, ISO 27001 / BSI C5 private cloud on Ubuntu 24.04 + OpenStack 2025.2, with your data staying in Germany โ€” so your team builds on the right primitives without maintaining the plumbing. See our on-premise cloud solution.