Getting Started With LXD containers on Ubuntu 16.04

Why LXD?

It’s no secret that containers are hot right now in the Linux world. They are quickly becoming the backbone of the Cloud and are making DevOps dreams come true. Even so, at first glance, it seems a bit redundant for Canonical to develop a new container system for Ubuntu in a world easily dominated by Docker. So why, then, did they do it? To fill a middle ground between traditional virtual machines and Docker. Canonical said it themselves, “By combining the speed and density of containers with the security of traditional virtual machines, Canonical’s LXD is the next‐generation of container hypervisor for Linux.” Not only that, but Docker containers can be run within LXD containers, adding another dimension to potential container configurations.

LXD is an enhancement of the existing LXC Linux container hypervisor with it’s own toolset, sharing a similar relationship to the original project as Ubuntu does with Debian with the goal of taking existing great software and streamlining it for easier use. On Canonical’s latest Ubuntu LTS release, 16.04, LXD is well integrated and easy to use with clear and concise CLI tools that make container creation and management seamless.

Initial Setup

Getting started with LXD on Ubuntu 16.04 is as close to effortless as could be expected. Canonical condensed the install to a single package, making this a one command install. A simple sudo apt-get install lxd will get everything needed to get started.

Install LXD with apt-get install lxd

In order to add the user to the ‘lxd’ group in order to be able to execute the needed commands without a restart, run newgrp lxd. After that, everything will be clear to proceed with the setup of the LXD hypervisor. Running sudo lxd init begins the setup process.

Initializing LXD Setup

The initial setup process consists of a series of command line prompts asking for basic information needed to configure the LXD hypervisor. The process is all very straightforward and asks for information like storage type, IP address, port number, password, and whether or not the connection is bridged.

Basic LXD setup questions

After that series of prompts, the setup shifts to a text based interface with a series of questions about the networking configuration of the LXD hypervisor. The process creates bridged IPv4 and IPv6 networks complete with custom subnets and DHCP. This way, LXD acts as a virtual router for all of the containers deployed on it and provides a single point of configuration for these virtual networks.

Clearly, this is one of those times where LXD shines as a “best of both worlds” solution. Of course, it’s also nice that Canonical provides a Debian style configuration menu to walk through the process and make it almost mindlessly easy. Once the configuration finishes, it dumps back out to the command line and provides a short message saying that it has been successful.

LXD success message

LXD Images and Containers

Setting Up A Container

Like Docker, LXD is image based. It provides three main options for obtaining images; remote, built-in, and local imports. There are several remote sources that come with LXD out of the box as well as the local sources. To see what sources are available, just run lxc remote list, and you will be presented with a convenient command line table displaying information about currently available sources.

LXD source listing

For the purposes of this article, the local sources seemed to be the best and easiest option. There are clean Ubuntu images provided that make a great starting point for any deployment. This is another one of those “best of both worlds” moments. Instead of having a stripped down container tailored to running a single application, LXD containers are closer to a full-fledged virtual machine.

They come complete with command line access and even the ability to install packages. At the same time LXD provides excellent command line tools to manage containers and even push and pull files to and from them. To spin up an Ubuntu 16.04 container, just run lxc launch ubuntu:16.04 name-of-container. LXD will fetch the image, create a container, and start the container.

Creating a container in LXD

Working With LXD Containers

It’s easy to check the status of the container with lxc list. Starting and stopping containers is just as easy with lxc stop name-of-container and lxc start name-of-container.

Listing containers in LXD

One of the clear benefits of LXD over traditional containers like Docker is the ability to edit running containers and update them rather than packing up a container, deploying it, and leaving it alone. If it’s a matter of passing files between the host system and containers, LXD has push and pull commands that allow files to be passed back and forth. If something more involved is needed, LXD provides a great command line tool for accessing running containers and getting a full shell. In order to get access to the shell of a container run, lxc exec name-of-container -- /bin/bash.

LXD containers have a full filesystem

In the container’s shell there is a full Linux filesystem, and the the command line has access to whichever tools were bundled with the image or installed on the containers later. This allows LXD containers to run updates and multiple applications, including Docker. This way, a DevOps engineer could deploy an LXD container running a database and web server as well as Docker with several web applications running in Docker containers.
Of course, that is just one of many possibilities, but the key aspect here is that LXD adds another layer to the equation and provides more flexibility when configuring a software stack.


It’s clear from even this most basic trial with LXD that Canonical did meet their goal in creating a clear middleground between full Linux virtualization and Docker containers. LXD is a tool that DevOps engineers should seriously consider adding to their toolbox.