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
interface.
Declaring daemons
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 bin/app2: it
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.
The daemon key values follow systemd service types (forking, oneshot, notify and simple). See the apps and commands syntax for details on these types.
Stopping daemons
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 SIGKILL if SIGTERM fails).
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.
Tutorial
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.
Using wrappers
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 PATH,
LD_LIBRARY_PATH or other runtime specific environment variables.
For 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 python or java.
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.
Fixed assets
Desktop files
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:
snap/gui/<app-name>.desktop
snapcraft.yaml
Where <app-name> is the entry corresponding to apps in snapcraft.yaml.
Package icons
To use an icon to represent your snap, just declare a PNG or SVG in
snapcraft.yaml through an icon entry with a path relative
to the icon inside the snap.
icon: project/src/images/icon.png