Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/renovate.json5
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
$schema: "https://docs.renovatebot.com/renovate-schema.json",
extends: ["config:recommended", ":disableRateLimiting"],
includePaths: ["**/src/renderer/lib/**"],
includePaths: ["**/src/renderer/lib/**", "flatpak/**"],
regexManagers: [
{
fileMatch: ["src/renderer/lib/install\\.ts$"],
Expand Down
100 changes: 100 additions & 0 deletions .github/workflows/flatpak-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Optional GitHub Pages site: static Flatpak repo + .flatpakrepo / .flatpakref / bundle.
# Enable Pages (branch: gh-pages) in repo Settings before relying on this workflow.
name: Publish Flatpak repository

on:
workflow_dispatch:
push:
tags:
- "v*"

permissions:
contents: write

concurrency:
group: flatpak-pages-${{ github.repository }}
cancel-in-progress: true

jobs:
pages-flatpak-repo:
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Update USB IDs database
run: |
rm -f data/usb.ids
curl -fsSL -o data/usb.ids http://www.linux-usb.org/usb.ids

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev libusb-1.0-0-dev flatpak flatpak-builder

- name: Set up Bun
uses: oven-sh/setup-bun@v2

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"
cache-dependency-path: "guest_server/go.sum"

- name: Cache Flatpak builder state
uses: actions/cache@v4
with:
path: |
~/.flatpak-builder/cache
flatpak/.flatpak-builder-state
key: flatpak-${{ runner.os }}-24.08-${{ hashFiles('flatpak/app.winboat.WinBoat.yml') }}
restore-keys: |
flatpak-${{ runner.os }}-24.08-

- name: Install dependencies
run: bun ci

- name: Build Linux unpacked (dir target; no RPM)
run: bun run build:linux-dir
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ELECTRON_BUILDER_COMPRESSION_LEVEL: 5

- name: Build Flatpak repo and bundle
run: bun run build:flatpak

- name: Assemble Pages directory
run: |
set -eux
OWNER="${GITHUB_REPOSITORY%%/*}"
REPO="${GITHUB_REPOSITORY##*/}"
BASE_URL="https://${OWNER}.github.io/${REPO}"
mkdir -p site/repo
cp -a flatpak/.flatpak-repo-local/. site/repo/
cp dist/winboat.flatpak site/
cp flatpak/pages-index.html site/index.html
{
echo '[Flatpak Repo]'
echo 'Title=WinBoat'
echo "Url=${BASE_URL}/repo/"
echo "Homepage=https://github.com/${GITHUB_REPOSITORY}"
echo 'Comment=Nightly Flatpak repository (unsigned unless you add GPG)'
echo 'Description=WinBoat — Windows apps on Linux via containers'
} > site/winboat.flatpakrepo
{
echo '[Flatpak Ref]'
echo 'Name=app.winboat.WinBoat'
echo 'Branch=stable'
echo 'Title=WinBoat'
echo "Url=${BASE_URL}/repo/"
echo 'RuntimeRepo=https://flathub.org/repo/flathub.flatpakrepo'
echo 'IsRuntime=false'
echo 'SuggestRemoteName=winboat'
} > site/winboat.flatpakref

- name: Deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
force_orphan: true
33 changes: 31 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,23 @@ jobs:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev libusb-1.0-0-dev
sudo apt-get install -y libudev-dev libusb-1.0-0-dev flatpak flatpak-builder rpm
- name: Set up Bun
uses: oven-sh/setup-bun@v2
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"
cache-dependency-path: "guest_server/go.sum"
- name: Cache Flatpak builder state
uses: actions/cache@v4
with:
path: |
~/.flatpak-builder/cache
flatpak/.flatpak-builder-state
key: flatpak-${{ runner.os }}-24.08-${{ hashFiles('flatpak/app.winboat.WinBoat.yml') }}
restore-keys: |
flatpak-${{ runner.os }}-24.08-
- name: Install dependencies
run: bun ci
- name: Build guest server and app
Expand All @@ -77,6 +86,14 @@ jobs:
*) echo "ARCH=$BUN_ARCH" >> "$GITHUB_OUTPUT" ;;
esac
fi
- name: Build Flatpak bundle
run: bun run build:flatpak
- name: Upload Flatpak bundle
uses: actions/upload-artifact@v4
with:
name: ${{ steps.meta.outputs.NAME }}-${{ steps.meta.outputs.VERSION }}-${{ steps.meta.outputs.ARCH }}.flatpak
path: dist/winboat.flatpak
if-no-files-found: error
- name: Upload AppImage
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -167,21 +184,32 @@ jobs:
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libudev-dev libusb-1.0-0-dev
sudo apt-get install -y libudev-dev libusb-1.0-0-dev flatpak flatpak-builder rpm
- name: Set up Bun
uses: oven-sh/setup-bun@v2
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "stable"
cache-dependency-path: "guest_server/go.sum"
- name: Cache Flatpak builder state
uses: actions/cache@v4
with:
path: |
~/.flatpak-builder/cache
flatpak/.flatpak-builder-state
key: flatpak-${{ runner.os }}-24.08-${{ hashFiles('flatpak/app.winboat.WinBoat.yml') }}
restore-keys: |
flatpak-${{ runner.os }}-24.08-
- name: Install dependencies
run: bun ci
- name: Build guest server and app
run: bun run build:linux-gs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ELECTRON_BUILDER_COMPRESSION_LEVEL: 5
- name: Build Flatpak bundle
run: bun run build:flatpak
- name: Zip unpacked variant
run: cd dist && zip -r winboat-linux-unpacked.zip linux-unpacked/
- name: Create GitHub Release
Expand All @@ -192,6 +220,7 @@ jobs:
dist/*.deb
dist/*.rpm
dist/*.tar.bz2
dist/winboat.flatpak
dist/winboat-linux-unpacked.zip
dist/latest-linux.yml
dist/linux-unpacked/resources/guest_server/winboat_guest_server.zip
Expand Down
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@ package-lock.json
# *.exe
temp
guest_server/winboat_guest_server.exe
guest_server/winboat_guest_server.zip
guest_server/winboat_guest_server.zip

# Local Flatpak builder outputs
flatpak/.flatpak-build-dir
flatpak/.flatpak-repo-local
flatpak/.flatpak-builder-state
.flatpak-builder
91 changes: 87 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,12 @@ Before running WinBoat, ensure your system meets the following requirements:

## Downloading

You can download the latest Linux builds under the [Releases](https://github.com/TibixDev/winboat/releases) tab. We currently offer four variants:
You can download the latest Linux builds from **[Releases](https://github.com/TibixDev/winboat/releases)** (created when you push a **`v*`** tag or run **Actions → Build WinBoat → Run workflow** with **Build type: all**) and from **every push to `main`** via **Actions → latest run → Artifacts** (AppImage, `.flatpak`, etc.).

We currently offer these variants:

- **AppImage:** A popular & portable app format which should run fine on most distributions
- **Flatpak (`winboat.flatpak`):** After each successful **`build`** workflow on `main`, download the artifact named like `winboat-*-x86_64.flatpak`, extract it if zipped (GitHub zips single-file artifacts), then run `flatpak install --bundle ./winboat.flatpak`. The same file is attached to **Releases** when a release is produced. Uses Flatpak app ID `app.winboat.WinBoat` (for stores like Flathub); your Electron/desktop integration ID remains `com.teabox.winboat`. When you bump `package.json` **version**, update `<release version="…"/>` in [`flatpak/app.winboat.WinBoat.metainfo.xml`](flatpak/app.winboat.WinBoat.metainfo.xml) for accurate store metadata.
- **Unpacked:** The raw unpacked files, simply run the executable (`linux-unpacked/winboat`)
- **.deb:** The intended format for Debian based distributions
- **.rpm:** The intended format for Fedora based distributions
Expand All @@ -81,18 +84,98 @@ You can download the latest Linux builds under the [Releases](https://github.com
virtualisation.docker.enable = true;
users.users.{yourUser}.extraGroups = ["docker"];
```

### Flatpak details

WinBoat drives **Docker or Podman on the host** and uses **KVM** (`/dev/kvm`) for the Windows VM inside [dockur/windows](https://github.com/dockur/windows). The Flatpak is wired for that: host home directory access, container sockets (`/run/docker.sock`, XDG Podman paths), DRI, Pulse/PipeWire audio, **session + system D-Bus** (so Chromium/Electron stops probing a missing `/run/dbus/system_bus_socket`), **`ELECTRON_TRASH=gio`**, host icon paths for cursor scaling under Wayland, and talking to the host Flatpak session so `flatpak run com.freerdp.FreeRDP` can satisfy FreeRDP 3.

Packaging follows ideas from the official [Electron on Flatpak](https://docs.flatpak.org/en/latest/electron.html) guide. This repo **repacks your existing `linux-unpacked` Electron build** (self-contained binary). The Flathub-style alternative is **`org.electronjs.Electron2.BaseApp`** plus a **`zypak-wrapper`** launcher so Chromium is shared and sandbox integration matches upstream samples—that would be a larger manifest rewrite than the current “bundle what electron-builder produced” flow.

The Flatpak wrapper runs Electron with **`--no-sandbox`** / **`--disable-setuid-sandbox`**: Chromium’s setuid `chrome-sandbox` cannot be root-owned inside a Flatpak, so process isolation for the UI relies on **Flatpak’s sandbox** instead (same pattern as many other Electron Flatpaks). **`--ozone-platform-hint=auto`** is passed so Wayland is used when the session supports it (still consider X11/Xwayland the most predictable default per the guide).

#### Host tools when you install the Flatpak (Docker + FreeRDP)

The setup wizard talks to the **host**: install and run these **outside** the Flatpak. The Flatpak does **not** ship the `docker` / `podman` CLIs; WinBoat runs them on the host with **`flatpak-spawn --host`** (see [`flatpak-host.ts`](src/renderer/lib/flatpak-host.ts)) while using the mounted **Docker/Podman sockets**. You still need **`--talk-name=org.freedesktop.Flatpak`** in the manifest (already set).

| Check | Debian/Ubuntu-style hints |
|--------|---------------------------|
| **Docker Engine** | `sudo apt install docker.io` (or Docker’s official repo). |
| **Docker Compose v2** | `sudo apt install docker-compose-v2` (plugin: `docker compose version`). |
| **`docker` group** | `sudo usermod -aG docker "$USER"` then **log out and back in** (or reboot). |
| **Daemon running** | `sudo systemctl enable --now docker` then `docker ps`. |
| **FreeRDP 3.x** | Install **`xfreerdp3`** on the host, **or** `flatpak install --user flathub com.freerdp.FreeRDP` (WinBoat probes the host via `flatpak-spawn --host …`). Verify on the host: `xfreerdp3 --version` or `flatpak run com.freerdp.FreeRDP --command=xfreerdp -- --version`. |

Use **Podman** instead of Docker if you prefer; the Flatpak exposes `xdg-run/podman` paths for the rootless socket.

**Flathub:** Publishing on [Flathub](https://flathub.org/) is a separate submission ([author docs](https://docs.flathub.org/docs/for-app-authors/submission)). Reviewers treat apps that depend heavily on host services case-by-case; upstream maintenance expectation applies especially where emulation or host tooling is involved. The canonical manifest for packaging lives at [`flatpak/app.winboat.WinBoat.yml`](flatpak/app.winboat.WinBoat.yml).

**Optional GitHub Pages repo:** The workflow [flatpak-pages.yml](.github/workflows/flatpak-pages.yml) builds an OSTree repo plus `.flatpakrepo`, `.flatpakref`, and a bundle on tags (`v*`) or manual dispatch, and pushes them to the `gh-pages` branch (enable **Pages** in the repo settings first). To mirror Flathub’s builder locally:

```bash
docker run --rm -it -v "$PWD:/work" -w /work ghcr.io/flathub-infra/flatpak-builder:stable \
flatpak-builder --help
```
## Known Issues About Container Runtimes

- Docker Desktop is **unsupported** for now
- USB passthrough via Podman is currently **unsupported**

## Building WinBoat

- For building you need to have Bun and Go installed on your system
- For building you need **Bun**, **Go**, and **Node.js** (see `engines` in `package.json`; Vite’s CLI runs under `node` during production builds)
- Clone the repo (`git clone https://github.com/TibixDev/WinBoat`)
- Install the dependencies (`bun i`)
- Build the app and the guest server using `bun run build:linux-gs`
- You can now find the built app under `dist` with an AppImage and an Unpacked variant

**Linux outputs:**

| Command | Produces | Notes |
|--------|----------|--------|
| `bun run build:linux-dir` | `dist/linux-unpacked/` only | No AppImage/deb/rpm; **no `rpmbuild`** needed — use this before Flatpak locally. |
| `bun run build:linux-gs` | AppImage, deb, **rpm**, tar.bz2, unpacked | On Debian/Ubuntu install **`rpm`** so electron-builder can call `rpmbuild`: `sudo apt install rpm`. |

CI installs **`rpm`** alongside **`flatpak`** / **`flatpak-builder`** so release jobs match your `electron-builder.json` targets.

### Building the Flatpak bundle locally

You need **`flatpak`** and **`flatpak-builder`** (e.g. `sudo apt install flatpak flatpak-builder`). The first run downloads the Freedesktop SDK/runtime from Flathub and can take a while.

The source build expects **`Node.js` on your `PATH`** so Vite runs under Node; Bun runs scripts and installs deps. If you see `Cannot find module 'vite/module-runner'`, run `rm -rf node_modules && bun install` so **Vite stays at 7.3.1** (pinned in `package.json` + `overrides`).

**Recommended one-shot** (unpack dir target + bundle — avoids RPM tooling):

```bash
bun run build:linux-flatpak
flatpak install --bundle ./dist/winboat.flatpak
```

If you already built unpacked output (`build:linux-dir` or `build:linux-gs`):

```bash
bun run build:flatpak
```

Gitignored Flatpak working dirs: `flatpak/.flatpak-build-dir`, `flatpak/.flatpak-repo-local`, `flatpak/.flatpak-builder-state`, and repo-root **`.flatpak-builder`** (cache flatpak-builder sometimes writes next to the project). **`electron-builder` excludes `flatpak/` and `.flatpak-builder/`** so it does not traverse sandbox or cache trees (`EACCES` under paths like `wpa_supplicant`). If problems persist, delete those directories — avoid `chmod -R` on them.

### Bun install and Docker

- **Host install:** `curl -fsSL https://bun.sh/install | bash` then restart your shell (or `source ~/.bashrc`).
- **`oven/bun`** images ship Bun only — they do **not** include Flatpak, `rpmbuild`, or your distro libraries. Use them only for steps like `bun ci` / `bun run build:linux-dir` **inside** a volume-mounted repo; run **`flatpak/build-bundle.sh`** on the host (or use a **full OS container** below).

**Full Linux build in Docker (example):** Debian/Ubuntu base + deps + Bun + Node + Go + Flatpak tooling + `rpm` for parity with CI:

```bash
docker run --rm -it \
-v "$(pwd):/src" -w /src \
ubuntu:22.04 bash -lc '
apt-get update && apt-get install -y curl ca-certificates git unzip \
libudev-dev libusb-1.0-0-dev flatpak flatpak-builder rpm golang-go nodejs npm &&
curl -fsSL https://bun.sh/install | bash &&
export PATH="$HOME/.bun/bin:$PATH" &&
bun ci && bun run build:linux-flatpak
'
```

Use a **newer Node** than the default `nodejs` package if your distro’s version is below `engines.node` (e.g. install from [nodejs.org](https://nodejs.org/) inside the image).

## Running WinBoat in development mode

Expand Down
5 changes: 4 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion electron-builder.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
},
"!build",
"!dist",
"!scripts"
"!scripts",
"!flatpak",
"!.flatpak-builder"
],
"extraResources": [
{
Expand Down
10 changes: 10 additions & 0 deletions flatpak/app.winboat.WinBoat.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Version=1.5
Name=WinBoat
Comment=Run Windows apps on Linux with Docker or Podman
Exec=winboat %u
Icon=app.winboat.WinBoat
Categories=Utility;System;
Terminal=false
StartupNotify=true
Loading