Build on LXD

Building snaps within an isolated environment, such as LXD, has several advantages over a native build:

  • containers keep your host system clear of your new snap’s dependencies
  • your host system can’t expose conflicting libraries to your new snap build

Read on to discover how to build snaps with LXD.

Install LXD

Recent non-desktop versions of Ubuntu install LXD by default - you can check whether it is installed with the following command:

$ lxd version
3.7

The easiest way to add LXD to your system is via its snap:

$ sudo snap install lxd

Now initialise LXD with the following command, accepting all the default options unless you have specific requirements:

$ sudo lxd init

If the system you are installing LXD onto is using a network with a 10.x.x.x subnet then network create may fail. Step through the following to resolve this.

Manually create a network on a 10.x.x.x subnet

If you try to run lxd init on a system that is connected to a network with a 10.x.x.x subnet, then the final step of the Iinit* may fail with the following error:

Error: Failed to create network 'lxdbr0': Failed to automatically find an unused IPv4 subnet, manual configuration required

To resolve this issue, you must manually create the network with the following command:

$ sudo lxc network create lxdbr0 ipv4.address=10.0.3.1/24 ipv4.nat=true

You can then re-run lxd init. When you are prompted to create a new network bridge you must respond no.

Would you like to create a new network bridge (yes/no) [default=yes]? no

Group permissions

If you want to build snaps as a non-root user, which is advised, then you need to add your user account to the lxd group:

$ sudo usermod -g lxd ${USER}

You now need to either restart your session, reboot your computer, or use newgrp to acquire the new group assignment:

$ newgrp lxd

The newgrp command will start a new sub-shell (shell within a shell) with the new lxd group assigned.

Building

If snapcraft is not yet installed, enter sudo snap install snapcraft --classic.

To build your project using lxd run:

$ cd $HOME/my-snap-project
$ snapcraft cleanbuild

If the build fails, add the --debug option to the snapcraft cleanbuild command. This will drop you into a shell running within the LXD environment that just attempted to build your snap, allowing you to examine where the issue may be.

Experimental: persistent containers

When building with LXD, the old container is discarded. This means that LXD needs to build a new environment, each time you build your snap. This is acceptable with small snaps, or for a final build, but can be problematic during development.

For example, during development, you might normally use:

$ snapcraft
$ snap try prime

The ‘try’ method allows you to directly edit files in a snap’s prime directory without having to re-install or re build after each change. However, when using cleanbuild, this feature is not supported.

But there is an experimental feature that uses LXD in a different way, allowing you to retain intermediate files, and the container:

$ export SNAPCRAFT_BUILD_ENVIRONMENT=lxd 
$ snapcraft

If you get the following error:

Failed to start container: the local folder could not be mounted into the container. 

Add a line containing root:1000:1 to the following files:

  • /etc/subuid
  • /etc/subgid

You may need to log out and back in again before reattempting the build. If successful, you can now try the snap, make changes, and rebuild quickly:

$ snap try prime

The environment variable SNAPCRAFT_BUILD_ENVIRONMENT instructs snapcraft to use experimental LXD integration to build the snap in a persistent LXD container. This container remains after the build has finished, and retains intermediate build files to speed up rebuilds.

Last updated 19 days ago. Help improve this document in the forum.