···1-# buildFHSUserEnv {#sec-fhs-environments}
23-`buildFHSUserEnv` provides a way to build and run FHS-compatible lightweight sandboxes. It creates an isolated root with bound `/nix/store`, so its footprint in terms of disk space needed is quite small. This allows one to run software which is hard or unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions, games distributed as tarballs, software with integrity checking and/or external self-updated binaries. It uses Linux namespaces feature to create temporary lightweight environments which are destroyed after all child processes exit, without root user rights requirement. Accepted arguments are:
45- `name`
6 Environment name.
···26```nix
27{ pkgs ? import <nixpkgs> {} }:
2829-(pkgs.buildFHSUserEnv {
30 name = "simple-x11-env";
31 targetPkgs = pkgs: (with pkgs;
32 [ udev
···1+# buildFHSEnv {#sec-fhs-environments}
23+`buildFHSEnv` provides a way to build and run FHS-compatible lightweight sandboxes. It creates an isolated root with bound `/nix/store`, so its footprint in terms of disk space needed is quite small. This allows one to run software which is hard or unfeasible to patch for NixOS -- 3rd-party source trees with FHS assumptions, games distributed as tarballs, software with integrity checking and/or external self-updated binaries. It uses Linux namespaces feature to create temporary lightweight environments which are destroyed after all child processes exit, without root user rights requirement. Accepted arguments are:
45- `name`
6 Environment name.
···26```nix
27{ pkgs ? import <nixpkgs> {} }:
2829+(pkgs.buildFHSEnv {
30 name = "simple-x11-env";
31 targetPkgs = pkgs: (with pkgs;
32 [ udev
···94Then instead of running the AppImage "as-is", run `appimage-run foo.appimage`.
9596To make other pre-built executables work on NixOS, you need to package them
97-with Nix and special helpers like `autoPatchelfHook` or `buildFHSUserEnv`. See
98the [Nixpkgs manual](https://nixos.org/nixpkgs/manual) for details. This
99is complex and often doing a source build is easier.
···94Then instead of running the AppImage "as-is", run `appimage-run foo.appimage`.
9596To make other pre-built executables work on NixOS, you need to package them
97+with Nix and special helpers like `autoPatchelfHook` or `buildFHSEnv`. See
98the [Nixpkgs manual](https://nixos.org/nixpkgs/manual) for details. This
99is complex and often doing a source build is easier.
···23{ alsa-lib
4, bash
5-, buildFHSUserEnv
6, cacert
7, coreutils
8, dbus
···178 # Android Studio downloads prebuilt binaries as part of the SDK. These tools
179 # (e.g. `mksdcard`) have `/lib/ld-linux.so.2` set as the interpreter. An FHS
180 # environment is used as a work around for that.
181- fhsEnv = buildFHSUserEnv {
182 name = "${drvName}-fhs-env";
183 multiPkgs = pkgs: [
184 ncurses5
···23{ alsa-lib
4, bash
5+, buildFHSEnv
6, cacert
7, coreutils
8, dbus
···178 # Android Studio downloads prebuilt binaries as part of the SDK. These tools
179 # (e.g. `mksdcard`) have `/lib/ld-linux.so.2` set as the interpreter. An FHS
180 # environment is used as a work around for that.
181+ fhsEnv = buildFHSEnv {
182 name = "${drvName}-fhs-env";
183 multiPkgs = pkgs: [
184 ncurses5
···22, mkDerivation
23, xkeyboard_config
24, fetchurl
25-, buildFHSUserEnv
26, openal
27, makeDesktopItem
28}:
···94in
9596# We can patch the "/bin/superposition", but "/bin/launcher" checks it for changes.
97-# For that we need use a buildFHSUserEnv.
9899-buildFHSUserEnv {
100 name = "Superposition";
101102 targetPkgs = pkgs: [
···22, mkDerivation
23, xkeyboard_config
24, fetchurl
25+, buildFHSEnv
26, openal
27, makeDesktopItem
28}:
···94in
9596# We can patch the "/bin/superposition", but "/bin/launcher" checks it for changes.
97+# For that we need use a buildFHSEnv.
9899+buildFHSEnv {
100 name = "Superposition";
101102 targetPkgs = pkgs: [
···1{ autoPatchelfHook
2-, buildFHSUserEnv
3, dpkg
4, fetchurl
5, inotify-tools
···41 '';
42 };
4344- expressvpndFHS = buildFHSUserEnv {
45 name = "expressvpnd";
4647 # When connected, it directly creates/deletes resolv.conf to change the DNS entries.
···1{ autoPatchelfHook
2+, buildFHSEnv
3, dpkg
4, fetchurl
5, inotify-tools
···41 '';
42 };
4344+ expressvpndFHS = buildFHSEnv {
45 name = "expressvpnd";
4647 # When connected, it directly creates/deletes resolv.conf to change the DNS entries.
+1-1
pkgs/applications/networking/pcloud/default.nix
···3# of applications.
4#
5# What Nix does, simplifying a bit, is that it extracts an AppImage and starts
6-# it via buildFHSUserEnv - this is totally fine for majority of apps, but makes
7# it by-design *impossible* to launch SUID wrappers [^1]; in case of pCloud,
8# it's fusermount.
9# (so pCloud starts, but silently fails to mount the FUSE drive.)
···3# of applications.
4#
5# What Nix does, simplifying a bit, is that it extracts an AppImage and starts
6+# it via buildFHSEnv - this is totally fine for majority of apps, but makes
7# it by-design *impossible* to launch SUID wrappers [^1]; in case of pCloud,
8# it's fusermount.
9# (so pCloud starts, but silently fails to mount the FUSE drive.)
···2## - export ELECTRON_SKIP_BINARY_DOWNLOAD=1
3## - jq "del(.scripts.preinstall)" node_modules/shellcheck/package.json | sponge node_modules/shellcheck/package.json
4{
5- lib, stdenv, buildFHSUserEnvBubblewrap, runCommand, writeScript, fetchurl, fetchzip
6}:
7let
8 pname = "webtorrent-desktop";
···20 else
21 throw "Webtorrent is not currently supported on ${stdenv.hostPlatform.system}";
2223- fhs = buildFHSUserEnvBubblewrap rec {
24 name = "fhsEnterWebTorrent";
25 runScript = "${src}/WebTorrent";
26 ## use the trampoline, if you need to shell into the fhsenv
···2## - export ELECTRON_SKIP_BINARY_DOWNLOAD=1
3## - jq "del(.scripts.preinstall)" node_modules/shellcheck/package.json | sponge node_modules/shellcheck/package.json
4{
5+ lib, stdenv, buildFHSEnv, runCommand, writeScript, fetchurl, fetchzip
6}:
7let
8 pname = "webtorrent-desktop";
···20 else
21 throw "Webtorrent is not currently supported on ${stdenv.hostPlatform.system}";
2223+ fhs = buildFHSEnv rec {
24 name = "fhsEnterWebTorrent";
25 runScript = "${src}/WebTorrent";
26 ## use the trampoline, if you need to shell into the fhsenv
···6}:
78{ bash
9-, buildFHSUserEnv
10, cacert
11, git
12, runCommand
···100101 # Wrap flutter inside an fhs user env to allow execution of binary,
102 # like adb from $ANDROID_HOME or java from android-studio.
103- fhsEnv = buildFHSUserEnv {
104 name = "${drvName}-fhs-env";
105 multiPkgs = pkgs: [
106 # Flutter only use these certificates
···6}:
78{ bash
9+, buildFHSEnv
10, cacert
11, git
12, runCommand
···100101 # Wrap flutter inside an fhs user env to allow execution of binary,
102 # like adb from $ANDROID_HOME or java from android-studio.
103+ fhsEnv = buildFHSEnv {
104 name = "${drvName}-fhs-env";
105 multiPkgs = pkgs: [
106 # Flutter only use these certificates
···1-{ lib, stdenv, buildGoModule, fetchFromGitHub, buildFHSUserEnv, installShellFiles }:
23let
4···4849in
50if stdenv.isLinux then
51-# buildFHSUserEnv is needed because the arduino-cli downloads compiler
52# toolchains from the internet that have their interpreters pointed at
53# /lib64/ld-linux-x86-64.so.2
54- buildFHSUserEnv
55 {
56 inherit (pkg) name meta;
57
···1+{ lib, stdenv, buildGoModule, fetchFromGitHub, buildFHSEnv, installShellFiles }:
23let
4···4849in
50if stdenv.isLinux then
51+# buildFHSEnv is needed because the arduino-cli downloads compiler
52# toolchains from the internet that have their interpreters pointed at
53# /lib64/ld-linux-x86-64.so.2
54+ buildFHSEnv
55 {
56 inherit (pkg) name meta;
57
···9495 # no tests in PyPI dist
96 # run into https://stackoverflow.com/questions/51203641/attributeerror-module-alembic-context-has-no-attribute-config
97- # also, tests use conda so can't run on NixOS without buildFHSUserEnv
98 doCheck = false;
99100 meta = with lib; {
···9495 # no tests in PyPI dist
96 # run into https://stackoverflow.com/questions/51203641/attributeerror-module-alembic-context-has-no-attribute-config
97+ # also, tests use conda so can't run on NixOS without buildFHSEnv
98 doCheck = false;
99100 meta = with lib; {
···1-{ stdenvNoCC, lib, fetchurl, buildFHSUserEnv }:
23let
4 version = "2.3";
···20 };
2122 # FHS env, as patchelf will not work
23- env = buildFHSUserEnv {
24 name = "left4gore-env-${version}";
25 targetPkgs = _: [ left4gore-unwrapped ];
26 runScript = "left4gore";
···1+{ stdenvNoCC, lib, fetchurl, buildFHSEnv }:
23let
4 version = "2.3";
···20 };
2122 # FHS env, as patchelf will not work
23+ env = buildFHSEnv {
24 name = "left4gore-env-${version}";
25 targetPkgs = _: [ left4gore-unwrapped ];
26 runScript = "left4gore";
+3-3
pkgs/games/runescape-launcher/default.nix
···1{ stdenv
2, lib
3, autoPatchelfHook
4-, buildFHSUserEnv
5, cairo
6, dpkg
7, fetchurl
···109110 /*
111 * We can patch the runescape launcher, but it downloads a client at runtime and checks it for changes.
112- * For that we need use a buildFHSUserEnv.
113 * FHS simulates a classic linux shell
114 */
115- buildFHSUserEnv {
116 name = "RuneScape";
117 targetPkgs = pkgs: [
118 runescape
···1{ stdenv
2, lib
3, autoPatchelfHook
4+, buildFHSEnv
5, cairo
6, dpkg
7, fetchurl
···109110 /*
111 * We can patch the runescape launcher, but it downloads a client at runtime and checks it for changes.
112+ * For that we need use a buildFHSEnv.
113 * FHS simulates a classic linux shell
114 */
115+ buildFHSEnv {
116 name = "RuneScape";
117 targetPkgs = pkgs: [
118 runescape
···1# The actual Plex package that we run is a FHS userenv of the "raw" package.
2{ stdenv
3-, buildFHSUserEnvBubblewrap
4, writeScript
5, plexRaw
6···9, dataDir ? "/var/lib/plex"
10}:
1112-buildFHSUserEnvBubblewrap {
13 name = "plexmediaserver";
1415 inherit (plexRaw) meta;
···1# The actual Plex package that we run is a FHS userenv of the "raw" package.
2{ stdenv
3+, buildFHSEnv
4, writeScript
5, plexRaw
6···9, dataDir ? "/var/lib/plex"
10}:
1112+buildFHSEnv {
13 name = "plexmediaserver";
1415 inherit (plexRaw) meta;