Faster to install
Snaps are faster to install, easier to create, safer to run, and they update automatically and transactionally so your app is always fresh and never broken.
Snaps aim to work on any distribution or device, from IoT devices to servers, desktops to mobile devices.
GitHub and beyond
The public collection of snaps includes the best of GitHub and beyond, so you have the whole world of Linux at your fingertips.
How do snaps work?
A snap is a fancy zip file containing an application together with its dependencies, and a description of how it should safely be run on your system, especially the different ways it should talk to other software.
Most importantly snaps are designed to be secure, sandboxed, containerised applications isolated from the underlying system and from other applications. Snaps allow the safe installation of apps from any vendor on mission critical devices and desktops.
Try this (you may need to install snapd)
$ sudo snap install hello-world
Now you have installed a snap. You can take a look inside the snap very easily, it shows up as a new directory on your system:
$ cd /snap/hello-world/current/ $ tree . ├── bin ← this directory structure is just for convenience │ ├── echo there is no hardcoded structure requirement other │ ├── env than meta/snap.yaml │ ├── evil │ ├── sh │ ├── showdev │ └── usehw └── meta ← your snap must have this directory ├── icon.png ← no prizes for guessing what this is └── snap.yaml ← this is the required metadata
So a snap is very easy to create. Just put all the files you need
into a directory, use whatever subdirectory structure you want. That
directory will be compressed into a squashfs - a zipped directory -
and then it will be mounted at
the snap is installed. Your snap apps will know where they are mounted
because that is provided as the $SNAP environment variable when snap apps
The only actual hard requirement on a snap structure is that you
have a file called
inside your snap directory, which describes security requirements
and how the snap should be integrated with other parts of the system.
Let’s take a look at that
$ cat meta/snap.yaml name: hello-world version: 6.1 architectures: [ all ] summary: "The 'hello-world' of snaps" description: | This is a simple snap example that includes a few interesting binaries to demonstrate snaps and their confinement. * hello-world.env - dump the env of commands run inside app sandbox * hello-world.evil - show how snappy sandboxes binaries * hello-world.sh - enter interactive shell that runs in app sandbox * hello-world - simply output text apps: env: command: bin/env evil: command: bin/evil sh: command: bin/sh hello-world: command: bin/echo
The top metadata is easy, that’s just descriptive. One thing to remember is that the version is purely for humans, the snap system won’t ever treat that version as special or try to compare versions between snaps. That’s just so you know what the developer thinks about this software.
Note the explicit list of “apps” exported by this snap. Each app is explicitly named (‘env’, ‘evil’, ‘sh’, and ‘hello-world’) and each gets a distinctive command, which is path relative to $SNAP. The name of the app doesn’t have to match the command.
The special app here is ‘hello-world’, because it has the same name as the snap itself, it’s the default app in the snap and you can run it just by typing ‘hello-world’ after the snap is installed. The others need to be namespaces, so ‘hello-world.evil’ will execute the bin/evil command in the snap.
A snap can declare daemons to be started as well, this one just describes some apps.
Snaps are read-only and have segregated data stores
Snaps are read-only for security. We want to prevent a hostile party from sneakily changing the software on your machine, so you cannot modify a snap that is installed on your system. This also means you can always check the signature on the snap, even long after you installed it, to make sure it is still exactly the software you intended. If you want to modify a snap, you can usually build your own version of it, especially if it is open source.
So where can a snap write data? Each snap gets its own set of writable directories which have specific properties. There are two directories which the snap can write to independent of the user. One of these is versioned - each time the snap is upgraded the data is saved and the new snap revision can upgrade its copy. The other ‘common’ data directory is not versioned and is used for big blobs of data that you don’t want to duplicate across revisions of the snap:
/var/snap/<name>/current/ ← $SNAP_DATA is the versioned snap data directory /var/snap/<name>/common/ ← $SNAP_COMMON will not be versioned on upgrades
Typically, configuration is stored in one of these, along with system-wide data for the snap.
There are also an equivalent two writable directories for each snap in the user home, which can be used to store snap data that is specific to one user or another, separately:
~/snap/<name>/current/ ← $SNAP_USER_DATA that can be rolled back ~/snap/<name>/common/ ← $SNAP_USER_COMMON unversioned user-specific data
This way applications can be immutable for security reasons while still offering a full and rich user experience. To learn more about the makeup of a snap please see the snap architecture article.
Snap integration with interfaces, plugs and slots
Snaps are safely confined in their separate sandboxes by sophisticated kernel security mechanisms. That means that snaps can’t peek around at your data - other than the data you give them - if they are compromised. But what if you need your snap to talk to another one? For example, what if your snap needs to talk to a database? That’s where snaps get really amazing.
They can use ‘interfaces’ - standard and well-defined ways to provide and consume services from one another. Snaps can offer ‘slots’ to provide services, and declare ‘plugs’ that connect to other snap slots to consume those services. Imagine two snaps A and B that need to talk to each other:
These two snaps can be connected because they have a plug and a slot with a matching interface.
The interfaces are declared in the
There are many interfaces that are defined and can be used by snap developers to describe the ways their snaps should be connected. Also, a snap can be connected to the host system OS using plugs, too, which is how a snap can access shared user documents or other services like OpenGL.
Snaps can share files with other snaps from the same vendor, or with community-maintained shared snaps which act as libraries of common data or code, using the content-sharing interface, for example. This reduces duplication while still ensuring rigorous security and update control.
When you install a snap, the system will automatically connect up the standard, safe plugs and slots. For example, your new game will automatically get access to the OpenGL libraries on your system because that’s considered normal behaviour for a game. But there may be other plugs and slots you can connect up by choice, and snaps will document those individually.
The architecture of a snappy system
So a snappy system has a collection of snaps, each of which is read-only, each of which has its own set of independent writable directories, and each of which can talk to other snaps and the host OS through a set of plugs and slots with matching interfaces. It’s a very elegant world.
The snap system will present all the snap apps under
so with that on your $PATH you can easily run snap commands. It
will also integrate all the snap daemons (services) with your
init system so that they are automatically started and stopped
Using snaps - the snappy "hello world" tour
To install a snap, you’ll start by looking for available snaps. Anybody can publish a snap, but if you search the default Ubuntu store you will only see snaps that have been reviewed and judged to be of good quality, and which can be installed securely. We call these the ‘promoted’ snaps, and you can search them for a matching name:
$ snap find hello Name Version Developer Notes Summary hello 2.10 canonical - GNU Hello, the "hello world" snap hello-huge 1.0 noise - A really big snap hello-world 6.1 canonical - Hello world example
In the future, you will be able to refine
snap find queries with more parameters.
These examples use the Ubuntu store, your snap implementation might be different, other stores are available and it is also easy to create your own. There is an open source simple snap store implementation to get you started making your own store.
We’ll start by installing GNU Hello, from the Free Software Foundation:
$ sudo snap install hello
Just like any other app, we can then launch the snap from the command line, or from the desktop if it has a launcher:
$ hello Hello, world!
See the snaps installed on your system with ‘snap list’, which will also tell you the software version, the unique revision, the developer of the installed snap, and any extra information such as whether the snap is in developer mode or not:
$ snap list Name Version Rev Developer Notes hello 2.10 26 canonical - core 16.04-55 109 canonical - snapweb 0.17 21 canonical -
Always fresh – update fast and reliably
Snaps are updated automatically in the background every day. You can manually get the latest version of all your snaps with snap refresh which will bring you completely up to date for all snaps, unless you specify particular snaps to refresh.
$ sudo snap refresh hello hello already up to date $ sudo snap refresh core 64.75 MB [=====================================>___] 12s core updated
And revert if something goes wrong!
With the technology built in to snappy it is simple to roll back to a previous version of an application for any reason.
$ snap list Name Version Rev Developer Notes hello-world 6.1 26 canonical - $ sudo snap revert hello-world Name Version Rev Developer Notes hello-world 6.0 25 canonical -
Stable, candidate, beta and edge channels
Developers can release stable, candidate, beta and edge versions of a snap, at the same time, to engage with a community who are willing to test upcoming changes. You decide how close to the leading edge you want to be.
By default, snaps are installed from the stable channel. By convention, developers use the ‘candidate’ channel to provide a heads-up of a new stable revision, putting it in ‘candidate’ a few days before ‘stable’ so that people can test it out. The beta channel is for unfinished but interesting milestones, and the edge channel is conventionally used for regular or daily development builds that have passed some lightweight smoke-testing.
$ sudo snap refresh hello --channel=beta hello (beta) 1.2 installed
Now, you can run the beta version of the snap:
$ hello Hello, snap padawan!
You can also install a snap from the beta channel directly, with:
$ sudo snap install hello --beta Hello (beta) 1.2 installed
Check out snaps on uappexplorer.com or just use the command line to install any of these great snaps.
Snaps have a very simple internal structure - you can easily craft them by hand!
But the easiest way to build a snap is with Snapcraft, which supports building from source and from existing packages. Snapcraft also handles publishing your snaps to the world.