Learn snapcraft by example – multi-app client-server snap

by Igor Ljubuncic on 27 March 2020

Over the past few months, we published a number of articles showing how to snap desktop applications written in different languages – Rust, Java, C/C++, and others. In each one of these zero-to-hero guides, we went through a representative snapcraft.yaml file and highlighted the specific bits and pieces developers need to successfully build a snap.

Today, we want to diverge from this journey and focus on the server side of things. We will give you an overview of a snapcraft.yaml with two interesting components: a) it will have more than one application; typically, snaps come with one application inside b) it will have a simple background service, to which other applications can connect. Let’s have a look.


Here’s the relevant part of the snapcraft.yaml file:

    command: bin/borg
    daemon: simple
    restart-condition: on-abnormal
      - home
      - network
      - network-bind
    command: bin/locutus
      - home
      - network

What do we have here?

First, we declare the server part of the bundle – an application named borg. It is a simple daemon, and the restart condition will be “on-abnormal” – the service states are based on values returned from systemd.

Second, for the service to work, it needs to be able to bind to network ports, which is why we’re defining the network-bind interface. Please note that if your application needs to bind to a privileged port, you will need sudo to be able to make it run correctly. The use of snaps does not change the underlying security requirements.

We also define access to home (so that the service can read a configuration file, for instance), and network, so it can communicate over the network. This is necessary in addition to the bind declaration, unless your service is designed to only run and listen on localhost.

In the second part, we declare the client part of the bundle – an application that only needs access to the home directory (configuration files, certificates, etc.), and network. This way, you can run the component applications of this snap on various systems, in a classic client-server model.

How to invoke a multi-app snap?

The one question you may have is – with multiple apps inside a snap, how does the user run them? When the app name matches the snap name, e.g.: igor, you only need to run “igor” or “/snap/bin/igor”. Here, the invocation is slightly different. Let’s say the snap is called “picard”. In this case, for the server application, you would run:


Similarly, for the client application:


Users can manually create aliases to work around this. Similarly, developers can request automatic aliases for their software from the Snap Store team, in cases where there is no obvious namespace clash. This can lead to a smoother, more streamlined user experience. In this example, borg will be mapped to picard.borg, and locutus will be mapped to picard.locutus.


We hope today’s guide sheds clarity on how to make somewhat more elaborate use cases with snaps, including multi-apps and client-server scenarios. Of course, creating the snapcraft.yaml is only part of the work, you also need to make sure that your software parts can communicate with one another, and do their job correctly. However, at least you have the snapcraft side of things covered.

If you have any comments, or perhaps requests on future articles that would help you snap your application (or a complex service), please join our forum for a discussion.

No Star Trek TNG references were aliased in the creation of this article.

Photo by Marlon Corona on Unsplash.

Newsletter Signup

Related posts

Popular snaps per distro (2020 edition)

Back in mid-2019, we wrote a blog post detailing and comparing the most popular snaps across multiple distributions – Arch Linux, CentOS, Debian, Fedora, Manjaro, and Ubuntu. This article gave us a fascinating insight into the usage patterns across these different systems and their audiences. We wanted to see if and how the situation has […]

The Hunt for Rogue Time – How we investigated and solved the Chromium snap slow startup problem

In October, we shared a blog post detailing significant snap startup time improvements due to the use of a new compression algorithm. In that article, we focused on the cold and hot application startups, but we did not delve much into the first-run setup scenario. While running our tests, we observed a rather interesting phenomenon, […]

Introducing etrace – a multi-purpose application profiling tool

These days, the internal workings of Linux applications involve many different moving parts. Sometimes, it can be rather difficult to debug them when things go wrong or run slower than expected. Tracing an application’s execution is one way of understanding potential issues without diving into the source code. To this end, we wrote an app […]