Skip to content
Merged
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
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Build
on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
paths-ignore: ['*.md']
branches: ['master']

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Work this package's `TODO.md` from top to bottom. Keep `README.md` (architecture

## This repo

- **Package id is `bisq`.** Bisq Desktop is a GUI application, served to the browser over a LinuxServer.io KasmVNC base image (`/init` s6 entrypoint). A single `primary` daemon runs it; the only interface is the `ui` web view (host `ui-multi`). Depends on `bitcoind` (Bitcoin full node) for blockchain data.
- **Package id is `bisq`.** Bisq Desktop is a GUI application, served to the browser over a LinuxServer.io Selkies base image (`/init` s6 entrypoint). A single `primary` daemon runs it; the only interface is the `ui` web view (host `ui-multi`). Depends on `bitcoind` (Bitcoin full node) for blockchain data.

## Inspecting a running install

Expand Down
27 changes: 13 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Stage 1: Install Bisq in Ubuntu where the .deb works
FROM ubuntu:jammy AS bisq-builder

ARG BISQ_VERSION=1.10.3
ARG BISQ_VERSION=1.10.4
ARG BISQ_PGP_KEY=B493319106CC3D1F252E19CBF806F422E222AA02

RUN apt-get update && \
Expand All @@ -20,8 +20,8 @@ RUN wget -qO /tmp/Bisq-64bit-${BISQ_VERSION}.deb \
test -d /opt/bisq && \
rm -f /tmp/Bisq-64bit-${BISQ_VERSION}.deb*

# Stage 2: Webtop with bloat removed
FROM ghcr.io/linuxserver/baseimage-kasmvnc:debianbookworm AS buildstage
# Stage 2: Selkies webtop with bloat removed
FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie@sha256:a5f7b38bb806c913bdabbe5667aa462d97d2c5ab3710498fe5aeee97c17287f8 AS buildstage

# Install GTK3, X11 libraries for JavaFX, and wmctrl
RUN apt-get update && \
Expand All @@ -43,13 +43,14 @@ RUN apt-get update && \
libfreetype6 \
libfontconfig1 \
libasound2 \
fonts-dejavu-core \
x11-xserver-utils \
xcvt \
wmctrl && \
# Remove large unused packages from base image
DEBIAN_FRONTEND=noninteractive \
apt-get remove --purge --autoremove -y \
containerd.io \
cpp \
cpp-12 \
docker-ce \
docker-ce-cli \
docker-buildx-plugin \
Expand All @@ -69,14 +70,10 @@ RUN apt-get update && \
COPY --from=bisq-builder /opt/bisq /opt/bisq
RUN ln -s /opt/bisq/bin/Bisq /usr/local/bin/bisq

# Branding, window config — maximize ALL windows, no decorations
# Branding
RUN echo "Bisq for StartOS is loading ..." > \
/etc/s6-overlay/s6-rc.d/init-adduser/branding && \
sed -i '/run_branding() {/,/}/d' /docker-mods && \
sed -i 's|</applications>| <application type="normal">\n <maximized>yes</maximized>\n <decor>no</decor>\n </application>\n</applications>|' \
/etc/xdg/openbox/rc.xml && \
rm -f /etc/cont-init.d/99-deprecation 2>/dev/null || true && \
rm -f /kasmbins/kasm_webcam_server 2>/dev/null || true
sed -i '/^run_branding() {$/,/^}$/c\run_branding() { :; }' /docker-mods

# Stage 3: Flatten into a single layer from scratch
FROM scratch
Expand All @@ -93,17 +90,19 @@ ENV \
S6_VERBOSITY=1 \
S6_STAGE2_HOOK=/docker-mods \
VIRTUAL_ENV=/lsiopy \
PATH="/lsiopy/bin:$PATH" \
PATH="/lsiopy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
DISPLAY=:1 \
PERL5LIB=/usr/local/bin \
OMP_WAIT_POLICY=PASSIVE \
GOMP_SPINCOUNT=0 \
START_DOCKER=false \
PULSE_RUNTIME_PATH=/defaults \
NVIDIA_DRIVER_CAPABILITIES=all
SELKIES_INTERPOSER=/usr/lib/selkies_joystick_interposer.so \
SELKIES_ENCODER="x264enc,jpeg" \
TITLE=Selkies

# Add local files
COPY root/ /
COPY --chmod=755 root/ /

EXPOSE 3000
VOLUME /config
Expand Down
107 changes: 73 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,66 +33,88 @@

## Image and Container Runtime

| Property | Value |
| ------------- | ------------------------------------------------------------------------------------------------------------------- |
| Image source | Custom multi-stage Dockerfile (Ubuntu Jammy builder + KasmVNC Debian Bookworm webtop, flattened via `FROM scratch`) |
| Architectures | x86_64 only |
| Entrypoint | `/init` launched via SDK `runAsInit: true` so the container gets PID 1 for s6-overlay |
| Property | Value |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Image source | Custom multi-stage Dockerfile (Ubuntu Jammy builder + pinned LinuxServer Selkies Debian Trixie webtop, flattened via `FROM scratch`) |
| Architectures | x86_64 only |
| Entrypoint | Upstream `/init` launched via SDK `useEntrypoint()` and `runAsInit: true` so the container gets PID 1 for s6-overlay |

Bisq is a JavaFX desktop application with no web interface. This package runs it inside a browser-accessible Linux desktop (webtop) powered by KasmVNC:
Bisq is a JavaFX desktop application with no web interface. This package runs it inside a browser-accessible Linux desktop (webtop) streamed by Selkies:

```
Browser -> KasmVNC (port 3000) -> Openbox -> Bisq (JavaFX)
Browser -> Selkies (port 3000) -> Openbox -> Bisq (JavaFX)
```

Selkies starts Openbox through its upstream D-Bus session wrapper. The
package-owned `/defaults/autostart` hook launches Bisq inside that session and
is copied over the persisted Openbox autostart file on every launch so upgrades
cannot retain an obsolete KasmVNC/Selkies startup file.

## Volume and Data Layout

| Volume | Mount point | Contents |
| ------ | ----------- | ------------------------------------------------ |
| `main` | `/config` | Webtop home, Bisq application data, `store.json` |

- **`store.json`** — StartOS-managed file storing the admin password (username is hardcoded to `bisq`)
- **`store.json`** — StartOS-managed file storing the desktop password and Bitcoin connection mode (username is hardcoded to `bisq`)
- **`/config/.local/share/Bisq/`** — upstream Bisq data directory (wallet, trades, settings)
- **`/config/.local/share/Bisq/bisq.properties`** — generated at launch by `startwm.sh`
- **`/config/.local/share/Bisq/bisq.properties`** — generated at launch by the Selkies autostart hook

## Installation and First-Run Flow

1. On install, `store.json` is seeded empty (no password set) and the username `bisq` is hardcoded in the service.
2. A **critical task** prompts the user to run the **Set Admin Password** action, which generates a random password and displays the credentials.
3. The password is passed to KasmVNC via the `PASSWORD` environment variable.
3. The credentials are passed to Selkies via the `CUSTOM_USER` and `PASSWORD` environment variables.

Bisq launches directly into the desktop. Any upstream wallet/setup prompts run
inside the Bisq UI after the desktop opens.

## Configuration Management

| StartOS-Managed | Upstream-Managed |
| ------------------------------------- | -------------------------------------------- |
| Admin username and password | All Bisq application settings via its own UI |
| KasmVNC webtop settings (port, auth) | Wallet, trades, offers |
| `bisq.properties` (Tor/network flags) | |

The `bisq.properties` file is regenerated on every launch by `startwm.sh` with:

- `useTorForBtc=false` (StartOS handles Tor at the network level)
- `btcNodes=` (empty — let Bisq discover peers)
- Empty banned node lists (`bannedSeedNodes`, `bannedBtcNodes`, `bannedPriceRelayNodes`)
| StartOS-Managed | Upstream-Managed |
| ------------------------------------ | -------------------------------------------- |
| Admin username and password | All other Bisq application settings via its own UI |
| Bitcoin connection mode | Wallet, trades, offers |
| Selkies webtop settings (port, auth) | |
| `bisq.properties` (Tor/Bitcoin peers) | |

The `bisq.properties` file is regenerated on every launch. The selected mode is:

- **Local node only (default):** `useTorForBtc=false` and
`btcNodes=<bridge address>` target Bitcoin's private, whitelisted
`peer-local` listener. A startup oneshot waits up to one minute for that
listener and fails startup if it remains unreachable.
- **Bisq network fallback:** `useTorForBtc=true` and `btcNodes=<Bisq-provided
peers>` use the remote peer set bundled with the packaged Bisq release over
Tor. In this mode Bitcoin is not a required StartOS dependency.

`startos/main.ts` resolves the live bridge address from Bitcoin's `peer-local`
binding only in local-only mode. The address and connection-mode setting are
watched reactively: Bisq restarts when either changes, but not when Bitcoin
receives a routine update.

Selkies keeps upload and download enabled so users can move Bisq wallet/history
exports between machines. Passwordless sudo, terminal binaries, the remote
command channel, external open helpers, and the unrelated Applications sidebar
are disabled.

## Network Access and Interfaces

| Interface | Port | Protocol | Purpose |
| ------------ | ---- | -------- | ---------------------------------------------------- |
| Bisq Desktop | 3000 | HTTP | KasmVNC web interface (full Bisq desktop in browser) |
| Bisq Desktop | 3000 | HTTP | Selkies web interface (full Bisq desktop in browser) |

Access via LAN (.local), Tor (.onion), or any other address type configured in StartOS. StartOS terminates TLS, so the interface is always available over HTTPS to the user.

## Actions (StartOS UI)

| Action | Purpose | Availability | Inputs | Outputs |
| ---------------------- | ------------------------------------------------------- | ------------ | ------ | ------------------------- |
| **Set Admin Password** | Generate a new random password for the webtop interface | Any status | None | Username and new password |
| Action | Purpose | Availability | Inputs | Outputs |
| -------------------------------- | --------------------------------------------------------------- | ------------ | ----------------------- | ------------------------- |
| **Set Admin Password** | Generate a new random password for the Selkies interface | Any status | None | Username and new password |
| **Configure Bitcoin Connection** | Select local-only mode or the remote Bisq network fallback mode | Any status | Bitcoin connection mode | None |

On first install, this action is triggered automatically as a critical task.
On first install, **Set Admin Password** is triggered automatically as a
critical task.

## Backups and Restore

Expand All @@ -107,17 +129,22 @@ On first install, this action is triggered automatically as a critical task.

## Dependencies

| Dependency | Required | Health check | Purpose |
| -------------------- | -------- | ------------ | --------------- |
| Bitcoin (`bitcoind`) | Yes | `bitcoind` | Blockchain data |
| Dependency | Required | Health check | Purpose |
| -------------------- | ------------------------------ | ------------ | ---------------------------------------------------- |
| Bitcoin (`bitcoind`) | In local-only mode (default) | `bitcoind` | Private, trusted peer connection for blockchain data |

When local-only mode is selected, a recurring critical dependency task requires
Bitcoin's `peerbloomfilters` setting to remain enabled. Switching to fallback
mode clears that task and removes the dependency warning.

## Limitations and Differences

1. **x86_64 only** — Bisq does not provide official ARM builds.
2. **No direct desktop access** — Bisq runs inside a KasmVNC webtop, not as a native desktop app.
2. **No direct desktop access** — Bisq runs inside a Selkies webtop, not as a native desktop app.
3. **`bisq.properties` is overwritten on every start** — manual edits to this file will not persist.
4. **Tor for BTC is disabled** — StartOS manages Tor at the network layer; Bisq's built-in Tor is bypassed.
5. **First launch is slow** — Bisq needs to connect to the P2P trading network and sync, which can take several minutes.
4. **Local-only mode fails closed** — Bisq does not silently use remote Bitcoin peers when the local node is missing or unreachable.
5. **Fallback mode uses remote peers over Tor** — select it explicitly with the Configure Bitcoin Connection action when a local Bitcoin node is not available.
6. **First launch is slow** — Bisq needs to connect to the P2P trading network and sync, which can take several minutes.

## What Is Unchanged from Upstream

Expand All @@ -137,23 +164,35 @@ Build and development workflow follow the StartOS packaging guide: <https://docs

```yaml
package_id: bisq
image: custom dockerBuild (multi-stage: ubuntu + baseimage-kasmvnc, flattened via FROM scratch)
image: custom dockerBuild (multi-stage: ubuntu + pinned baseimage-selkies, flattened via FROM scratch)
architectures: [x86_64]
volumes:
main: /config
ports:
ui: 3000
dependencies:
- bitcoind (running, health check: bitcoind)
- bitcoind (local-only mode; running, health check: bitcoind)
startos_managed_env_vars:
- CUSTOM_USER
- PASSWORD
- BITCOIN_CONNECTION_MODE
- BITCOIND_PEER_ADDR
- BISQ_NETWORK_FALLBACK_NODES
- PUID
- PGID
- TZ
- TITLE
- S6_CMD_WAIT_FOR_SERVICES_MAXTIME
- S6_VERBOSITY
- NO_DECOR
- DISABLE_OPEN_TOOLS
- DISABLE_SUDO
- DISABLE_TERMINALS
- SELKIES_COMMAND_ENABLED
- SELKIES_UI_SIDEBAR_SHOW_APPS
- SELKIES_UI_SIDEBAR_SHOW_FILES
- SELKIES_FILE_TRANSFERS
actions:
- set-password
- configure-bitcoin-connection
```
15 changes: 14 additions & 1 deletion UPDATING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Updating the upstream version

This package wraps the Bisq desktop application (from `bisq-network/bisq`), installing the upstream `.deb` published at `bisq.network/downloads/v<version>/` into a KasmVNC webtop image and verifying it against a pinned PGP key.
This package wraps the Bisq desktop application (from `bisq-network/bisq`), installing the upstream `.deb` published at `bisq.network/downloads/v<version>/` into a LinuxServer Selkies webtop image and verifying it against a pinned PGP key.

## Determining the upstream version

Expand All @@ -15,3 +15,16 @@ This package wraps the Bisq desktop application (from `bisq-network/bisq`), inst
## Applying the bump

- **Bisq**: in `Dockerfile`, update the `ARG BISQ_VERSION=...` line to the new version (without the leading `v`). If upstream rotated signers, also update `ARG BISQ_PGP_KEY=...` to the new fingerprint.

- **Bisq-provided Bitcoin peers**: compare `startos/utils.ts`'
`bisqNetworkFallbackNodes` with `BtcNodes.getProvidedBtcNodes()` in the
matching upstream Bisq tag. The explicit list ensures that switching from a
persisted local custom node to fallback mode takes effect.

- **Selkies base image**: `Dockerfile` pins the multi-architecture `ghcr.io/linuxserver/baseimage-selkies:debiantrixie` image by OCI index digest. Verify the current tag and architectures with:

```
docker buildx imagetools inspect ghcr.io/linuxserver/baseimage-selkies:debiantrixie
```

When intentionally updating the base, replace the digest in the `FROM` line and confirm that the flattened image's `ENV` block still matches the base image's runtime environment.
Loading