Snapcraft, the snap-building tool, is designed to use a combination of Multipass and bases to both simplify the build process and to confine the build environment within a virtual machine. This mostly removes the need to use LXD.
ⓘ See Snapcraft overview for details on both Multipass and bases
Snapcraft can also use LXD, and it’s often a faster alternative.
-
If you are using bases and Snapcraft version 3.4+ you can request to use LXD with the
--use-lxd
argument:$ snapcraft --use-lxd
You can also set
SNAPCRAFT_BUILD_ENVIRONMENT=lxd
to use LXD by default. -
If your snapcraft.yaml doesn’t use bases, you should continue using
snapcraft cleanbuild
.
See below for help on installing LXD, manually building snaps within an LXD environment and building without bases.
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.13
The easiest way to add LXD to your system is via its snap:
$ sudo snap install lxd
On recent versions of Ubuntu, the deb package encapsulates the snap installation.
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 init* 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 -a -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 with bases
Snapcraft with LXD operates in much the same way as snapcraft with a default Multipass environment. However, with LXD installed and configured, you need to manually add the --use-lxd
argument to initiate the build within LXD, or set the SNAPCRAFT_BUILD_ENVIRONMENT=lxd
environment variable.
$ snapcraft --use-lxd
Many of the snapcraft’s Multipass operations also work with LXD, including:
--shell
--shell-after
--debug
Similarly, snapcraft’s lifecycle commands, pull, build, stage and prime, together with clean, can also use the --use-lxd
option.
$ snapcraft clean --use-lxd
The LXD provider is offered as a technology preview for early adopters.
The command line interface, container names or lifecycle handling may change in upcoming releases.
Building without bases
ⓘ 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
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.
Building manually
These instructions are intended to be only a general guide. For further details on using LXD as a container environment, see the LXD Documentation.
First, create and run a new container based on Ubuntu 18.04 LTS (Bionic Beaver). Our example calls this container mysnapcraft:
$ lxc launch ubuntu:18.04 mysnapcraft
Copy your snap’s snapcraft.yaml to this new container:
$ lxc file push snap/snapcraft.yaml mysnapcraft/home/ubuntu/
Now open an interactive shell within your container and install snapcraft:
$ lxc exec mysnapcraft -- /bin/bash
$ snap install snapcraft --classic
Finally, staying within the container, start the build by running snapcraft with the --destructive-mode
argument. This forces snapcraft to build the snap directly within the current host (the mysnapcraft LXD container):
$ cd /home/ubuntu
$ snapcraft --destructive-mode
You can troubleshoot the build process just as you would on the native machine. The container is persistent and will remain until stopped and deleted.
With the build complete, you can copy your new snap to your native environment with the following command:
$ lxc file pull mysnapcraft/home/ubuntu/mysnap.snap .