Files
multi-monitor-kiosk/README.md
T
2026-07-06 16:32:50 +02:00

76 lines
3.3 KiB
Markdown

# Scalable Multi-Monitor Kiosk
A Docker Compose-based project designed to run multiple hardware-accelerated Chromium kiosk instances across multiple monitors (e.g., the dual HDMI ports of a Raspberry Pi 4).
Each Chromium instance provides an HTTP API (inspired by the [balena browser block](https://github.com/balena-io-experimental/browser)) that allows you to dynamically control the browser's URL, refresh behavior, kiosk mode, and GPU settings on the fly.
## Architecture
This project uses a robust **X11 Architecture** designed specifically to avoid the complexities of Virtual Terminals and Session Management inside headless Docker containers.
1. **`display-manager` Container**: Runs a central Xorg server with direct access to the GPU (`/dev/dri`). It exposes the X11 Unix socket to the other containers.
2. **`kiosk` Containers**: Individual, scalable containers running Node.js and Chromium.
- **Resolution Independence**: On startup, each kiosk uses `xrandr` to dynamically detect the exact resolution and physical offset of its assigned monitor (e.g., `HDMI-1`). It then perfectly frames its Chromium window to that specific screen.
## Prerequisites
- Docker and Docker Compose installed.
- A host machine with KMS/DRM graphics capabilities (like a Raspberry Pi 4 running Debian/Raspberry Pi OS).
- Multiple displays connected.
## Getting Started
1. **Clone the repository** and navigate to the root directory.
2. **Build and start the stack**:
```bash
docker-compose up -d --build
```
3. The display manager will initialize the X server, and the two kiosk instances will launch on their respective monitors.
## Scaling
To add a third monitor (e.g., `HDMI-3`), simply add a new service to `docker-compose.yml`:
```yaml
kiosk-3:
build: ./kiosk
restart: always
depends_on:
- display-manager
ports:
- "5013:5011"
volumes:
- x11-socket:/tmp/.X11-unix
devices:
- "/dev/dri:/dev/dri"
environment:
- DISPLAY=:0
- MONITOR=HDMI-3
- PORT=5011
- LAUNCH_URL=https://example.com
```
## API Reference
Each kiosk exposes an API on its mapped port (e.g., `5011` for HDMI-1, `5012` for HDMI-2).
### Status & Information
* **`GET /ping`**: Returns `HTTP 200 OK` if the browser is ready.
* **`GET /url`**: Returns the URL currently being displayed.
* **`GET /flags`**: Returns the internal flags Chromium was started with.
* **`GET /version`**: Returns the version of Chromium running.
* **`GET /screenshot`**: Returns a `.png` screenshot of the X11 display.
### Navigation
* **`POST /url`**: Sets the URL to be displayed (send as JSON or URL-encoded form data).
* *Example*: `curl -X POST -d "url=https://wikipedia.org" http://localhost:5011/url`
* *Note*: You can also pass `gpu=0|1` and `kiosk=0|1` alongside the URL.
* **`POST /refresh`**: Reloads the current page.
* **`POST /autorefresh/{interval}`**: Automatically refreshes the browser window every X seconds (send `0` to disable).
### Configuration
* **`GET /kiosk`**: Returns `1` if kiosk mode is enabled, `0` if disabled.
* **`PUT /kiosk/{value}`**: Enables (`1`) or disables (`0`) kiosk mode (restarts the browser).
* **`GET /gpu`**: Returns `1` if GPU acceleration is enabled, `0` if disabled.
* **`PUT /gpu/{value}`**: Enables (`1`) or disables (`0`) hardware acceleration (restarts the browser).