PiPiece Setup Guide
This guide explains how to set up a Raspberry Pi for PiPiece using the automation in setup-pi.sh and the scripts in the setup/ directory.
It supports two installation modes:
- Remote mode: run the setup from another machine over SSH
- Local mode: SSH into the Pi first, then run the setup scripts directly on the Pi
- Automated local mode (recommended): a single command downloads the latest release and runs
setup/install.shwhich auto-detects hardware, configures the display, installs everything, and optionally reboots
It also supports two ways to get the PiPiece code onto the Pi:
- Release tarball (recommended for production): download a pre-built release that includes the compiled Vue UI. No
gitor build tooling required on the Pi. - Clone from source: clone the repository and build locally. Required for development.
Overview
The setup flow uses SSH to run shell scripts on the Raspberry Pi remotely. The main script is:
./setup-pi.sh [-u username] <hostname> <command>Example:
./setup-pi.sh pipiece newExample with a custom SSH username:
./setup-pi.sh -u john pipiece.local newLocal example:
./setup-pi.sh pipiece localImportant behavior:
- The Raspberry Pi hostname is expected to be reachable as
<hostname>.local - The script connects as user
piby default - Use
-u <username>to connect as a different SSH user - The script uses the local SSH key
~/.ssh/id_rsa - Each selected script in
setup/is piped over SSH and executed on the Raspberry Pi - The
localcommand runs the same setup sequence directly on the Pi without SSH - The current argument parser still expects a first argument before
local, so use./setup-pi.sh pipiece localrather than./setup-pi.sh local
Before You Start
Make sure all of these are true before running setup:
- Raspberry Pi OS is installed on the microSD card.
- The Pi is on your network and reachable with the hostname
pipiece.localor your chosen hostname. - SSH is enabled on the Pi.
- Your local machine has a working private key at
~/.ssh/id_rsa. - The matching public key is already installed for the remote user you plan to connect as.
- The PiPiece repository exists on the Raspberry Pi at
~/src/pipiece-ui.
The last item matters because setup/server.sh does not clone the repository. It expects the code to already be present.
Quick Start
Run the full default setup sequence:
cd ~/src/rpi/pipiece-ui
./setup-pi.sh pipiece newIf your remote SSH user is not pi, use:
./setup-pi.sh -u <username> pipiece.local newRun the same sequence locally after SSHing into the Pi:
cd ~/src/pipiece
./setup-pi.sh pipiece localThe new command runs these scripts in order:
updatehyperpixelnodetoolssshserverui
Command Reference
List available setup commands:
./setup-pi.sh pipieceList commands for a custom SSH user:
./setup-pi.sh -u <username> pipiece.localRun a single step manually:
./setup-pi.sh pipiece update
./setup-pi.sh pipiece node
./setup-pi.sh pipiece serverRemote examples with a custom SSH user:
./setup-pi.sh -u <username> pipiece.local update
./setup-pi.sh -u <username> pipiece.local serverWhen you are already SSHed into the Pi, individual scripts can be run directly:
bash ./setup/update.sh
bash ./setup/node.sh
bash ./setup/server.shUseful optional scripts:
doctorchecks whether the Pi matches the expected configurationraspienables camera support and screen blanking settings usingraspi-configrebootreboots the Raspberry Pino-uiremoves the Labwc Chromium autostart entry
Automated Local Setup (setup/install.sh)
The install.sh script is an all-in-one orchestrator designed to run directly on the Pi. It replaces the need to use setup-pi.sh from a remote machine.
cd ~/pipiece-ui && bash setup/install.shWhat it does:
- Detects hardware — runs
doctor.sh --emitto identify the attached display and write a machine-readable state file (setup-state.env) - Updates system packages — runs
update.sh - Configures the display — auto-selects the correct display script based on detection:
- HyperPixel4 →
hyperpixel.sh - TouchDisplay 1 →
touchdisplay1.sh - TouchDisplay 2 →
touchdisplay2.sh - PiTFT 2.4" →
pitft24.sh - No screen detected → warns and continues
- HyperPixel4 →
- Installs Node.js and tools — runs
node.shandtools.sh - Hardens SSH — runs
ssh.sh - Starts the server — runs
server.sh - Configures the kiosk — runs
ui.sh - Optional packages — prompts for astrometry.net and LiteRT/ML inference
- Validates — runs
doctor.shto show final system state - Reboot prompt — offers to reboot to apply display changes
Flags:
--yes/-y— non-interactive mode: skips optional package prompts (declines them) and auto-reboots
The script tracks success/failure of each step and prints a summary at the end.
What Each Setup Step Does
1. update
Script: setup/update.sh
This step updates the APT package list and upgrades installed packages:
sudo apt update
sudo apt upgrade -yWhy it matters:
- Pulls in current package metadata
- Installs the latest available security and system updates
- Reduces avoidable issues later in the setup
2. hyperpixel
Script: setup/hyperpixel.sh
This step configures the HyperPixel4 display and display layout.
It does three things:
- Adds the HyperPixel4 overlay to
/boot/firmware/config.txt - Adds rotation and touchscreen parameters to
/boot/firmware/config.txt - Writes a
kanshidisplay profile to~/.config/kanshi/config
Why it matters:
- Enables the HyperPixel hardware overlay
- Rotates the display to the orientation expected by PiPiece
- Ensures Wayland display layout is correct
A reboot is required after this step if the display overlay or rotation settings were newly added.
3. node
Script: setup/node.sh
This step installs Node.js, updates npm, installs PM2 globally, and configures PM2 to start at boot.
It uses the NodeSource setup script for Node 24.x, then installs:
nodejsbuild-essentialpm2
It also runs:
pm2 startup systemd -u pi --hp /home/piWhy it matters:
- The server requires Node.js
- PM2 keeps the server running and restores it after reboot
4. tools
Script: setup/tools.sh
This installs supporting packages:
xdotoolentrwtypeimagemagick
Why it matters:
imagemagickis used by image-processing utilities in the repowtypeandxdotoolsupport UI and automation workflowsentris useful for file watching and utility scripting
5. ssh
Script: setup/ssh.sh
This disables password authentication in /etc/ssh/sshd_config by changing:
PasswordAuthentication noWhy it matters:
- Moves the Pi toward key-only SSH access
- Reduces attack surface compared to password logins
Do not run this step until you have confirmed that SSH public key authentication works.
6. server
Script: setup/server.sh
This step prepares directories and starts the PiPiece Express server with PM2.
It creates:
~/photos~/pipiece-ui/config~/src
Then it expects the repo to already exist at:
~/src/pipieceInside ~/src/pipiece-ui/server, it runs:
npm ci
pm2 start bin/www.js --name "pipiece-ui"
pm2 restart pipiece-ui --watch
pm2 saveWhy it matters:
- Installs server dependencies cleanly from the lockfile
- Starts the Express app under PM2
- Saves the PM2 process list for reboot persistence
7. ui
Script: setup/ui.sh
This appends a Chromium kiosk launch command to:
~/.config/labwc/autostartThe configured browser target is:
http://localhostWhy it matters:
- Launches Chromium automatically in kiosk mode on login
- Opens the local PiPiece UI without browser chrome
- Forces dark-mode related Chromium flags used by this project
software-update
Script: setup/software-update.sh
This script checks for and applies PiPiece software updates from GitLab releases:
- Queries the GitLab Releases API for the latest version
- Compares against the currently installed version
- Downloads the release tarball
- Backs up the current installation to
~/pipiece-ui-backup/ - Extracts and rsyncs updated files (preserving config, photos, node_modules)
- Runs
npm installfor server dependencies - Restarts the PM2 service
Use --check-only to check for updates without applying them.
Recommended Full Setup Sequence
Step 1. Prepare the Raspberry Pi OS image
Use Raspberry Pi Imager and make sure you configure:
- Hostname:
pipiece - SSH enabled
- Public key authentication enabled
- Your SSH public key installed for the user you will connect as
- Wi-Fi credentials if needed
If you need a walk-through, see rpi-imager.md.
Step 2. Boot the Pi and verify SSH access
From your local machine:
ssh -i ~/.ssh/id_rsa pi@pipiece.localIf you use a different account on the Pi:
ssh -i ~/.ssh/id_rsa <username>@pipiece.localIf this fails, do not continue until SSH access is working.
Step 3. Get the PiPiece code onto the Raspberry Pi
Option A — One-command install from release tarball (recommended)
This is the fastest way to get a fully configured Pi. A single command downloads the latest release, extracts it, and runs the automated setup which detects your display, installs all required software, and configures the kiosk.
SSH into the Pi and run:
TAG=$(curl -s "https://gitlab.com/api/v4/projects/79538131/releases" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['tag_name'])") && curl -L "https://gitlab.com/api/v4/projects/79538131/packages/generic/pipiece/${TAG}/pipiece-${TAG}.tar.gz" -o pipiece-${TAG}.tar.gz && tar -xzf pipiece-${TAG}.tar.gz -C ~ && cd ~/pipiece-ui && bash setup/install.shThis will:
- Fetch the latest release tag from the GitLab API
- Download the tarball
- Extract it to
~/pipiece-ui/ - Run
setup/install.shwhich automatically:- Detects the attached display (HyperPixel4, TouchDisplay 1/2, PiTFT 2.4")
- Updates system packages
- Configures the detected display
- Installs Node.js, PM2, and system tools
- Hardens SSH (disables password auth)
- Starts the Express server under PM2
- Configures Chromium kiosk autostart
- Prompts to install optional packages (astrometry.net, LiteRT/ML)
- Validates the installation with doctor.sh
- Offers to reboot
For non-interactive installs (e.g. headless/automated), add --yes to skip all prompts, decline optional packages, and auto-reboot:
TAG=$(curl -s "https://gitlab.com/api/v4/projects/79538131/releases" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['tag_name'])") && curl -L "https://gitlab.com/api/v4/projects/79538131/packages/generic/pipiece/${TAG}/pipiece-${TAG}.tar.gz" -o pipiece-${TAG}.tar.gz && tar -xzf pipiece-${TAG}.tar.gz -C ~ && cd ~/pipiece-ui && bash setup/install.sh --yesAfter this, skip to Step 7 to validate the installation.
Option B — Download tarball only (manual setup)
If you prefer to run setup steps individually:
TAG=$(curl -s "https://gitlab.com/api/v4/projects/79538131/releases" | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['tag_name'])") && curl -L "https://gitlab.com/api/v4/projects/79538131/packages/generic/pipiece/${TAG}/pipiece-${TAG}.tar.gz" -o pipiece-${TAG}.tar.gz && tar -xzf pipiece-${TAG}.tar.gz -C ~Then continue with Step 4 to run the remote or local setup.
Option C — Clone from source
Use this if you want to develop or build from source.
On the Pi:
mkdir -p ~/src
git clone https://gitlab.com/johnwebbcole/pipiece-ui.git ~/src/pipieceThis is required before setup/server.sh can succeed.
Step 4. Run the automated setup
From your local machine in the repo root:
./setup-pi.sh pipiece newThis runs the full setup sequence remotely over SSH.
If your Raspberry Pi account is not pi:
./setup-pi.sh -u <username> pipiece.local newStep 4a. Run the automated setup locally from an SSH session on the Pi
If you are already logged into the Pi over SSH and want to run the same setup directly on the device:
cd ~/src/pipiece
./setup-pi.sh pipiece localThis runs the same sequence as new, but it executes each script locally instead of piping it over SSH.
Use this mode when:
.localname resolution is unreliable from your workstation- You want to watch output directly on the Pi
- The remote SSH wrapper is getting in the way of debugging
Important note:
- The current script still requires a placeholder first argument before
local - In practice, use
pipieceas that first argument even though local mode does not use it
Step 5. Apply Raspberry Pi configuration if needed
The new sequence does not run setup/raspi.sh. If camera support or screen blanking behavior is not correct, run:
./setup-pi.sh pipiece raspiThis script enables:
- Camera support
- Screen blanking setting
Step 6. Reboot the Raspberry Pi
Some changes require a reboot, especially HyperPixel configuration.
Run:
./setup-pi.sh pipiece rebootOr reboot manually over SSH.
Step 7. Validate the installation
Run the doctor script:
./setup-pi.sh pipiece doctorThis checks:
- Raspberry Pi configuration values
- HyperPixel overlay and rotation config
- SSH password authentication state
kanshidisplay profilenode,pm2,xdotool,entr,wtype, andconvert- Presence of expected directories
- Labwc Chromium autostart entry
- Whether the PM2 server process is running
Manual Verification Checklist
After setup and reboot, confirm the following:
ssh pi@pipiece.localworks with your SSH key.pm2 liston the Pi shows thepipiece-uiprocess.curl http://localhost/api/system/infoon the Pi returns JSON.- Chromium launches automatically in kiosk mode if the UI environment is enabled.
- The HyperPixel display is rotated correctly and touch input matches the screen orientation.
Troubleshooting
SSH cannot connect to pipiece.local
Checks:
- Confirm the Pi is powered on and on the same network.
- Confirm the hostname was set to
pipieceduring Raspberry Pi Imager setup. - Try
ping pipiece.local. - If mDNS is unreliable on your network, connect by IP address instead.
The script itself assumes .local name resolution. If that does not work in your environment, either fix mDNS or update the script.
Workaround:
- SSH to the Pi by IP address, then run
./setup-pi.sh pipiece localfrom~/src/pipiece-ui
SSH key authentication fails
Checks:
- Confirm your private key exists at
~/.ssh/id_rsaon the local machine. - Confirm the matching public key is in
~/.ssh/authorized_keysfor the user you are connecting as on the Raspberry Pi. - Test manually:
ssh -i ~/.ssh/id_rsa pi@pipiece.localIf you use a different user, test with that account name and pass the same username to setup-pi.sh with -u.
Do not run setup/ssh.sh until this works.
setup/server.sh says PiPiece is not found
Cause:
- The repository is missing at
~/src/pipiece-uion the Raspberry Pi.
Fix:
- Clone the repo manually on the Pi before rerunning the
serverstep.
./setup-pi.sh local only shows help
Cause:
- The script parses the first positional argument as the hostname, so
localby itself is treated as a hostname instead of a command.
Fix:
- Run local setup as:
./setup-pi.sh pipiece local- Or run individual scripts directly:
bash ./setup/update.sh
bash ./setup/node.sh
bash ./setup/server.shLocal setup fails because the repo path is wrong
Checks:
- Confirm you are in
~/src/pipiece-ui - Confirm the
setup/directory exists under the current working directory
The local runner uses relative paths like ./setup/node.sh, so it must be launched from the repository root.
sudo commands fail during remote setup
Cause:
- The setup scripts run non-interactively over SSH and may fail if
sudoexpects an interactive password prompt.
Fix:
- Log in manually and run the failing step directly on the Pi.
- Or configure your sudo policy appropriately for the setup workflow.
HyperPixel display does not rotate correctly
Checks:
- Verify both lines exist in
/boot/firmware/config.txt:
dtoverlay=vc4-kms-dpi-hyperpixel4
dtparam=rotate=90,touchscreen-swapped-x-y,touchscreen-inverted-y- Verify
~/.config/kanshi/configcontains theDPI-1profile. - Reboot after making changes.
Chromium does not start automatically
Checks:
- Confirm
~/.config/labwc/autostartexists. - Confirm it contains the Chromium kiosk command added by
setup/ui.sh. - If you want to remove kiosk startup, run:
./setup-pi.sh pipiece no-uiPM2 server is not running after reboot
Checks:
- Run
pm2 list - Run
pm2 save - Re-run the PM2 startup command if necessary:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u pi --hp /home/pi- Then restart the server setup step:
./setup-pi.sh pipiece serverCamera features do not work
Checks:
- Run
./setup-pi.sh pipiece raspi - Reboot the Pi
- Verify camera availability with Raspberry Pi camera tools installed on the device
Suggested Workflow for Re-runs
If you only need to fix one part of the system, rerun just that step instead of the whole new sequence.
Examples:
./setup-pi.sh pipiece hyperpixel
./setup-pi.sh pipiece ssh
./setup-pi.sh pipiece server
./setup-pi.sh pipiece ui
./setup-pi.sh pipiece doctorThis is usually the safer approach once the initial installation is complete.