Commands, daemons & assets
The entire syntax of a
snapcraft.yaml with all available keys can be
reviewed in the snapcraft.yaml syntax section. Here we will
discuss the apps metadata in more detail.
Declaring app commands
For every app you build in your snap, you can define which commands or
daemons are shipped. Declaring them in
snapcraft.yaml will expose them in
the system. Starting with the apps keyword you specify each app and its
functionality. So, if there were two apps, one called app1 and another
called app2, the extract would look like
apps: app1: command: bin/app1 app2: command: opt/bin/app2 plugs: - network
So in the example, app1 will declare its command to the relative path
bin/app1, while app2 defines a
different command being
opt/bin/app2 and using the network
Every app may build a binary that may need to be exposed in the system, with that in mind, the way to expose a daemon is by using the daemon keyword. So, if there were two services, one called service1 and another called service2, the extract would look like
apps: daemon1: command: bin/app1 daemon: simple daemon2: command: bin/app2 --start stop-command: bin/app2 --stop daemon: forking
So in the example, daemon will declare its start to the relative path
bin/app1, while daemon2 defines a different start to
declares an explicit stop mechanism.
Also note that daemon1 is defined as a simple daemon, meaning that it is expected that the command configured is the main process. Daemons like daemon2 which use forking have the configured command call fork() as part of its start-up. The parent process is expected to exit when start-up is complete and all communication channels are set up. The child continues to run as the main daemon process. This is the behavior of traditional UNIX daemons.
daemon key values follow systemd service types (
simple). See the apps and commands syntax for details on these types.
To provide a clean way to stop a daemon, you can provide a
stop-command with an additional
stop-timeout. In case the
stop-command does not successfully terminate the daemon in the timeout duration, it will be terminated with
SIGTERM (and ultimately with
apps: daemon1: command: bin/app1 daemon: simple stop-command: bin/app1-stop stop-timeout: 10s
In this example, when snapd needs to stop
daemon1 (eg. if the user disables or removes the snap),
bin/app1-stop will be executed.
See the apps and commands syntax for details on how to automatically restart a daemon.
To get a first experience with snapping a service, the “Build a nodejs service” tutorial will guide you through building, confining and general good practices to snap a simple web server.
It’s customary to use within your app small wrappers that will launch the real binaries. For instance, to select the binaries for the correct architecture or to set runtime variables such as the application state directory.
The typical wrapper is a small shell script that sets
LD_LIBRARY_PATH or other runtime specific environment variables.
PATH to work properly, it’s necessary not to hardcode any pathname in
your code. For instance, don’t rely on
/usr/bin/python or on
/usr/bin/java but instead run
Snapcraft already generates a wrapper for each declared command, that adjusts symlinks to be relative and work for your snap. These wrappers are named after commands:
command-<command>.wrapper and can be found in the
prime/ directory after a snapcraft build or in the
/snap/<snap-name>/current/ directory after a snap install.
You can declare a desktop file from your app within an
apps entry using a path relative to the
prime directory pointing to a desktop file, snapcraft will take care of the rest. If your project already has a desktop file, say in
/usr/share/applications/my-app.desktop all you need to do is the following:
apps: my-app: command: my-app desktop: usr/share/applications/my-app.desktop
Alternatively, you can create a
snap/gui/ directory at the root of your snapcraft project to host a desktop file:
<app-name> is the entry corresponding to
Providing an icon for your snap is important, even for command-line applications, if for nothing else than discoverability from management interfaces such as store fronts like snapweb.
To use an icon to represent the snap, just declare a PNG or SVG in
snapcraft.yaml through an
icon entry with a path relative
to the icon inside the snap.