Skip to content

Convert a nixos derivation into a self-contained binary

License

Notifications You must be signed in to change notification settings

ralismark/nix-appimage

Repository files navigation

nix-appimage

Create an AppImage, bundling a derivation and all its dependencies into a single-file executable. Like nix-bundle, but much faster and without the glibc dependency.

Getting started

To use this, you will need to have Nix available. Then, run this via the nix bundle interface, replacing nixpkgs.hello with the flake you want to build:

$ nix bundle --bundler github:ralismark/nix-appimage nixpkgs#hello

This produces hello.AppImage, which prints "Hello world!" when run:

$ ./hello.AppImage
Hello, world!

If you get a entrypoint ... is not executable error, or want to specify a different binary to run, you can instead use the ./bundle script:

$ ./bundle dnsutils /bin/dig # or ./bundle dnsutils dig
$ ./dig.AppImage -v
DiG 9.18.14

You can also use nix-appimage as a nix library -- the flake provides lib.<system>.mkAppImage which supports more options. See mkAppImage.nix for details.

Caveats

OpenGL apps not being able to run on non-NixOS systems is a known problem, see NixOS/nixpkgs#9415 and #5. You'll need to use something like nixGL. Addressing this problem outright is out of scope for this project, however PRs to integrate solutions (e.g. nixGL) are welcome.

Additionally, the produced file isn't a fully conforming AppImage. For example, it's missing the relevant .desktop file and icons -- this doesn't affect the running of bundled apps in any way, but might cause issues with showing up correctly in application launchers (e.g. rofi). Please open an issue if this is something you want.

The current implementation also has some limitations:

  • This requires Linux User Namespaces (i.e. CAP_SYS_USER_NS), which are available since Linux 3.8 (released in 2013), but may not be enabled for security reasons.
  • Plain files in the root directory aren't visible to the bundled app.

Under The Hood

nix-appimage creates type 2 AppImages, which are essentially just a binary, known as the Runtime, concatenated with a squashfs file system. When the AppImage is run, the runtime simply mounts the squashfs somewhere and runs the contained AppRun. The squashfs contains all the files needed to run the program:

  • nix/store/..., containing the closure of the bundled program
  • entrypoint, a symlink to the actual executable, e.g. /nix/store/q9cqc10sw293xpx3hca4qpsmbg7hsgzy-hello-2.12.1/bin/hello
  • AppRun, which gets started after the squashfs is mounted. This isn't the actual bundled executable, but a wrapper that makes the bundled nix/store file visible under /nix/store before executing entrypoint.

Runtimes are included within the flake as packages.<system>.appimage-runtimes.<name>. Currently supported are:

AppRuns are included within the flake as packages.<system>.appimage-appruns.<name>. Currently supported are:

  • userns-chroot (default). This uses Linux User Namespaces and chroot to make /nix/store appear to have the bundled files, similar to nix-user-chroot. There is a known problem of plain files in the root folder not being visible to the bundled app when using this AppRun.

About

Convert a nixos derivation into a self-contained binary

Topics

Resources

License

Stars

Watchers

Forks