Skip to content

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

Overview

The setup flow uses SSH to run shell scripts on the Raspberry Pi remotely. The main script is:

bash
./setup-pi.sh [-u username] <hostname> <command>

Example:

bash
./setup-pi.sh pipiece new

Example with a custom SSH username:

bash
./setup-pi.sh -u john pipiece.local new

Local example:

bash
./setup-pi.sh pipiece local

Important behavior:

  • The Raspberry Pi hostname is expected to be reachable as <hostname>.local
  • The script connects as user pi by 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 local command 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 local rather than ./setup-pi.sh local

Before You Start

Make sure all of these are true before running setup:

  1. Raspberry Pi OS is installed on the microSD card.
  2. The Pi is on your network and reachable with the hostname pipiece.local or your chosen hostname.
  3. SSH is enabled on the Pi.
  4. Your local machine has a working private key at ~/.ssh/id_rsa.
  5. The matching public key is already installed for the remote user you plan to connect as.
  6. The PiPiece repository exists on the Raspberry Pi at ~/src/pipiece.

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:

bash
cd ~/src/rpi/pipiece-ui
./setup-pi.sh pipiece new

If your remote SSH user is not pi, use:

bash
./setup-pi.sh -u <username> pipiece.local new

Run the same sequence locally after SSHing into the Pi:

bash
cd ~/src/pipiece
./setup-pi.sh pipiece local

The new command runs these scripts in order:

  1. update
  2. hyperpixel
  3. node
  4. tools
  5. ssh
  6. server
  7. ui

Command Reference

List available setup commands:

bash
./setup-pi.sh pipiece

List commands for a custom SSH user:

bash
./setup-pi.sh -u <username> pipiece.local

Run a single step manually:

bash
./setup-pi.sh pipiece update
./setup-pi.sh pipiece node
./setup-pi.sh pipiece server

Remote examples with a custom SSH user:

bash
./setup-pi.sh -u <username> pipiece.local update
./setup-pi.sh -u <username> pipiece.local server

When you are already SSHed into the Pi, individual scripts can be run directly:

bash
bash ./setup/update.sh
bash ./setup/node.sh
bash ./setup/server.sh

Useful optional scripts:

  • doctor checks whether the Pi matches the expected configuration
  • raspi enables camera support and screen blanking settings using raspi-config
  • reboot reboots the Raspberry Pi
  • no-ui removes the Labwc Chromium autostart entry

What Each Setup Step Does

1. update

Script: setup/update.sh

This step updates the APT package list and upgrades installed packages:

bash
sudo apt update
sudo apt upgrade -y

Why 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:

  1. Adds the HyperPixel4 overlay to /boot/firmware/config.txt
  2. Adds rotation and touchscreen parameters to /boot/firmware/config.txt
  3. Writes a kanshi display 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:

  • nodejs
  • build-essential
  • pm2

It also runs:

bash
pm2 startup systemd -u pi --hp /home/pi

Why 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:

  • xdotool
  • entr
  • wtype
  • imagemagick

Why it matters:

  • imagemagick is used by image-processing utilities in the repo
  • wtype and xdotool support UI and automation workflows
  • entr is useful for file watching and utility scripting

5. ssh

Script: setup/ssh.sh

This disables password authentication in /etc/ssh/sshd_config by changing:

text
PasswordAuthentication no

Why 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/config
  • ~/src

Then it expects the repo to already exist at:

bash
~/src/pipiece

Inside ~/src/pipiece/server, it runs:

bash
npm ci
pm2 start bin/www --name "expressjs"
pm2 restart expressjs --watch
pm2 save

Why 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:

bash
~/.config/labwc/autostart

The configured browser target is:

text
http://localhost:3000

Why 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

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:

bash
ssh -i ~/.ssh/id_rsa pi@pipiece.local

If you use a different account on the Pi:

bash
ssh -i ~/.ssh/id_rsa <username>@pipiece.local

If this fails, do not continue until SSH access is working.

Step 3. Clone the repository on the Raspberry Pi

On the Pi:

bash
mkdir -p ~/src
git clone <your-repo-url> ~/src/pipiece

This is required before setup/server.sh can succeed.

Step 4. Run the automated setup

From your local machine in the repo root:

bash
./setup-pi.sh pipiece new

This runs the full setup sequence remotely over SSH.

If your Raspberry Pi account is not pi:

bash
./setup-pi.sh -u <username> pipiece.local new

Step 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:

bash
cd ~/src/pipiece
./setup-pi.sh pipiece local

This runs the same sequence as new, but it executes each script locally instead of piping it over SSH.

Use this mode when:

  • .local name 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 pipiece as 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:

bash
./setup-pi.sh pipiece raspi

This script enables:

  • Camera support
  • Screen blanking setting

Step 6. Reboot the Raspberry Pi

Some changes require a reboot, especially HyperPixel configuration.

Run:

bash
./setup-pi.sh pipiece reboot

Or reboot manually over SSH.

Step 7. Validate the installation

Run the doctor script:

bash
./setup-pi.sh pipiece doctor

This checks:

  • Raspberry Pi configuration values
  • HyperPixel overlay and rotation config
  • SSH password authentication state
  • kanshi display profile
  • node, pm2, xdotool, entr, wtype, and convert
  • 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:

  1. ssh pi@pipiece.local works with your SSH key.
  2. pm2 list on the Pi shows the expressjs process.
  3. curl http://localhost:3000/api/system/info on the Pi returns JSON.
  4. Chromium launches automatically in kiosk mode if the UI environment is enabled.
  5. 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 pipiece during 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 local from ~/src/pipiece

SSH key authentication fails

Checks:

  • Confirm your private key exists at ~/.ssh/id_rsa on the local machine.
  • Confirm the matching public key is in ~/.ssh/authorized_keys for the user you are connecting as on the Raspberry Pi.
  • Test manually:
bash
ssh -i ~/.ssh/id_rsa pi@pipiece.local

If 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 on the Raspberry Pi.

Fix:

  • Clone the repo manually on the Pi before rerunning the server step.

./setup-pi.sh local only shows help

Cause:

  • The script parses the first positional argument as the hostname, so local by itself is treated as a hostname instead of a command.

Fix:

  • Run local setup as:
bash
./setup-pi.sh pipiece local
  • Or run individual scripts directly:
bash
bash ./setup/update.sh
bash ./setup/node.sh
bash ./setup/server.sh

Local setup fails because the repo path is wrong

Checks:

  • Confirm you are in ~/src/pipiece
  • 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 sudo expects 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:
text
dtoverlay=vc4-kms-dpi-hyperpixel4
dtparam=rotate=90,touchscreen-swapped-x-y,touchscreen-inverted-y
  • Verify ~/.config/kanshi/config contains the DPI-1 profile.
  • Reboot after making changes.

Chromium does not start automatically

Checks:

  • Confirm ~/.config/labwc/autostart exists.
  • Confirm it contains the Chromium kiosk command added by setup/ui.sh.
  • If you want to remove kiosk startup, run:
bash
./setup-pi.sh pipiece no-ui

PM2 server is not running after reboot

Checks:

  • Run pm2 list
  • Run pm2 save
  • Re-run the PM2 startup command if necessary:
bash
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:
bash
./setup-pi.sh pipiece server

Camera 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:

bash
./setup-pi.sh pipiece hyperpixel
./setup-pi.sh pipiece ssh
./setup-pi.sh pipiece server
./setup-pi.sh pipiece ui
./setup-pi.sh pipiece doctor

This is usually the safer approach once the initial installation is complete.