Mats Tage Axelsson shows you how the methods for distributing applications for Linux are changing − and why we should care.
Let’s get going with Snaps – Mats Tage Axelsson believes they’re the future!
Linux users often argue with users of other operating systems about how brilliant Linux is. Yet one thing that’s always been hard to defend is how tricky it is to download your favourite application directly from the developer’s website and run it. Usually, it’s a deliberate choice to have a central repository with well-tested and secure software. However, for desktop applications, users prefer to find the developer’s website and download from there.
Until lately, you could only choose to use a distribution or compile your own. Most regular users won’t compile their software packages. For the developers, maintaining a package for all the distributions available is a nightmare. They need to adapt to the libraries in each distribution, including which version they need to support. If they’re using a new feature in one of their libraries, they may not be able to convince distribution maintainers to add it. This situation especially applies to applications with a small user base.
Ubuntu has introduced snaps as one of many solutions to obtain application packages that aren’t distro specific and are also available as downloads. We’ll cover snaps and appimage in this tutorial, and mention Flatpack and a few others.
An Appimage contains the executable you want, but that’s not the first executable that runs when you start an Appimage. The first binary to run is AppRun, which sets up the system for the application.
The appimagekit creates AppRun during the process of making the AppImage. The resulting AppRun executable is very similar in different appimages. After all, it only sets the system up with variables and libraries. You’re also free to create the AppRun yourself, but you’d probably only do this after you’ve used the appimagekit a few times.
A good idea for your first few projects is to write your recipe when you create an appimage. The recipes are YAML files, one for each AppImage. The file contains all the information to create the AppImage, including a script to download and configure the package.
A Snap has a similar structure, but with a stricter specification. The package contains a local root /, /meta and /bin/. The local root contains the source and wrapper files, / bin contains binaries and /meta contains configuration files.
The difference between snaps and AppImages is that snap needs a daemon to operate, while an Appimage doesn’t. When you download a snap, you have to install it before you can use it. That is one task that the snap daemon performs.
With an AppImage, you must have AppRun in the root and /usr directory of the image created. It’s not necessary to integrate your application into your system. If you do want it to show up in your favourite desktop environment, then you can choose to use the optional appimage daemon. In practice, you must follow the standards laid down at www.freedesktop.org for your applications to run correctly.
The big difference between the two packaging formats is that AppImage uses an ISO 9660 file, and a Snap uses a squashfs filesystem. Furthermore, Snaps and AppImage come from different lines of thought. The most important priority of the AppImage project is to make it easy to distribute and use software directly from the developer. In other words, the user and developer shouldn’t depend on the distribution maintainers to move over to newer versions.
There’s a greater emphasis on correct confinement in the snap design. The system also requires a central repository, called stores. And so when you want to use Snaps, you first need to install the Snaps system for your distro. The snap system is a traditional package for many distributions, so in Ubuntu you use apt : $ sudo apt install snap
In Fedora you use dnf . $ sudo dnf install snap
Fedora started the Flatpack project, which is competing to solve the same problem. So you need to go through a lengthier procedure before you can install snap. In other distributions, you need to check if they’ve added the snap packages. It’s already native in Arch, Debian, Fedora and the main Ubuntu distributions. The most common problem is missing support for the confinement, and you need to run your snaps in development mode.
Once snap is installed the process is very similar to using a package manager. Below is a typical flow for getting a snap.
We start by finding the snap package. $ snap find nextcloud Name Version Developer Notes Summary Name Version Developer Notes Summary nextcloud-port8080 1.01 arcticslyfox - Nextcloud Server nextcloud-nextant 11.0.0snap3 rmescandon - Nextcloud Server + search support nextcloud 11.0.3snap7 nextcloud - Nextcloud Server cashbox-nextcloud 11.0.2snap2 cashbox - Nextcloud Server for www.cashBOX.plus spreedme 0.29.5snap1 nextcloud - Spreed.ME audio/ video calls and conferences feature for the Nextcloud Snap qownnotes 17.07.6 pbek - Plain-text file notepad with markdown support and ownCloud integration solr 0.1 rmescandon - Starts up solr as forking daemon mdns-hostname 0.0.1 welike - mDNS minidaemon to published hostname.local As you can see, the command shows all versions available along with related snaps, too.
Once you’ve verified that it’s available, install it. $ sudo snap install nextcloud Now, run the command. $ nextcloud Nextcloud is now running and you can confirm this using systemctl: $ systemctl status snap.nextcloud.* To obtain more information use the info command:
$ snap info nextcloud
A Snap will be active once it’s installed. For regular applications, this isn’t a major issue. However, if we install
nextcloud, as in the above example, then the service will continue running. When you no longer need the server to run you have two options: disable it or remove it. A service like this can, of course, be stopped with the systemctl commands and leave it at that. Here, we wanted to see if it’s better to use a snap instead − and indeed it is! With a snap, you can list all your snaps and choose whether you want them active, disabled or thrown away. If you use the disable function, then the package will still be on the disc with all settings intact until you start it again or remove it.
The best thing about this approach is that snap will check all functions and stop the service without any additionals commands. From past experience, we expected to have to stop the service first and then disable it. If you’ve decided that
this snap isn’t your thing, you can erase it. All settings go with it so make sure you know that you’ve not made changes that you want to bring over to either a new install or perhaps another snap: $ snap remove nextcloud
The above actions are the most common when you use snaps. If you’ve followed this tutorial thusfar, you have now done everything needed to verify the nextcloud package. Testers will find this useful because all files and configurations are in the snap tree. When you remove a snap, no files will be left behind.
The next section is our recommended approach for using AppImage. Hang on to your hats!
Download the file
Set execute permissions for the file. We have chosen to allow all users. It works even if you add only yourself. $ chmod a+x Downloads/TheApp.AppImage
Next, run the application. $ Downloads/TheApp.AppImage
That’s it! As you can see, the system is created to make using software simple. The big challenge is for the programmers to make the package work in most distributions without creating a bloated download. To make things even simpler, use the appimage daemon. The daemon scans predefined directories for AppImages, sets the executable bit and then adds them to your desktop.
Snap requires a store. The default store is the Ubuntu one, but the idea is that anyone can run a store. If you’re interested, check out https://github.com/noise/snapstore. This is a snap store example on Github that will enable you to
gain some experience in running a store. A quick search on the internet doesn’t reveal any stores − yet.
AppImage, on the other hand, is designed to enable anyone to create and distribute software without any central repository at all. With that said, there are already over 100 applications on bintray for you to download.
Living in Flatpak land
When using Flatpak, the installer checks dependencies and downloads runtimes. Runtimes are the libraries and other binaries that are necessary to run the packages. The Flatpak structure is similar to that of AppImage, except that it has a metadata file for configuration information, /files directory for source code and application information. The binaries go in /files/bin and any data that the application needs to share with the environment goes in the /export directory.
Flatpak is more like a package manager compared to AppImage, which should make the Flatpak packages smaller. With so few applications though, it’s hard to judge right now.
Creation is a snap
We’ll start looking how to create packages, either as a developer or just because you want to try the application out. First up is snaps. The build tool for snaps is called snapcraft, so install that with your regular package management wizardry. $ sudo apt install snapcraft
The snapcraft tool will compile the packages for you, so the build-essential package is required. $ sudo apt install build-essential
For the snapcraft tool to do anything useful, you need a configuration file called snapcraft.yml. The contents of this file describes the application you want to compile.
Running the snapcraft tool is simple: there are two different procedures. The simplest approach is to just run the command without switches in the directory where you put your snapcraft.yml file. $ snapcraft
In this case, snapcraft will read the snapcraft.yml file and compile the defined package. After this, you install the snap. $ snap install [yourApp.snap] –dangerous
When the packages become bigger, the procedure has a few more optional steps. This is because the system can add libraries that are uncommon. If your application needs a new library, you can add it as a part of your configuration file. When your package is this big, you have the option to compile one part at a time. In fact, snapcraft will detect if you already have the latest of any part and only recompile the updated part when you want to upgrade. You have the option to build a part at a time, use the build command. $ snapcraft build [part]
Without the part parameter, snapcraft builds all the parts that need compiling. You can use this if you want to change only one part. $ snapcraft clean [part] The snapcraft.yml file controls it all. The top of the snapcraft.yml file contains the descriptive information such as the name, the version and the description. The other sections control the behaviour of snapcraft, which in turn configures your snap.
The next section is confinement, because in a production snap this value needs to be strict. For security reasons, the strict value stops the snap from communicating with the rest of the system. While you’re developing a snap, you need to set the value to devmode or use the switch –dangerous to make it run outside of confinement.
For the snap to work properly in any environment you then need to define what it’s permitted to interface with. For example, a web browser needs to access the network as a client. To do this, you need to add the network parameter in the file. This parameter is called a plug when the snap needs a resource and a slot when the snap provides one.
The other sections are apps and parts. In the apps section, the name parameter names the executable and points to the command. Usually, they’ll both be the same, but you may need to start it with bash, python or the like.
Moving on to the parts section, you need to define what you need to build your code with and where your code is. In
its simplest form, the parts directive contains the name of the app, the plugin and the source.
A simple example here: parts: hello: plugin: autotools source: ./src/hello The plugin will vary, depending on your source code. A reference list available at https://snapcraft.io/docs/ reference/plugins.
Creating an AppImage
To make an AppImage, it’s likely that you’ll use the build services available online. One example is Travis CI.
Usually, the developer will create either the recipe file or the directory structure. If an existing package doesn’t exist as an AppImage, you can create the directory structure yourself.
The directory structure stems from the ROX desktop project. The structure contains at least the files and directories shown below. MyApp.AppDir/ MyApp.AppDir/AppRun MyApp.AppDir/myapp.desktop MyApp.AppDir/myapp.png MyApp.AppDir/usr/bin/myapp MyApp.AppDir/usr/lib/libfoo.so.0
The key file is AppRun. As mentioned earlier in this article, it’ll configure your package. AppRun is a wrapper script that sets all environment variables at runtime and launches the application.
The myapp.desktop file follows the freedesktop standard. The appimage daemon will find and read this file to integrate the application into your desktop environment. Look inside the file to learn the details.
To show how this works, we’ll make an AppImage using the Calibre recipe.
The Calibre.yml file already exists on www.github.com, and there’s also a script that reads the recipe file.
Download the script with wget. $ wget https://raw.githubusercontent.com/probonopd/ AppImages/master/recipes/meta/Recipe
Set the executable bits. $ chmod a+x Recipe
Make a directory for your AppImage and cd into it. $ mkdir Calibre && cd Calibre
Finally, run the recipe script. $ ../Recipe Calibre
You may notice that we’ve not included the yml extension, if you do, the script stops early. This script will look for the recipe file, first in your current directory and then turn to
www.github.com and execute the recipe as a script. During the execution, the script will download the source code, binary files, and dependencies and create the AppDir.
The script also creates an out directory where you’ll find your AppImage. Curious readers will no doubt investigate the AppDir under Calibre.
To make an AppImage for a developer requires just a little bit more work first. If you’re interested, read the install document and then adjust the recipe file to the build system for the particular application. Then run the same script for that application, and increase the number of applications delivered by AppImage. Because the particular project will be pioneering, you’ll run into a few more issues to handle, such as hard-coded directories in the source code.
The zeroth law
Until now, we’ve not mentioned zeroinstall. This is an earlier project that solved the same problem, but does not seem to have experienced the same take-up as snaps. We find this all rather puzzling because making your application ready for zeroinstall is very simple. You create a web page in the standard XML format that the makers prescribe in their instructions and then you test. The project is also very active, and to top it all off there are three versions that supporting the three big operating systems. You can read more about zeroinstall in the box ( belowleft).
Turning back to snaps, you have secure confinement builtin if you register your application and set your signature. Appimage doesn’t have this natively so for the security conscious use firejail. The package is simple to use just add the appimage switch. $ firejail –appimage krita-3.1.2-x86_64.appimage
Inside the firejail, the application can still read your user data, so any files that you’ve put in your home directory will be accessible.
Some readers will be wondering why we need snap and AppImages at all. For many people, the distribution system works fine, and there’s no problem to solve. Yet while the distributions are useful for keeping a stable system, it also requires more people between developer and end-user.
The problems start when you want to try an application, and the developer doesn’t support your distribution. What will you do? Changing distribution is a big job, and other applications may not work in your new distribution. These solutions makes it easier to test applications and to get hold of uncommon software.
Don’t fight the change, embrace it.
The snapcraft tour command creates directories that enable you to learn the basics. During the tour, you create regular snaps as well as web-based software.
Linphone is installed as a flatpak. When the flatpak installs, it also installs dependencies to the flatpak system without upgrading the rest of the system.
Zeroinstall has both a GUI helper and a command line tool that enable you to create your publisher feed file. Publishing to the web is a built-in feature.
When you run the recipe script from http://bit. ly/2vYe2pG, all the required files are downloaded to the AppDir that will become part of your AppImage.