Skip to content

fix(appimage): drop injected --no-sandbox in the Linux launcher wrapper#267

Open
sproctor wants to merge 1 commit into
NucleusFramework:mainfrom
sproctor:fix/appimage-no-sandbox
Open

fix(appimage): drop injected --no-sandbox in the Linux launcher wrapper#267
sproctor wants to merge 1 commit into
NucleusFramework:mainfrom
sproctor:fix/appimage-no-sandbox

Conversation

@sproctor

Copy link
Copy Markdown
Contributor

Problem

AppImages built by Nucleus fail to launch on Ubuntu 24.04+ (and any host where unprivileged user namespaces are restricted):

$ ./MyApp.AppImage
Error: no such option --no-sandbox

Fixes #266.

Root cause

Nucleus packages the AppImage via electron-builder. electron-builder's generated AppRun prepends --no-sandbox to the launched binary when unshare -Ur true fails (i.e. unprivileged user namespaces are unavailable, the Ubuntu 24.04+ default), on the assumption the binary is Chromium/Electron:

if [ $HAVE_NO_SANDBOX -eq 0 ] && ! unshare -Ur true 2>/dev/null ; then
  NO_SANDBOX=(--no-sandbox)
fi
...
exec "$BIN" "${NO_SANDBOX[@]}" "${EXECUTABLE_ARGS[@]}" "${args[@]}"

But Nucleus packages JVM / GraalVM-native apps, which have no Chromium sandbox and whose launchers may abort on the unknown option.

There is no electron-builder configuration to disable this: the injection is hardcoded in generateAppRunScript, the AppRun is rewritten on every build, and linux.executableArgs can only add arguments (it cannot remove --no-sandbox).

Fix

AppRun execs "$APPDIR/<executableName>", which is the launcher wrapper Nucleus already generates in ensureLinuxExecutableAlias (it resolves symlinks and delegates to the real bin/<launcher>). This drops --no-sandbox in that wrapper before delegating:

for arg in "$@"; do
  shift
  [ "$arg" = "--no-sandbox" ] && continue
  set -- "$@" "$arg"
done
exec "$DIR/<relativePath>" "$@"

Chosen here because it:

  • needs no AppImage repackaging and no extra tooling;
  • leaves electron-builder's artifact bytes, sha512, and .blockmap untouched, so auto-update metadata stays valid;
  • covers both jpackage and GraalVM launchers, which both route through this wrapper;
  • is independent of which electron-builder version a build resolves.

Alternatives considered

  • Post-processing the built .AppImage to rewrite AppRun: requires extract + repackage tooling and would invalidate the auto-update sha512/.blockmap electron-builder just generated.
  • Upstream electron-builder change to skip the injection for non-Electron targets: the cleaner long-term fix, but not something Nucleus can do locally.

Testing

The POSIX sh rebuild idiom preserves argument order and arguments containing spaces; only exact --no-sandbox tokens are removed.

electron-builder's AppImage AppRun prepends --no-sandbox to the launched
binary when unprivileged user namespaces are unavailable (the Ubuntu 24.04+
default), on the assumption the target is Chromium/Electron. Nucleus packages
JVM/native apps that have no such sandbox, and their launchers may abort on
the unknown option.

AppRun execs "$APPDIR/<executableName>", which is the wrapper script Nucleus
generates in ensureLinuxExecutableAlias, so drop --no-sandbox there before
delegating to the real launcher. This needs no AppImage repackaging, leaves
electron-builder's auto-update hash/blockmap intact, and covers both the
jpackage and GraalVM launchers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AppImage: electron-builder is invoked unpinned (npx electron-builder), making AppRun non-deterministic and breaking non-Electron apps with --no-sandbox

1 participant