- HTML 59%
- Shell 28.9%
- JavaScript 12.1%
| scripts | ||
| server | ||
| systemd | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| install-online.sh | ||
| README.md | ||
| TASK.md | ||
🖥️ Linux Kiosk Manager
A complete Linux kiosk solution — fullscreen Chromium display with a web-based management interface to update the displayed URL remotely.
Tested on Debian 13 (Trixie).
Architecture
┌──────────────────────────────────────────────────────┐
│ Linux machine │
│ │
│ kiosk-xorg.service │
│ └─ xinit → /etc/kiosk/xinitrc │
│ └─ chromium --kiosk (reads config.json) │
│ ↑ restarts on URL change / crash │
│ │
│ kiosk-manager.service :8080 │
│ └─ Node.js REST API + Web UI │
│ └─ writes /etc/kiosk/config.json │
└──────────────────────────────────────────────────────┘
Install
curl -fsSL https://git.bennellit.com.au/sb/linux-kiosk/raw/branch/main/install-online.sh | sudo bash
Options
sudo KIOSK_URL="https://mydashboard.com" MANAGER_PORT=8080 bash install-online.sh
| Variable | Default | Description |
|---|---|---|
KIOSK_URL |
https://example.com |
Initial URL to display |
MANAGER_PORT |
8080 |
Web UI port |
KIOSK_TOKEN |
random hex | Auth token |
KIOSK_USER |
kiosk |
Linux user |
INSTALL_DIR |
/opt/kiosk-manager |
Server path |
Reinstalls preserve the existing KIOSK_TOKEN and KIOSK_URL automatically — no need to pass them again.
Management UI
Open http://<kiosk-ip>:8080 from any device on your network.
Features:
- Update the displayed URL and label
- Toggle mouse cursor visibility (takes effect within 3 s, no restart needed)
- Screen rotation: Normal, Left 90°, Right 270°, Inverted 180° (browser restarts to apply)
- View system status (Chromium, uptime, IP, display)
- URL history with one-click reload
- Restart the kiosk browser
REST API
# Get config
curl -H "Authorization: Bearer $TOKEN" http://kiosk-ip:8080/api/config
# Update URL
curl -X POST http://kiosk-ip:8080/api/config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":"https://newpage.com","label":"My Page"}'
# Enable mouse cursor
curl -X POST http://kiosk-ip:8080/api/config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"mouseEnabled":true}'
# Enable portrait mode
curl -X POST http://kiosk-ip:8080/api/config \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"screenRotation":"left"}'
# Available: "normal", "left" (90°), "right" (270°), "inverted" (180°)
# Restart browser
curl -X POST http://kiosk-ip:8080/api/reload \
-H "Authorization: Bearer $TOKEN"
Files
linux-kiosk/
├── install-online.sh ← Installer
├── scripts/
│ └── xinitrc ← X session + Chromium launcher
├── server/
│ ├── server.js ← Node.js management server
│ └── public/
│ └── index.html ← Management web UI
└── systemd/
├── kiosk-xorg.service ← X + Chromium session
└── kiosk-manager.service ← Web management server
WiFi / network boot
On WiFi machines the kiosk waits for network connectivity before launching Chromium, so the page loads cleanly on the first attempt. The X session is held by systemd until network-online.target is reached, and xinitrc additionally pings 1.1.1.1 for up to 60 seconds as a fallback. Progress is logged to /var/log/kiosk.log.
DHCP reservations (Windows Server / Debian 13 minimal)
Debian 13 minimal installs send a DUID-based client identifier instead of the MAC address by default. This causes Windows Server DHCP to show a long hex string rather than the MAC, making reservations by MAC address fail.
The installer automatically configures dhcpcd to use the hardware MAC address as the client identifier (clientid in /etc/dhcpcd.conf), covering both WiFi and wired Ethernet on Debian 13 minimal installs.
Useful commands
# View kiosk log
sudo tail -f /var/log/kiosk.log
# Service status
sudo systemctl status kiosk-xorg kiosk-manager
# Restart kiosk browser
sudo systemctl restart kiosk-xorg.service
# Change token
sudo nano /etc/systemd/system/kiosk-manager.service
sudo systemctl daemon-reload && sudo systemctl restart kiosk-manager