Skip to content

Native desktop installer (Electron) for Windows, macOS, and Linux#495

Open
Papyszoo wants to merge 6 commits into
copilot/detect-model-name-collisionsfrom
feat/native-installer
Open

Native desktop installer (Electron) for Windows, macOS, and Linux#495
Papyszoo wants to merge 6 commits into
copilot/detect-model-name-collisionsfrom
feat/native-installer

Conversation

@Papyszoo
Copy link
Copy Markdown
Owner

Summary

Ships a native installer track for Modelibr alongside the existing Docker setup. Non-technical users can download a .exe / .dmg / .AppImage from GitHub Releases, install it, and run a fully self-contained Modelibr — bundled frontend, WebApi, asset processor workers, Node runtime, and PostgreSQL — without touching Docker or .env files.

⚠️ Stacked on top of #494. This PR is opened against `copilot/detect-model-name-collisions` so the diff only shows native-installer changes. Once #494 merges to main, this base will be retargeted to `main` and the PR will be ready for a final review pass.

What's in this PR

Backend wiring

  • `DISABLE_HTTPS_LISTENER` + `HTTP_PORT` in WebApi so it can run plain HTTP behind the launcher's edge server.
  • `WEBDAV_PROBE_BASE_URL` makes the WebDAV probe work in both Docker (nginx) and native (edge server) modes.
  • `ENABLE_GPU_RENDERING` toggle in the asset processor — swap swiftshader for real GPU Chromium flags.

Desktop launcher (`src/desktop/`)

  • ProcessManager — starts PostgreSQL → WebApi → workers in order; respawns workers on unexpected exit.
  • EdgeServer — Express reverse proxy on the public app port; terminates `/api/native/runtime` locally, proxies the rest.
  • runtimeConfig — sanitised JSON config in `userData` for port/worker/GPU settings.
  • prepare-bundle script — stages the runtime tree consumed by electron-builder.
  • Loading screen during the multi-second boot, friendly EADDRINUSE message, platform-correct `window-all-closed` (stays alive on macOS).

Frontend

  • Settings gains a Native Runtime accordion section (only visible when `/api/native/runtime` responds): app port, worker process count, jobs per worker, hardware-acceleration checkbox. Apply / Reset buttons with dirty-state tracking and bounds validation.
  • WebDAV help text branches on native vs Docker mode so existing Docker users keep their `.env` guidance.

CI (`.github/workflows/native-release.yml`)

  • build-installers matrix builds `.exe` (Windows), `.dmg` (macOS arm64), `.AppImage` + `.deb` (Linux). Triggers on release publication and `workflow_dispatch`. Always uploads artifacts.
  • test-installers matrix downloads the artifact, installs it silently, starts the app (xvfb on Linux), waits for `http://127.0.0.1:3010\`, exercises `/`, `/api/native/runtime`, `/api/health`, then uninstalls and asserts the app binary is gone while `userData/` survives.

Docs

  • README + docs site now show the native installer path alongside the Docker quick start and point at Settings > Native Runtime for tuning.

Test plan

  • Run the workflow via `workflow_dispatch` and confirm both jobs (`build-installers`, `test-installers`) pass on Windows, macOS, and Linux
  • Download the macOS arm64 `.dmg` artifact, install on an M-series Mac, verify the app boots, the Settings > Native Runtime section renders, and changing the app port + restart works
  • Confirm the Docker setup still works unchanged (no native runtime section should appear in Settings)
  • Verify WebDAV is reachable on the same port as the app in native mode
  • Smoke test thumbnail generation with GPU rendering on and off

Follow-ups (intentionally not in this PR)

  • Auto-update / electron-updater
  • macOS code-signing + notarization for distribution
  • Universal binary (currently Apple Silicon only)

Papyszoo added 6 commits May 15, 2026 01:20
Add DISABLE_HTTPS_LISTENER + HTTP_PORT so the WebApi can run plain HTTP
behind the native launcher's edge server, and make the WebDAV probe
base URL overridable via WEBDAV_PROBE_BASE_URL so the same probe works
in Docker (nginx) and native (edge server) modes.
ENABLE_GPU_RENDERING swaps swiftshader for real GPU Chromium flags so
the native launcher can opt thumbnail workers into GPU rendering on
machines that support it. Default behaviour (software rendering) is
unchanged.
Introduce src/desktop/ — an Electron launcher that bundles the frontend,
WebApi (self-contained .NET publish), asset processor, Node runtime, and
PostgreSQL into a single installable app.

Components:
- ProcessManager — boots PostgreSQL, WebApi, and N worker processes in
  order; restarts workers on unexpected exit.
- EdgeServer — Express reverse proxy on the public app port, terminates
  /api/native/runtime locally and proxies the rest to WebApi/WebDAV.
- runtimeConfig — sanitised JSON config persisted in userData with
  port/worker/GPU settings.
- prepare-bundle script — stages the runtime tree consumed by
  electron-builder.

Startup shows a loading screen until the backend health-checks pass;
EADDRINUSE on the app port surfaces a friendly message; window-all-closed
follows the platform convention (stay alive on macOS).

Root package.json gains stage:desktop and build:desktop scripts.
When the WebApi exposes /api/native/runtime (only in native installs),
Settings shows a "Native Runtime" accordion section to configure the
app port, worker process count, jobs-per-worker, and hardware
acceleration. Port changes flag a restart-required hint; worker
changes apply immediately.

Existing WebDAV help text now branches on whether a native runtime is
detected so Docker users keep their .env guidance.
Adds the Native Installers workflow:
- build-installers job — stages the runtime, dotnet publishes the WebApi
  per-RID, installs PostgreSQL via the platform package manager, and
  produces .exe / .dmg / .AppImage+.deb via electron-builder.
- test-installers job — downloads the built artifact, installs silently,
  starts the app (xvfb on Linux), waits for the HTTP server on port 3010,
  exercises /, /api/native/runtime, and /api/health, then uninstalls and
  asserts that the app binary is gone and userData survives.

macOS target is Apple Silicon (macos-14, osx-arm64, electronArch arm64).
Artifacts are uploaded on every run so the test job can consume them.
README and the docs site now describe the native installer path
(Windows/macOS/Linux) next to the existing Docker quick start, point
users at Settings > Native Runtime for port and worker tuning, and
clarify which deployment path uses .env vs the in-app config.
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.

1 participant