Desktop packaging (Linux, Arch, Windows)

How to produce distributable desktop packages for JellyTau. All three flows can run in Docker so no host toolchain setup is required. Outputs land in ./dist.

One builder image (shared with CI)

The deb/rpm and Windows-cross flows build on the unified registry builder (../Dockerfile.buildergitea.tourolle.paris/dtourolle/jellytau-builder), the same image CI uses. It carries every packaging tool: Android SDK/NDK, rpm/file (Linux bundler), cargo-xwin + lld + llvm + nsis + the x86_64-pc-windows-msvc rust target (Windows). There is one dependency source of truth — no per-stage tool installs.

The desktop stages in ../Dockerfile are thin FROM ${BUILDER_IMAGE} environments; the actual build runs at container-run time on your bind-mounted source (like the dev service), so source edits need no image rebuild.

If you changed Dockerfile.builder (e.g. added a tool), rebuild and push it first, or the packaging flows use the stale registry image:

scripts/build-builder-image.sh           # build + push :latest to the registry
# ...or iterate locally without pushing:
docker build -f Dockerfile.builder -t jellytau-builder:latest .
BUILDER_IMAGE=jellytau-builder:latest bun run docker:build:windows

Arch uses a separate archlinux image (../Dockerfile.arch) because makepkg is Arch-specific — it is not part of the unified builder.

TargetFormatDocker commandFunctional?
Debian/Ubuntu, Fedora.deb, .rpmbun run docker:build:linux✅ yes
Arch Linux.pkg.tar.zstbun run docker:build:arch✅ yes
WindowsNSIS installer + .exebun run docker:build:windows✅ yes (unsigned)

Linux: deb + rpm

Tauri's bundler produces these natively. The build runs on the existing Ubuntu builder image (../Dockerfile, desktop-linux-build stage):

bun run docker:build:linux            # deb + rpm -> ./dist
# or, on a host with the Tauri Linux deps installed:
BUNDLES="deb,rpm" scripts/build-desktop-linux.sh

Runtime dependency: the app links libmpv (audio) and WebKitGTK (webview + HTML5 transcoded video). The deb/rpm declare these.

Note: appimage is also a valid Tauri target if you want a portable bundle — add it to BUNDLES.

Arch Linux: pacman package

Tauri has no pacman bundle target (as of tauri-cli 2.9.x — valid targets are deb/rpm/appimage/msi/nsis/app/dmg). So we ship a hand-written PKGBUILD in ../packaging/arch/PKGBUILD and build it with makepkg on an Arch base image (../Dockerfile.arch):

bun run docker:build:arch             # .pkg.tar.zst -> ./dist

The PKGBUILD is AUR-ready: swap its source=() for a release tarball/VCS URL to publish. Runtime deps: webkit2gtk-4.1, mpv, gtk3, libayatana-appindicator.

makepkg refuses to run as root, so the Docker stage builds as a non-root builder user. Because the image COPYs the source at build time, the arch-build compose service does not bind-mount the repo — rebuild the image to pick up source changes.

Windows: NSIS installer cross-compiled from Linux

Produces a working (unsigned) NSIS installer + .exe via the official Tauri cross-compile path — the x86_64-pc-windows-msvc target driven by cargo-xwin. Video plays via WebView2 and audio via the webview <audio> backend. See build-windows.md for the full explanation.

bun run docker:build:windows                     # NSIS installer + .exe -> ./dist
WIN_BUNDLES=none bun run docker:build:windows     # exe only, skip bundling

The Docker windows-cross stage is a thin layer over the builder, which carries cargo-xwin + lld + llvm + nsis + the x86_64-pc-windows-msvc target. Cross-compilation is Tauri's "last resort" path (less tested than building on Windows); a windows-latest CI job is the fallback if it misbehaves.