[Unit] Description=BetterFrame Kiosk (cage + betterframe-kiosk) Documentation=https://github.com/BetterCorp/BetterFrame After=systemd-user-sessions.service plymouth-quit-wait.service network-online.target seatd.service Wants=network-online.target Conflicts=getty@tty1.service After=getty@tty1.service # After 10 fast restarts in 60s, back off so a broken binary doesn't burn CPU. StartLimitIntervalSec=60 StartLimitBurst=10 [Service] Type=simple User=bfkiosk Group=bfkiosk SupplementaryGroups=video render input audio PAMName=cage TTYPath=/dev/tty1 TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes StandardInput=tty-fail StandardOutput=journal StandardError=journal UtmpIdentifier=tty1 UtmpMode=user WorkingDirectory=/home/bfkiosk EnvironmentFile=-/etc/default/betterframe-kiosk Environment=XDG_SESSION_TYPE=wayland Environment=XDG_SESSION_CLASS=user Environment=GST_DEBUG=1 Environment=BETTERFRAME_SERVER=http://localhost # Let the unprivileged kiosk process control the Pi fan PWM sysfs files. ExecStartPre=+/bin/sh -c 'for d in /sys/class/hwmon/hwmon*; do [ -e "$d/pwm1" ] || continue; chgrp bfkiosk "$d/pwm1" "$d/pwm1_enable" 2>/dev/null || true; chmod g+w "$d/pwm1" "$d/pwm1_enable" 2>/dev/null || true; done' ExecStartPre=+/usr/local/sbin/betterframe-firmware-rollback.sh ExecStart=/usr/bin/cage -s -- /opt/betterframe/kiosk/betterframe-kiosk Restart=always RestartSec=2 # WebKitGTK uses bubblewrap for its web-content sandbox. bwrap aborts with # "Unexpected capabilities but not setuid" when launched from a process that # still carries CAP_* bits. Strip caps + lock NoNewPrivileges so WebKit's # sandbox can initialise cleanly. Without this WebKit cells crash on load. CapabilityBoundingSet= AmbientCapabilities= NoNewPrivileges=yes # Fallback if the above isn't enough on a given distro (disables WebKit sandbox): #Environment=WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1 [Install] WantedBy=multi-user.target