Introduction to Ubuntu’s LXD Containers

Containers are useful for many reasons. They isolate apps from the rest of the system. They are portable and easy to clone and/or move to other operating systems. And, in the case of Linux, they work the same way under any distribution, with no adaptations necessary. If you need to move a container from RedHat to Ubuntu, it should be just a simple copy operation.

Docker is a popular solution designed to contain a single application: for example, an MySQL database server. LXD is similar in some ways but designed to contain an entire operating system. This makes it useful for some scenarios. For example, you can spin up an LXD container, install a database server and an http server. You can then create a WordPress website inside. You can now switch from cloud to cloud by just moving this LXD container where it’s needed when you’re not happy with your previous provider. And since it’s easy to clone a container, you can even upload your website to multiple cloud providers to create a redundant, high-availability setup.

LXD doesn’t virtualize hardware like QEMU or VirtualBox do, which means it’s very fast, offering near-native speed of execution.

Install and Configure LXD

Open a terminal and install LXD, plus the ZFS utilities, which will help you speed up some operations and save disk space when working with containers.

sudo apt install zfsutils-linux lxd


Start LXD configuration.

sudo lxd init

Press ENTER to select the default values.

For Size in GB of the new loop device (1GB minimum) [default=15GB], you can pick another value, like “50GB” if you know you’ll create a lot of containers.


Find and Launch an LXD Distribution Image

To list all Ubuntu images:

lxc image list ubuntu: arch=amd64


There will be a lot of results. You can ommit arch=amd64 if you need images for other platforms, like ARM processors (Raspberry Pi devices use such architecture).

In the previous picture the results have been limited (with |head) to make it easier to read. The fingerprint of Ubuntu 18.04 (84a71299044b) has been highlighted. If you want to launch a container with that distribution, the command would be:

lxc launch ubuntu:84a71299044b

At the moment this would return a permission denied error. You need to be in the “lxd” group. Your user has been added to this group already, but to make it active you have to log out and log back in. If you want to avoid that, use this command, replacing “user” with your username:

exec su - user


Now, lxc commands work without requiring sudo.

Launch LXD Containers with non-Ubuntu Distributions

This command will show you what other distributions are available:

lxc image list images: arch=amd64

To launch an image, instead of the fingerprint, you can also use an alias name if you see one available in that list.

lxc launch images:debian/9


If you append a string at the end, you can choose a name for your container:

lxc launch images:debian/9 wordpress-site

Manage LXD Containers

To list all containers:

lxc list


The “IPV4” column especially is important if you have any running services on that instance. For example, if an Apache http server would be running on the instance, entering “” in the browser would display the website hosted in the container.

To stop a container:

lxc stop name_of_container

This can take a very long time (or fail) with non-Ubuntu distributions. It’s better to get a shell to the container, and once inside, enter systemctl poweroff to stop it.

If all else fails, you can force a stop with:

lxc stop name_of_container --force

To start it:

lxc start name_of_container

To move inside your container:

lxc shell name_of_container


You can install programs with “sudo apt install” and do anything else you would do on a normal Linux distribution, e.g., configure an Apache server. When you want to exit from the container, simply type:


Transfer Files to/from LXD Containers

To upload a file to your container:

lxc file push /path/to/local/file name_of_container/path/to/uploaded/file

Include the name of the file to be created, not only the directory where you want to upload it. Here is an example:

lxc file push lxd-apt-install.png accurate-colt/var/www/website/upload.png

To upload a directory instead of a file:

lxc file push /path/to/local/directory name_of_container/path/to/remote/directory --recursive --verbose


lxc file push /bin accurate-colt/tmp --recursive --verbose

To download a directory from your container to your main operating system:

lxc file pull name_of_container/path/to/remote/directory /path/to/local/directory --recursive --verbose


lxc file pull accurate-colt/tmp /tmp --recursive --verbose


This covers the basic usage of LXD containers. There are more advanced features such as snapshots and rollbacks, imposing limits on resources such as CPU and RAM, cloning containers, and so on. These may be covered in a future tutorial if we notice readers are interested in the subject.

Alexandru Andrei

Fell in love with computers when he was four years old. 27 years later, the passion is still burning, fueling constant learning. Spends most of his time in terminal windows and SSH sessions, managing Linux desktops and servers.

Subscribe to our newsletter!

Our latest tutorials delivered straight to your inbox