Starting the project
The first thing to do is to create a general snaps directory followed by a working directory for this specific snap project:
$ mkdir -p ~/mysnaps/hello
$ cd ~/mysnaps/hello
It is from within this
hello directory where we will invoke all subsequent commands.
NOTE: Due to a limitation in the project we’re going to build, the path of the directory you put the
hello directory in shouldn’t contain any spaces.
Get started by initialising your snap environment:
$ snapcraft init
This creates a
snapcraft.yaml in which you declare how the snap is built and which properties it exposes to the user. We will edit this later.
The directory structure now looks like this:
Note: Any future snaps you want to create should be put within their own directory under
Describing the snap
Let’s take a look at the top part of your snapcraft.yaml file. It should look somewhat as shown below:
name: my-snap-name # you probably want to 'snapcraft register <name>'
base: core18 # the base snap is the execution environment for this snap
version: '0.1' # just for humans, typically '1.2+git' or '1.3.2'
summary: Single-line elevator pitch for your amazing snap # 79 char long summary
This is my-snap's description. You have a paragraph or two to tell the
most important story about your snap. Keep it under 100 words though,
we live in tweetspace and your description wants to look good in the snap
grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots
This part of
snapcraft.yaml is mandatory and is basic metadata for the snap.
Let’s go through this line by line:
name: The name of the snap.
base: A foundation snap that provides a run-time environment with a minimal set of libraries that are common to most applications. The template defaults to using
core18, which equates to Ubuntu 18.04 LTS. See Base snaps for further options.
version: The current version of the snap. This is just a human readable string. All snap uploads will get an incremental snap revision, which is independent from this version. It’s separated so that you can upload multiple times the same snap for the same architecture with the same version. See it as a string that indicates to your user the current version, like “stable”, “2.0”, etc.
summary: A short, one-line summary or tag-line for your snap.
description: A longer description of the snap. It can span over multiple lines if prefixed with the ‘|’ character.
grade: Can be used by the publisher to indicate the quality confidence in the build. The store will prevent publishing ‘devel’ grade builds to the ‘stable’ channel.
confinement: A snap’s confinement level is the degree of isolation it has from your system, and there are three levels:
devmode. strict snaps run in complete isolation,
classic snaps have open access to system resources and devmode snaps run as strict but with open access to the system. The latter is ideal for development, but your snap will need move from devmode to be published. See Snap confinement for more details.
In this tutorial, we will focus on
For more detailed information on this top-level metadata, see Adding global metadata.
And that’s it for the basics. It’s now time to customise the snapcraft.yaml file for our own snap. Taking the above into account, we can change the top of the file to be:
summary: GNU Hello, the "hello world" snap
GNU hello prints a friendly greeting.
Note: Version information is for snap user consumption only, and has no effect on snap updates. It’s defined within quotes, (
'2.10'), because it needs to be a YAML string rather than a floating-point number. Using a string allows for non-numeric version details, such as ‘
myfirstversion’ or ‘
Adding a part
Parts are used to describe your application, where its various components can be found, its build and run-time requirements, and those of its dependencies. A snap consists of one or more parts, depending on its complexity.
Here are a few multiple-part snap examples:
- snaps with separate logical parts, such as a server snap containing a web server, a database and the application itself
- a game which ships the game engine and game data for three different games, each one being defined in its own part
- snaps with parts from different locations - parts which are built in a different way
hello snap will be nice and simple. It will consist of only one part for now. In the following pages we are going to gradually extend it.
Two must-haves for every part are the ‘source’ and ‘plugin’ definition. Think of these as the “what” and the “how”, respectively. As source you can, for example, pick a source repository (like
git), a tarball, or a local directory. Snapcraft supports many plugins, allowing you to build a wide variety of project types (e.g. autotools, cmake, go, maven, nodejs, python2, python3).
hello, add the following ‘parts’ stanza to your
snapcraft.yaml file (replace anything else that might be there):
So we have added a part called
gnu-hello (its name is arbitrary). For ‘source’, we specified a tarball located on the GNU project’s FTP server. As ‘plugin’ we’ve chosen
autotools which uses the traditional
./configure && make && make install build steps.
See Supported plugins, or run
snapcraft list-plugins, to get more information on which build-tools and platforms Snapcraft supports.
To build our snap all you need to do is:
The first time you run snapcraft, you may be asked for permission to install Multipass. Snapcraft uses Multipass to both simplify the build process and to confine the build environment within a virtual machine. It offers the best build experience, so we highly recommend answering ‘y’. However, if you’d rather not use Multipass, you can also build natively, remotely, and with LXD. See Build options for details.
During the build, snapcraft will show plenty of output, however a successful build will end with:
+ snapcraftctl stage
+ snapcraftctl prime
Congratulations! You’ve just built your first snap, which is now ready to be installed:
$ sudo snap install --devmode hello_2.10_amd64.snap
The output should declare:
hello 2.10 installed
To get some info on the installed snap:
$ snap list hello
Name Version Rev Tracking Publisher Notes
hello 2.10 x1 - - devmode
Let’s try to execute it:
On traditional Ubuntu you will get:
The program 'hello' can be found in the following packages:
Try: sudo apt install <selected package>
Or you might get a different error if you previously installed the
bash: /snap/bin/hello No such file
The command doesn’t exist despite being part of our snap and installed! Indeed, snaps don’t expose anything to the user by default (command, services, etc.). We have to do this explicitly and that’s exactly what you are going to tackle next!
If it does work for you, you should verify that it’s the correct
hello command. Check the output of
which hello - it might list something like
/usr/bin/hello. What we’re after is a binary under the