Cruscotto Kiosk Touchscreen su ZimaBoard 2 con Docker (X.Org + Chromium)

Eva Wong è la Technical Writer e smanettatrice residente di ZimaSpace. Una geek da sempre con una passione per homelab e software open source, si specializza nel tradurre concetti tecnici complessi in guide pratiche e accessibili .Eva crede che l'auto-hosting debba essere divertente, non intimidatorio. Attraverso i suoi tutorial, dà potere alla community di demistificare le configurazioni hardware, dalla costruzione del primo NAS al dominio dei container Docker.

Ciao a tutti,

Volevo condividere come ho fatto funzionare un kiosk touchscreen a schermo intero sul mio ZimaBoard 2 collegato a un monitor touch da 22" via HDMI.

Poiché ZimaOS non ha un gestore di pacchetti (apt non esiste), il trucco è fare tutto dentro container Docker.

La mia configurazione

ZimaBoard 2 1664 (Intel N100, 16 GB RAM)

ZimaOS v1.5.4

Monitor touch da 22" via HDMI + input touchscreen USB-C→USB-A

Primo piano di un case PC Thermaltake Tower 900 bianco e rosso, con illuminazione LED blu personalizzata e vista dettagliata dei componenti interni, incluso un processore Intel e memoria.

L'approccio

ZimaOS è basato su Buildroot — niente apt, niente Xorg, niente ambiente desktop. Invece, eseguiamo un container Debian con driver Xorg modesetting + Chromium in modalità kiosk, con /dev/dri passato. Un container nginx:alpine separato serve i file della dashboard.

Passo 1 — Aggiungi il tuo utente al gruppo docker

Apri il terminale web su http://your-zima-ip:7681 ed esegui:

bash

sudo usermod -aG docker TUO_NOME_UTENTE

Poi riconnetti SSH per applicare la modifica.

Passo 2 — Crea i file

bash

mkdir -p /DATA/AppData/kiosk/dashboard

/DATA/AppData/kiosk/Dockerfile:

text

FROM debian:bookworm-slim
RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list
RUN apt-get update && \
apt-get install -y \
xserver-xorg-core \
xserver-xorg-input-libinput \
openbox chromium \
x11-xserver-utils xinit \
fonts-noto-core && \
apt-get install -y -t bookworm-backports libgl1-mesa-dri && \
rm -rf /var/lib/apt/lists/*
COPY xorg.conf /etc/X11/xorg.conf
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

Perché backportare Mesa? L'Intel N100 (Alder Lake-N, PCI ID 0x46d4) è supportato solo da Mesa 23.0+. Debian bookworm include la 22.3. I backport forniscono la 25.x.

/DATA/AppData/kiosk/xorg.conf:

text

Sezione "Dispositivo"
Identificatore "Intel"
Driver "modesetting"
Opzione "MetodoAccel" "nessuno"
EndSection

Sezione "Schermo"
Identificatore "Predefinito"
Dispositivo "Intel"
EndSection

Sezione "Dispositivo di input"
Identificatore "Touchscreen"
Driver "libinput"
Opzione "Dispositivo" "/dev/input/event8"
EndSection

Sezione "ServerLayout"
Identificatore "Predefinito"
Schermo "Predefinito"
Dispositivo di input "Touchscreen" "CorePointer"
EndSection

Trova il numero evento del tuo dispositivo touch con:

bash

cat /proc/bus/input/devices | grep -A3 -i touch

/DATA/AppData/kiosk/entrypoint.sh:

text

#!/bin/sh
Xorg :0 vt1 -s 0 -dpms -nolisten tcp &
sleep 4
export DISPLAY=:0
xset s off && xset -dpms && xset s noblank
openbox --sm-disable &
sleep 1
exec chromium \
--kiosk --no-sandbox --disable-gpu \
--disable-dev-shm-usage \
--touch-events=enabled \
--no-first-run --disable-infobars \
"${KIOSK_URL:-http://localhost:8888}"

/DATA/AppData/kiosk/nginx.conf:

text

server {
listen 8888;
root /usr/share/nginx/html;
index index.html;
}

Metti i tuoi file HTML/CSS/JS della dashboard in /DATA/AppData/kiosk/dashboard/.

Vista dall'alto del server single board ZimaBoard, evidenziando lo slot di espansione PCIe, le doppie porte Ethernet e i connettori SATA per l'integrazione di progetti fai-da-te.

Passo 3 — Costruisci e Avvia

Costruisci (nota: docker build richiede --config /tmp su ZimaOS):

bash

docker --config /tmp build -t kiosk:latest /DATA/AppData/kiosk

Server web Dashboard:

bash

docker --config /tmp run -d \
--name dashboard-server \
--restart unless-stopped \
--network host \
-v /DATA/AppData/kiosk/dashboard:/usr/share/nginx/html:ro \
-v /DATA/AppData/kiosk/nginx.conf:/etc/nginx/conf.d/default.conf:ro \
nginx:alpine

Schermo Kiosk:

bash

docker --config /tmp run -d \
--name jarvis-kiosk \
--restart unless-stopped \
--privileged \
--network host \
-e KIOSK_URL=http://localhost:8888 \
-v /DATA/AppData/kiosk/xorg.conf:/etc/X11/xorg.conf:ro \
-v /DATA/AppData/kiosk/entrypoint.sh:/entrypoint.sh:ro \
-v /run/udev:/run/udev:ro \
kiosk:latest

Entrambi i container hanno --restart unless-stopped quindi sopravvivono automaticamente ai riavvii.

Correzione click touchscreen (importante!)

La libreria libinput di Xorg mappa il tocco come eventi puntatore (mouse). Chromium applica quindi una soglia di movimento minima per il click — anche uno spostamento del dito di 1px impedisce il click. Se la tua dashboard usa gestori onclick, aggiungi questo JS per sostituirli con pointerup + una soglia di 20px:

js

(function touchFix() {
const downs = {};
document.addEventListener('pointerdown', e => {
downs[e.pointerId] = { x: e.clientX, y: e.clientY };
}, { passive: true });
function isTap(e) {
const d = downs[e.pointerId];
return !d || (Math.abs(e.clientX - d.x) < 20 && Math.abs(e.clientY - d.y) < 20);
}
function run(fn) { try { new Function(fn)(); } catch(ex) {} }
function patchButtons(root) {
root.querySelectorAll('button[onclick]').forEach(btn => {
const oc = btn.getAttribute('onclick');
btn.removeAttribute('onclick');
btn.addEventListener('pointerup', e => { e.stopPropagation(); if (isTap(e)) run(oc); });
});
}
window.addEventListener('load', () => {
document.querySelectorAll('.widget[onclick]').forEach(el => {
const oc = el.getAttribute('onclick');
el.removeAttribute('onclick');
el.addEventListener('pointerup', e => { if (isTap(e) && !e.target.closest('button')) run(oc); });
});
patchButtons(document.body);
});
new MutationObserver(muts => muts.forEach(m =>
m.addedNodes.forEach(n => { if (n.nodeType === 1) patchButtons(n); })
)).observe(document.body, { childList: true, subtree: true });
})();

Aggiungi anche al tuo CSS per nascondere il cursore del mouse su un touchscreen:

css

{ cursor: none !important; touch-action: manipulation; }

Un monitor touch Pisichen da 22 pollici collegato a uno ZimaBoard tramite HDMI e USB, che mostra una dashboard smart home personalizzata con widget interattivi.

Risoluzione problemi

Problema Correzione
docker build fallisce con flag sconosciuto Usa docker --config /tmp build …
Schermo nero / Test di output base fallito Usa Xorg modesetting, non Wayland/cage
Mesa non supporta N100 Installa libgl1-mesa-dri da bookworm-backports
Input touch non rilevato Controlla il numero dell'evento con /proc/bus/input/devices, aggiorna xorg.conf
La dashboard mostra il login di ZimaOS La porta 80 è occupata da ZimaOS — usa una porta diversa (va bene la 888)

Il mio setup Always-On di Home Assistant (Risposta)

Ho costruito un setup di home assistant a basso consumo energetico disponibile 24/7 senza che il mio PC principale consumi elettricità tutto il giorno. L'arma segreta è un Zima che funge da cervello sempre attivo, mentre il mio PC completo rimane in ibernazione finché non è effettivamente necessario.

Il PC principale

Ecco cosa c'è all'interno della macchina principale:

CPU: AMD Ryzen 9 9950X3D

Scheda madre: ASUS ROG Crosshair X870E Glacial

RAM: Acer Predator Hermes RGB DDR5 96GB (2×48GB) 6000MHz CL28

Archiviazione: Crucial T710 4TB NVMe M.2 PCIe 5.0 Gen5

GPU (Gaming): ASUS ROG Astral GeForce RTX 5080 16GB

GPU (AI): Intel Arc Pro B70 32GB (in attesa di rilascio)

PSU: Corsair RM1200x

Case: Thermaltake Tower 900

Configurazione Zima (Il centro sempre attivo)

Lo Zima funziona 24/7 e gestisce tutto ciò che è leggero — compiti da assistente domestico, flussi video delle telecamere e query AI di base usando il livello gratuito Groq via cloud.

Periferiche collegate direttamente allo Zima:

Monitor touchscreen Pisichen 22" via HDMI → adattatore miniDP + un cavo USB-C per input touch

Altoparlanti Edifier G1000 II tramite scheda audio esterna USB-A a 3,5mm

Microfono DAMAO DGM20S via USB-A

Archiviazione:

Seagate IronWolf Pro 20TB — disco NAS "buco nero"

Seagate IronWolf Pro 1TB — disco NAS principale

Rete:

Zima collegato al router tramite Ethernet

Secondo cavo Ethernet che collega direttamente lo Zima al PC per trasferimenti locali veloci

Un ambiente completo di automazione domestica con un chiosco touchscreen alimentato da ZimaBoard, altoparlanti professionali e una scrivania minimalista per il monitoraggio 24/7.

La parte intelligente: Wake-on-LAN

Ecco la magia — quando qualcuno fa una domanda troppo complessa per Gemini, lo Zima invia un pacchetto Wake-on-LAN per risvegliare il PC principale dalla modalità ibernazione. Una volta acceso, si collega a un LLM locale da 70 miliardi di parametri che gira sulla Intel Arc Pro B70. Dopo aver completato il compito, il PC torna in standby.

Il risultato: un assistente domestico sempre reattivo, ma il computer principale si attiva solo quando c'è un vero lavoro pesante da fare. Le bollette restano ragionevoli e ho comunque accesso a un modello locale davvero potente quando ne ho bisogno.

Un enorme ringraziamento a Claude Code e Perplexity — onestamente, senza il loro aiuto non sarei mai riuscito a mettere insieme questo progetto da solo. Sono stati preziosissimi durante tutto il processo.

Spero che queste informazioni aiutino chiunque sia abbastanza folle da intraprendere un progetto simile — sentitevi liberi di condividerle dove volete!

Centro Campagna Zima

Altro da leggere

Cos'è un server AI locale?
Apr 15, 2026Tutorials & Setup

Cos'è un server AI locale?

Smetti di pagare canoni mensili e di rischiare perdite di dati con i bot cloud. Costruisci un server AI locale privato per eseguire modelli...

Get More Builds Like This

Stay in the Loop

Get updates from Zima - new products, exclusive deals, and real builds from the community.

Stay in the Loop preferences

We respect your inbox. Unsubscribe anytime.