Skip to content

Migrate the browser block from X11 to Wayland (v3) - #207

Merged
flowzone-app[bot] merged 18 commits into
masterfrom
v3-dev/wayland-migration
Oct 8, 2026
Merged

flowzone-app[bot] merged 18 commits into
masterfrom
v3-dev/wayland-migration

Conversation

@rahul-thakoor

@rahul-thakoor rahul-thakoor commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

v3 of the browser block. Chromium now runs as a Wayland client instead of starting its own X server. It renders through a companion display (compositor) block that shares the Wayland socket on a /run volume. This is a breaking release; the full upgrade path is in docs/migrating-from-v2.md.

Breaking changes

  • A display block is required. Compose files must add the display service (bh.cr/balenasolutions/display-<arch>), share a volume at /run, and set XDG_RUNTIME_DIR / WAYLAND_DISPLAY on browser.
  • New image names: one image per device type, published under bh.cr/balenasolutions: browser-raspberrypi3-64, browser-raspberrypi4-64, browser-raspberrypi5, browser-generic-aarch64 and browser-generic-amd64.
  • Dropped targets: fincm3, 32-bit raspberrypi3, arm32 images.
  • Removed variables:
    • ROTATE_DISPLAY, ROTATE_DELAY, TOUCHSCREEN, WINDOW_SIZE, WINDOW_POSITION, SHOW_CURSOR and DISPLAY_NUM. Rotation and resolution are now set on the display block (DISPLAY_ROTATION / DISPLAY_RESOLUTION / DISPLAY_SCALE).
    • FORCE_VULKAN. Chromium's Vulkan backend doesn't work with Ozone Wayland; see docs/todo-vulkan-wayland.md.
  • The audio block is no longer built in. Audio goes directly to ALSA (HDMI and the 3.5mm jack work with no setup). The migration guide shows how to add the audio block back in a derived image.
  • Custom FLAGS / EXTRA_FLAGS that use X11-only switches need review.

New

  • ENABLE_GPU=1 turns on GPU rendering plus best-effort hardware video decode (V4L2 on Raspberry Pi; VA-API on x86, including Intel's iHD/i965 drivers). DISABLE_VIDEO_DECODE=1 turns decode off and keeps GPU rendering.
  • Opt-in /diagnostics/* endpoints (ENABLE_DIAGNOSTICS=1): version, gpu, media, vainfo, and report, a single text bundle to attach to bug reports.
  • Opt-in remote DevTools from another host through a TCP relay (ENABLE_REMOTE_DEBUG=1). It has no authentication, so only use it on trusted networks.
  • Chromium restarts automatically when the display block restarts and recreates its socket.
  • /screenshot uses the DevTools protocol and works under Wayland.
  • The balena.yml usage snippet, repository/logo URLs, package.json and the default landing page now point at balenasolutions.

Tested on

The block no longer starts its own X server. Chromium runs with
--ozone-platform=wayland against the socket that a companion display
(compositor) block exposes on a shared /run volume.

- Replace the X11 packages and the startx/Xwrapper setup with the Mesa
  GL/GBM/VA-API drivers
- Map the host GIDs of /dev/dri, /dev/video* and /dev/snd/* into the
  container so the unprivileged chromium user can use the GPU, V4L2
  video decode and ALSA
- ENABLE_GPU now enables GPU rendering and best-effort hardware video
  decode; DISABLE_VIDEO_DECODE opts out of decode
- Add /diagnostics/{version,gpu,media} endpoints, gated behind
  ENABLE_DIAGNOSTICS (off by default)
- Take /screenshot through the DevTools protocol instead of scrot
- Move to debian:13.2-slim and chrome-launcher 1.x

Change-type: major
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Drop fincm3 and 32-bit raspberrypi3, add generic-amd64 and
generic-aarch64, make raspberrypi4-64 the default device type, and
publish a raspberrypi3-64 block.

Change-type: major
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Chromium binds its DevTools endpoint to localhost only and ignores
--remote-debugging-address outside headless mode, so mapping the port
never made it reachable from another host. With ENABLE_REMOTE_DEBUG=1 a
small TCP relay forwards REMOTE_DEBUG_PORT to Chromium. The relay adds
no authentication or encryption.

Change-type: minor
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Chromium's Vulkan backend does not work with the Ozone Wayland
platform. The options for bringing it back after v3 are recorded in
docs/todo-vulkan-wayland.md.

Change-type: major
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
/diagnostics/report returns a single text file with device and host
info, runtime config, Chromium GPU and media state, and recent block
and Chromium logs, for attaching to bug reports. Diagnostics move into
src/diagnostics.js.

Change-type: minor
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Delete startx.sh and the unused X.org config for the Raspberry Pi 5.
ROTATE_DISPLAY, ROTATE_DELAY, TOUCHSCREEN, WINDOW_SIZE, WINDOW_POSITION,
SHOW_CURSOR and DISPLAY_NUM no longer exist; rotation and resolution
are now configured on the display block. The migration guide maps the
old variables to the new ones.

Change-type: major
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
The image no longer installs the PulseAudio ALSA bridge or sets
PULSE_SERVER. HDMI and the 3.5mm jack work with no extra container.
The migration guide shows how to add the audio block back in a derived
image.

Change-type: major
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
The display block deletes and recreates the Wayland socket on every
restart, which left Chromium disconnected. start.sh now supervises the
session and relaunches it when the socket's inode changes.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
mesa-va-drivers only provides VA-API for AMD/gallium, so on Intel
devices libva exposed zero decode profiles and Chromium fell back to
software for every codec. Install Intel's own VA driver
(intel-media-va-driver for Gen8+, i965-va-driver for older parts) on
amd64; libva auto-selects the right one per GPU.
Also bundle vainfo and surface its output in the diagnostics report
(plus a /diagnostics/vainfo endpoint) so VA profiles can be inspected
directly.
Verified on i3-7100U (Kaby Lake): H.264 and HEVC now decode via
VaapiVideoDecoder (hardware: true).

Change-type: minor
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Use bh.cr/balenasolutions for v3 image references, update the
balena.yml usage snippet for the display block, point the repository,
logo and package.json URLs at balenasolutions/browser, and drop the
balenalabs name from the default landing page.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
@rahul-thakoor
rahul-thakoor force-pushed the v3-dev/wayland-migration branch from 46f2d6d to 036f235 Compare October 1, 2026 13:41
@rahul-thakoor rahul-thakoor changed the title V3 Migrate the browser block from X11 to Wayland (v3) Oct 1, 2026
Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
start.sh printed the VERSION file but never exported it, so server.js had nothing to serve on /version or in the diagnostics report.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Add an endpoint overview, group endpoints, and correct /gpu and /kiosk to POST.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
Lay out the browser block horizontally and highlight it, mute the other
groups, and give every node explicit colours so it reads in dark mode.
Use consistent two-line group titles, label the V4L2 path as H.264
decode on Pi 3/4 only, and show the Wayland socket without its
configurable path.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
@rahul-thakoor
rahul-thakoor marked this pull request as ready for review October 6, 2026 01:46
FLAGS replaces the whole flag set, which also dropped
--ozone-platform=wayland. Chromium then fell back to X11, exited with
"Missing X server or $DISPLAY", and the block failed with ECONNREFUSED
on the debug port and restarted in a loop. Add the Wayland flag unless
FLAGS sets its own --ozone-platform, and document that FLAGS replaces
the kiosk defaults so additive flags belong in EXTRA_FLAGS.

Change-type: patch
Signed-off-by: rahul-thakoor <13220877+rahul-thakoor@users.noreply.github.com>
@flowzone-app
flowzone-app Bot enabled auto-merge October 7, 2026 14:21

@alanb128 alanb128 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs and README look good!

@flowzone-app
flowzone-app Bot merged commit 7335219 into master Oct 8, 2026
58 checks passed
@flowzone-app
flowzone-app Bot deleted the v3-dev/wayland-migration branch October 8, 2026 23:09
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.

2 participants