Setting up a test LXD environment on Ubuntu 16.04

June 4, 2016 by

This is a quick start guide to getting a fully functional LXD (lex-dee) test/dev environment set up on Ubuntu 16.04 Server. For the best experience, LXD works best if you have a bare metal machine to install it on, like a laptop already running Ubuntu 16.04. To some extent, you can think of LXD as a replacement for virtualization packages like VirtualBox, VMware and KVM. For testing purposes, however, it will work perfectly well to install LXD in a virtual machine, but the resulting double-NATted networking can prove a bit challenging.

LXD is a container technology. If you’re familiar with LXC, LXD is basically the next generation of LXC with a lot of enhancements. LXD isn’t a direct competitor to Docker, but rather a complement. You can run Docker with and along side of LXD. For a great overview with lots of specific examples, check out Stéphane Graber’s excellent twelve-piece series on LXD.

We will install and configure LXD, ZFS and bridge utils on Ubuntu 16.04 Server. (We won’t actually use bridge utils, but we’re installing the package just in case you want to use it later.)

For container storage we will configure LXD to use a loopback device for ZFS. For networking simplicity, we will use LXD’s lxdbr0, which creates a NAT bridge and provides DHCP to the containers as you create/start them.

A standard installation of Ubuntu 16.04 Server comes with LXD by default, so we don’t actually need to install it. However, we do want ZFS and bridge utils. For your ZFS setup, you’re going to want some amount of space on which to store your container images. You can also use a separate disk for ZFS if you happen to have one.


Let’s install the necessary packages:

ubuntu@lxd01:~$ sudo apt install lxd zfsutils-linux bridge-utils


Now that we have the necessary packages installed, before we can set up containers, we have to configuring the storage and networking for LXD. As mentioned, we will use a loopback device for ZFS and LXD’s built-in bridge along with NAT and DHCP.

Start the configuration of LXD by running sudo lxd init like so:

ubuntu@lxd01:~$ sudo lxd init
Name of the storage backend to use (dir or zfs): zfs
Create a new ZFS pool (yes/no)? yes
Name of the new ZFS pool: lxd-loop
Would you like to use an existing block device (yes/no)? no
Size in GB of the new loop device (1GB minimum): 10
Would you like LXD to be available over the network (yes/no)? no
Do you want to configure the LXD bridge (yes/no)? yes
Warning: Stopping lxd.service, but it can still be activated by:

Give the ZFS loop device (Size in GB) as much space as you can afford. While it’s possible to expand a ZFS partition, it’s definitely easier to give it as much space as possible during setup.

LXD should now be successfully configured and you should be able to download container images and start new containers.

Setup verification


With our bridge set up, our ZFS storage backend created and LXD fully configured, it’s time to test everything is working as it should be.

Check out your ZFS storage pool with sudo zpool list:

ubuntu@lxd01:~$ sudo zpool list
lxd-pool  9.94G  1.35G  8.59G         -     8%    13%  1.00x  ONLINE  -


Verify that your LXD networking is set up properly using lxc profile show default:

ubuntu@lxd01:~$ lxc profile show default
name: default
config: {}
description: Default LXD profile
    name: eth0
    nictype: bridged
    parent: lxdbr0
    type: nic

Download and start container images

Get a few containers downloaded and started with the lxc launch command. The last argument in the command below is the name of the container.

Ubuntu 16.04

The below command will download and start an Ubuntu Xenial (16.04) 64-bit (amd64) container image named ‘xenial‘.

ubuntu@lxd01:~$ lxc launch images:ubuntu/xenial/amd64 xenial

The output should look similar to:

ubuntu@lxd01:~$ lxc launch images:ubuntu/xenial/amd64 xenial
Creating xenial
Retrieving image: 100%
Starting xenial

Alpine Linux

The below command will download and start an Alpine Edge 64-bit (amd64) container image named ‘alpine‘.

ubuntu@lxd01:~$ lxc launch images:alpine/edge/amd64 alpine

Accessing the container

Lastly, to enter the container we just created, simply use the lxc exec <containerName> bash command, like:

ubuntu@lxd01:~$ lxc exec xenial bash

… assuming bash is installed. For Alpine, use lxc exec <containerName> sh since bash is not installed in Alpine Linux by default.

And from here on out, it should all probably seem fairly familiar.

For a summary of useful LXC/LXD commands, see my follow-up article LXD commands.

Comments (1)


  1. tporter says:

    Just getting started as a micro business and came aVDI brokercross your tutorial here doing some research on LXD. I’d fooled around with LXC via 14.04 but this is my first taste of the LXD version. So far, I LOVE it!
    Your instruction here were absolutely flawless an I spun up a 400 GB test machine on ESXi 6. I’d like to find a good VDI/BRoker for desktops using LXD or something similar. Know any???

Leave a Reply