Snap

Snap is a sandboxed application package format for Linux, supported across most major distributions. AppBundler builds .snap packages with a fully open-source toolchain, so they can be created on any platform without a Linux build environment.

Snap installation

Build pipeline

The standard workflow describes the build in snapcraft.yaml and lets snapcraft fetch sources, compile, and package the application:

snapcraft.yaml → snapcraft → MyApp.snap

snapcraft is open source, but it expects to run the compilation itself and does not cross-compile. Since a snap is ultimately a SquashFS image with metadata, AppBundler assembles the staging directory itself and compresses it directly:

StagingDir → mksquashfs → MyApp.snap

mksquashfs comes from squashfs-tools. It is redistributable and cross-compiled with BinaryBuilder, so snaps can be built from macOS and Windows as well as Linux.

Package contents

Before compressing, AppBundler assembles StagingDir/ with the following layout:

PathPurpose
meta/snap.yamlPackage metadata and configuration
bin/MyAppApplication launcher
meta/icon.pngApplication icon
meta/gui/MyApp.desktopDesktop integration
meta/hooks/configureConfiguration hook

Sandboxing and permissions are configured through the confinement level and the interfaces (plugs) declared in meta/snap.yaml.

Signing and installation

A locally built snap therefore has no assertions and must be installed with --dangerous. AppBundler applications usually use classic confinement, which also requires --classic:

sudo snap install --classic --dangerous myapp.snap

If the application is configured for strict confinement in meta/snap.yaml, drop --classic. Snaps installed this way get a local revision such as x1 and receive no automatic updates.

SnapStore

Once a snap is published, the store-signed version can be installed offline, for example on air-gapped machines. Download the snap together with its assertions, then import the assertions before installing:

snap download myapp             # fetches myapp_N.snap and myapp_N.assert
sudo snap ack myapp_N.assert
sudo snap install myapp_N.snap

Snaps preseeded into Ubuntu Core or custom images with ubuntu-image also carry their assertions and install without extra flags.

Debugging

To debug Snap packages, skip compression and install the staging directory directly. You can also inspect the sandbox environment of the installed application:

sudo snap try myapp_dir     # install unpackaged directory
snap run --shell myapp      # inspect sandbox environment interactively

API

snap_config = Snap(project)

bundle(snap_config, snap_archive) do app_stage
    # install files into app_stage
end
AppBundler.Snap — Type
Snap([project]; arch, compress, windowed, kwargs...)

Create a Snap configuration object for Linux application packaging.

When project is provided, configuration files are searched in project, then project/meta, then the built-in recipes directory. Application parameters (APP_NAME, APP_VERSION, etc.) are read from project/Project.toml, and packaging defaults (windowed, compress, etc.) are read from project/LocalPreferences.toml. Without project, only the built-in recipes and the active project's LocalPreferences.toml are used.

Arguments

  • project: Path to a project directory containing Project.toml, optional LocalPreferences.toml, and optional meta/snap/ overrides

Keyword Arguments

  • prefix = joinpath(dirname(@__DIR__), "recipes"): Base directory or array of directories to search for configuration files in sequential order
  • icon = get_path(prefix, ["snap/icon.png", "icon.png"]): Path to application icon file
  • snap_config = get_path(prefix, "snap/snap.yaml"): Path to Snap package metadata template
  • command::Cmd: Command launching the application; defaults to snap.command preference. Its executable and escaped arguments are exposed to the templates as COMMAND
  • desktop_launcher = get_path(prefix, "snap/main.desktop"): Path to desktop entry file template for GUI integration
  • configure_hook: Path to configuration hook script run on snap set; resolved from prefix using the bundler predicate; omitted if not found
  • main_launcher: Path to main launcher script installed into bin/; resolved from prefix using the bundler predicate; omitted if not found
  • windowed: If true, the application runs without a console window; defaults to windowed preference
  • compress: If true, pack the staging directory into a .snap archive; defaults to compress preference
  • arch = Sys.ARCH: Target CPU architecture
  • predicate: Bundler predicate used for hook selection; defaults to bundler preference
  • parameters: Dictionary of parameters for Mustache template rendering. When project is provided, pre-populated from Project.toml and preferences: APP_NAME, APP_DISPLAY_NAME, APP_VERSION, BUILD_NUMBER, APP_SUMMARY, APP_DESCRIPTION, BUNDLE_IDENTIFIER, PUBLISHER_DISPLAY_NAME, MODULE_NAME (Julia-based bundles only), and WINDOWED

Examples

Snap()                                    # default recipes only
Snap(app_dir)                             # project with Project.toml parameters
Snap(app_dir; windowed = false)           # project with keyword overrides
Snap(; prefix = ["custom/", "recipes/"]) # explicit search path
source