Skip to content

Kiosk Base Setup RPi

Ariel Shumacher edited this page Mar 10, 2026 · 7 revisions

This page covers setting up a Raspberry Pi as a museum kiosk. Unlike the Kiosk Base Setup (which targets Linux Mint desktops), these scripts are designed for Raspberry Pi OS and are meant to be copied into each exhibit's own repository as the project's setup.sh.

Note: if you need help installing the rpi OS onto your rpi see this video

There are two variants depending on your needs:

GUI Mode Terminal Mode
Script setup_gui_rpi.sh setup_terminal_rpi.sh
Desktop environment Yes (Xorg/LXDE) No (console only)
Remote access AnyDesk (graphical) Tailscale SSH
App autostart .desktop file in ~/.config/autostart/ tmux session launched from .bashrc
Boot mode Desktop with autologin (raspi-config B4) Console with autologin (raspi-config B2)
Best for Exhibits that need a GUI (browser, desktop app) Headless exhibits, VLC via DRM, better performance

Which Variant Should I Choose?

Use the GUI variant if:

  • Your exhibit runs a browser-based UI or needs a desktop application
  • You need graphical remote access (AnyDesk lets you see and control the screen)

Use the terminal variant if:

  • Your exhibit is headless or only uses VLC/terminal apps
  • You want better performance (no desktop overhead)
  • You want SSH access from anywhere via Tailscale

If you run into issues with AnyDesk, RustDesk is an open-source alternative. However, the museum standard is AnyDesk — talk to the team before switching.

Assumptions

  • Raspberry Pi OS (Bookworm or later) is already installed and the Pi is connected to the internet.
  • The script will be copied into your project repo and renamed to setup.sh. You should edit the apt-get install section to add any project-specific packages your exhibit needs (e.g. libgpiod2, i2c-tools, ffmpeg).
  • Your project has a run.sh at the repo root that defines how the exhibit starts.
  • Your project optionally has a requirements.txt for Python dependencies.
  • You are running the script as a regular user with sudo access (not as root).
  • For the GUI variant: AnyDesk requires Xorg (not Wayland), which is why the GUI variant forces X11 and boots to a desktop.
  • For the terminal variant: Tailscale provides SSH access from anywhere without port forwarding. It will prompt for browser-based authentication on first run.

How to Use

1. Copy the Script into Your Project

Pick the variant that matches your exhibit's needs and copy it into your project repo as setup.sh:

# Example: using the terminal variant
cp setup_terminal_rpi.sh ~/my-exhibit-repo/setup.sh

2. Edit the apt Packages

Open setup.sh and add any system packages your exhibit needs to the apt-get install line:

sudo apt-get install -y \
    python3 \
    python3-venv \
    python3-pip \
    tmux \
    vlc \
    your-package-here

3. Create a run.sh

Your project needs a run.sh at the repo root. This is what gets launched automatically on boot. For example:

#!/usr/bin/env bash
cd "$(dirname "${BASH_SOURCE[0]}")"
source .venv/bin/activate
python3 main.py

see this repo for a concrete example.

4. Clone and Run on the Pi

On a fresh Raspberry Pi OS install:

git clone <your-repo-url>
cd <repo-folder>
chmod +x setup.sh && ./setup.sh

For the GUI variant, you'll be prompted for an AnyDesk password. The AnyDesk ID will be printed at the end — write it down.

For the terminal variant, Tailscale will prompt you to authenticate via a URL in the terminal.

5. Reboot

sudo reboot

After rebooting, the Pi will auto-login and launch your run.sh.

GUI Variant — What Each Step Does

The GUI script (setup_gui_rpi.sh) runs 4 steps:

1. System Packages

Installs Python, tmux, and VLC. Edit this section to add your project-specific packages.

2. AnyDesk

Installs AnyDesk from the official Debian repo and enables the service. Sets an unattended-access password so you can connect remotely without anyone at the Pi. At the end, prints the AnyDesk ID you'll need to connect.

AnyDesk requires Xorg (not Wayland), which is why the GUI variant forces X11. Works on all Pi models.

3. Python Virtual Environment

Creates a .venv inside the repo and installs dependencies from requirements.txt if it exists.

4. GUI Auto-Login and Autostart

  • Forces X11 (Xorg) instead of Wayland. Raspberry Pi OS Bookworm defaults to Wayland (labwc), but AnyDesk requires X11 for incoming connections. This is done via raspi-config nonint do_wayland W1.
  • Sets the Pi to boot into the desktop with auto-login (raspi-config B4).
  • Creates a .desktop autostart entry that launches run.sh in an lxterminal window when the desktop session starts.

Terminal Variant — What Each Step Does

The terminal script (setup_terminal_rpi.sh) runs 4 steps:

1. System Packages

Same as GUI — installs Python, tmux, and VLC. Edit this section to add your project-specific packages.

2. Tailscale

Installs Tailscale for remote SSH access. Tailscale creates a private network so you can SSH into the Pi from anywhere without opening ports or configuring firewalls. On first run it will ask you to authenticate via a URL.

3. Python Virtual Environment

Same as GUI — creates a .venv and installs from requirements.txt.

4. Console Auto-Login and tmux Autostart

  • Sets the Pi to boot to console with auto-login (raspi-config B2) — no desktop environment, so VLC renders directly via DRM for better performance.
  • Appends a block to .bashrc that starts a tmux session running run.sh on login.
  • You can SSH in and tmux attach -t kiosk to see the running app, or Ctrl+B then D to detach without stopping it.

Troubleshooting

"Permission denied" when running setup.sh

  • Run chmod +x setup.sh first.

AnyDesk says "not available yet" for the ID

  • The AnyDesk service may need a moment to start. Run anydesk --get-id after a few seconds.

Tailscale authentication prompt

  • This is expected on first run. Open the URL it shows in a browser and log in to your Tailscale account.

VLC is choppy / high CPU on Pi 3B

  • Make sure your run.sh uses cvlc --codec=mmal <file> for hardware decoding.

App doesn't start after reboot (terminal variant)

  • Check that the kiosk autostart block is in ~/.bashrc: grep "kiosk autostart" ~/.bashrc
  • Check that run.sh exists and is executable.

App doesn't start after reboot (GUI variant)

  • Check that ~/.config/autostart/kiosk.desktop exists.
  • Make sure the Pi is set to boot to desktop: sudo raspi-config nonint get_boot_cli should return 1.

See Also

Clone this wiki locally