A handy installation script that makes installing Klipper (and more) a breeze!
KIAUH is a script that assists you in installing Klipper on a Linux operating
system that has
already been flashed to your Raspberry Pi's (or other SBC's) SD card. As a
result, you must ensure
that you have a functional Linux system on hand.
Raspberry Pi OS Lite (either 32bit or 64bit) is a recommended Linux image
if you are using a Raspberry Pi.
The official Raspberry Pi Imager
is the simplest way to flash an image like this to an SD card.
- Once you have downloaded, installed and launched the Raspberry Pi Imager,
select
Choose OS -> Raspberry Pi OS (other): \
- Then select
Raspberry Pi OS Lite (32bit)(or 64bit if you want to use that instead):
-
Back in the Raspberry Pi Imager's main menu, select the corresponding SD card to which you want to flash the image.
-
Make sure to go into the Advanced Option (the cog icon in the lower left corner of the main menu) and enable SSH and configure Wi-Fi.
-
If you need more help for using the Raspberry Pi Imager, please visit the official documentation.
If you are deploying KIAUH on a phone or tablet that ships with postmarketOS, make sure the base image is prepped through pmbootstrap and that you can reach the device over SSH. The following checklist helps align the mobile environment with KIAUH's init-system and Wayland tooling:
- Flash a recent
postmarketos-baserootfs and enable SSH or USB networking (pmbootstrap install --ssh). - Install one of the touch UIs (
postmarketos-ui-phoshorpostmarketos-ui-plasma-mobile) so the Wayland presets have an available session. - Sxmo users should keep
sxmo-utilsinstalled—the helper mirrors its wlroots environment exports when generating the KlipperScreen launcher. - Ensure the main user belongs to the
video,input, andplugdevgroups so KlipperScreen inherits display and input permissions. - Start the seat management service after the first boot (
rc-update add seatd default && rc-service seatd start) because the KlipperScreen Wayland wrapper relies on it. - Keep the vendor-specific DRM or DSI panel drivers enabled; the display preset generator reads them to pre-seed orientation hints.
With these prerequisites met, the init-system helper will link services into OpenRC automatically and the launcher presets can bind to the device's Wayland shell without manual tweaks.
🛠️ Kernel configuration checklist – When you build or select a custom postmarketOS kernel, make sure the drivers required by Klipper, Moonraker, KlipperScreen, crowsnest, and WireGuard are enabled. See docs/kernel_requirements.md for a per-component breakdown of the key
CONFIG_options and module names to verify before flashing.
These steps only apply if you are actually using a Raspberry Pi. In case you want to use a different SBC (like an Orange Pi or any other Pi derivates), please look up on how to get an appropriate Linux image flashed to the SD card before proceeding further (usually done with Balena Etcher in those cases). Also make sure that KIAUH will be able to run and operate on the Linux Distribution you are going to flash. You likely will have the most success with distributions based on Debian 11 Bullseye. Read the notes further down below in this document.
📢 Disclaimer: Usage of this script happens at your own risk!
- Step 1:
To download this script, it is necessary to have git installed. If you don't have git already installed, or if you are unsure, run the command that matches your distribution:
# Debian, Ubuntu, Raspberry Pi OS, ...
sudo apt-get update && sudo apt-get install git -y
# Alpine Linux / postmarketOS
sudo apk update && sudo apk add gitℹ️ Alpine/postmarketOS cross-toolchains – KIAUH now resolves the cross-compilation packages by their native
apknames:binutils-arm-none-eabi,gcc-arm-none-eabi,binutils-avr, andgcc-avr. This avoids the "package not found" errors reported during early postmarketOS installs that still referenced the Debian naming scheme.
- Step 2:
Once git is installed, use the following command to download KIAUH into your home-directory:
cd ~ && git clone https://github.com/postmarketOS-community/postmarketos-kiauh.gitℹ️ Self-update origin rewriting –
kiauh.shnow ensures that the script'soriginremote points to the postmarketOS community fork before running a self-update. If you maintain a personal fork, setKIAUH_REPO_URL=<your-remote-url>in the environment before launching KIAUH so the helper keeps your remote intact.
- Step 3:
Finally, start KIAUH by running the next command:
./kiauh/kiauh.sh- Step 4:
You should now find yourself in the main menu of KIAUH. You will see several actions to choose from depending on what you want to do. To choose an action, simply type the corresponding number into the "Perform action" prompt and confirm by hitting ENTER.
✅ Case-insensitive prompts – Every yes/no dialog now accepts upper- or lower-case responses alongside numeric toggles like
1/0andon/off, so you can answer from touch keyboards and remote shells without triggering the invalid choice handler.
- Loading spinners now pause automatically whenever
sudoneeds your password or the package manager prints interactive output, so update checks no longer obscure the prompt behind the animation. - KIAUH now offers to cache your sudo credentials for the current session, refreshing the timestamp behind the scenes and clearing it when you exit so multi-step updates only prompt once; if the host only ships a minimal sudo shim (such as
doas-sudo-shim) that lacks the required flags, the helper now skips caching automatically without surfacing unsupported option errors. - Menu loading indicators now shut down safely even if they were never started, eliminating the
AttributeErrorthat previously appeared when a menu tried to stop a missing spinner. - Warning prompts across installers and extensions now route through the shared
Logger.print_warnhelper so the CLI surfaces consistent messaging.
KIAUH now ships with a unified init abstraction so phones, tablets, and SBCs share the same workflows regardless of which service manager they boot. During startup the helper automatically detects whether the host is running systemd or
OpenRC. All service files are created in the appropriate
location (/etc/systemd/system for systemd, /etc/init.d for OpenRC) and every
component now executes start/stop/enable operations through a shared helper.
On OpenRC-based systems the helper transparently switches to rc-service and
rc-update, so manual maintenance commands follow the native tools instead of
systemctl.
- When NetworkManager is installed during the KlipperScreen flow on systemd, the helper now prints a reboot reminder instead of forcing an immediate restart so unattended runs can finish cleanly before you reboot manually.
- On OpenRC devices the standalone KlipperScreen path now installs a native
/etc/init.d/KlipperScreenscript, links it into the default runlevel, and exports the same environment variables as the upstream systemd unit so boot-to-console deployments land in the touch UI automatically. - apk-based OpenRC deployments now receive an
/etc/X11/Xwrapper.configwith console-friendly permissions soKlipperScreen-start.shcan launch Xorg from services without requiring logind. - The installer now patches
KlipperScreen-start.shwith a fallback client so manual launches still invokescreen.pyeven if init systems or shells omit theKS_XCLIENTenvironment export.
- Fluidd and other web front-ends now detect whether the host uses
/etc/nginx/conf.d/or Alpine's/etc/nginx/http.d/include directory before copying support files. This prevents the Fluidd installer from failing on postmarketOS devices whereconf.dis absent and keeps the generated configuration inside the directory that NGINX already loads. - The resolver now inspects
/etc/nginx/nginx.conffirst, so when both include directories exist it chooses the one nginx actually loads instead of defaulting to/etc/nginx/conf.d/and leaving the new sites ignored. - When neither include directory exists—common on freshly provisioned postmarketOS images—the installer now creates
/etc/nginx/conf.dbefore writingupstreams.confandcommon_vars.conf, so Fluidd deployments no longer abort with a missing-path error. - When
/etc/nginx/sites-availableor/etc/nginx/sites-enabledis missing—as on stock Alpine images—the installer provisions both directories withsudo install -dand drops akiauh-sites.confinclude into the detected NGINX include directory so multiple dashboards (Mainsail, Fluidd, PrettyGCode, etc.) can coexist without rewritingnginx.conf. - The
kiauh-sites.confhelper now seeds the resolved include directory before writing so stock nginx configurations load the generated sites even whenconf.d/http.dwas absent beforehand. - The helper logs the resolved directory so you can confirm which include path was used if you need to hand-inspect the configuration later.
- When an expected site definition is missing entirely, the menu falls back to the saved default port instead of crashing so you can still reinstall or reconfigure the client.
- Fluidd's NGINX site definition now streams straight into place with
sudo tee, sidestepping the tmpfile rename thatdoas-backed hosts occasionally lost before it reached/etc/nginx. - The installer now provisions
/var/log/nginx,/var/lib/nginx/logs, and/run/nginxon demand so nginx no longer fails its configuration tests on postmarketOS images that omit the runtime directories.
- When KIAUH seeds a fresh
printer.cfgfor new Klipper instances it now re-checks for installed Mainsail/Fluidd directories and automatically adds the matchingincludestatements. The generated example therefore keeps your dashboards reachable immediately after installation, even on systems that install the web UIs before Klipper. - Uninstalling Fluidd's configuration through the removal menu now deletes the
fluidd.cfgsymlinks and comments out legacyinclude fluidd.cfgdirectives before pruning the git checkout and Moonraker stanza, preventing Klipper from erroring out on references that point at missing files.
- The crowsnest installer now falls back to an apk-aware workflow when
aptis unavailable, translating the upstream dependency list through KIAUH's package mapper so ustreamer builds cleanly on postmarketOS and other Alpine derivatives. - During the apk install path the helper renders the upstream
crowsnest.conf, environment file, and logrotate rule directly from the cloned repository, then provisions a native OpenRC service that mirrors the original systemd unit so/webcam,/webcam2, etc. work immediately inside Fluidd and Mainsail. - Installations on OpenRC hosts add the invoking user to the
videogroup automatically and restart the new service, which keeps the camera stream reachable through the existing NGINX reverse proxy without manual tweaks.
- When the helper detects the
nftbinary it now inspects the defaultinet filter inputchain and offers to add allow rules for Moonraker and NGINX-hosted web UIs (Fluidd, Mainsail, etc.). Fresh installs only prompt when the target port is missing so existing firewall policies remain untouched. - The dialog lets you keep the listener open to the world, restrict it to the automatically detected local subnets, or enter a custom comma-separated list of CIDR ranges/hosts. IPv4 and IPv6 prefixes are supported.
- Reconfiguring a web UI port through the installation menu re-runs the firewall helper so the nftables rule stays in sync without manual edits. You can always skip the automation and adjust rules manually if you prefer.
- When the default
inet filter inputchain is missing, the helper now surfaces a follow-up warning that links to the postmarketOS firewall guide so you know where to add rules manually before continuing.
- The Installation menu now exposes a
WireGuardentry that installswireguard-tools, walks you through generating or importing keys, and writes/etc/wireguard/<interface>.confwith the peer settings you provide. - Existing configurations are backed up with a timestamped
.bakbefore the new file is written, permissions are tightened to600, and KIAUH enables the matchingwg-quickservice for systemd and OpenRC hosts when possible. - The helper prints the freshly generated public key so you can register the device on your VPN gateway, making it easier to pair WireGuard with the nftables automation when remote access is required.
During KlipperScreen installation you can now pick a Wayland launcher preset that mirrors the upstream Phosh, Plasma Mobile, and Sxmo recommendations while also deferring the choice until after you explicitly select the Wayland backend in the upstream installer. X11-first setups therefore skip the extra question but can rerun the preset helper later if they move to Wayland. When Wayland is selected, the prompt surfaces device-aware display defaults gathered from postmarketOS hardware probing. KIAUH writes the following artefacts after cloning the KlipperScreen repository:
- A shell wrapper in
~/.local/bin/that exports the compositor-friendly environment variables (Qt, GTK, SDL, etc.) before delegating toKlipperScreen-start.sh. - A
.desktopentry in~/.local/share/applications/so Phosh/Plasma launchers can spawn KlipperScreen with the expected Wayland flags. - When a Phosh or Plasma Mobile session is detected at install time, a matching
autostart entry is written to
~/.config/autostart/so the wrapper launches automatically on login. If KIAUH cannot detect the shell—for example when you run the installer over SSH—it now offers to generate a generic autostart entry so the session still comes up automatically after the next login. - On OpenRC consoles without a graphical shell, a login snippet in
~/.config/profile.d/waits for Moonraker to respond before spawning KlipperScreen. - Either a
systemd --userservice or an OpenRC user service stub, depending on the host init system, pointing to the wrapper. - Sxmo environments receive the same wlroots variables the upstream
sxmo-utilspackage exports, ensuring Qualcomm msm8953 reference images can launch KlipperScreen without additional wrappers.
KIAUH now enables the generated autostart integration automatically:
systemd --userservices are enabled and started withsystemctl --user enable --now …as part of the preset helper. If the helper cannot talk to the user service manager (for example because DBus is not available), it will print the exact command so you can run it manually later.- OpenRC user services are symlinked into
~/.config/openrc/runlevels/default/for you. Should the directory already contain a conflicting file, the helper prints instructions for creating the link manually.
The launcher presets are additive—the existing system instance managed by KIAUH remains untouched—so you can try the Wayland session without disrupting the original install.
When you enable panorama mode from the KlipperScreen installer menu, KIAUH now
updates KlipperScreen.conf, regenerates the X11 helper script, and attempts to
restart the system KlipperScreen service so the new resolution takes effect
immediately. If restarting the service fails (for example because it is running
as a user unit), the log highlights the next steps so you can restart it
manually. The updated writer now places the width/height overrides inside the
[main] section even when custom printer blocks exist, so KlipperScreen applies
the new geometry on the next launch. You can re-run the installer menu at any
time to adjust the recorded resolution or output name.
- The KlipperScreen installer now defaults to the packages strictly required to run the UI with touch input. Optional fonts and media backends are skipped unless you explicitly opt in when KIAUH asks before launching the upstream installer.
- Headless or scripted runs can preseed the decision by exporting
KIAUH_KS_INSTALL_EXTRAS=1(install extras) orKIAUH_KS_INSTALL_EXTRAS=0(keep the minimal set) before invokingKlipperScreen-install.sh. - When the extras are skipped, the downstream log highlights that the install kept the dependency footprint minimal, so you can verify that the additional packages were not pulled in.
- When the helper detects an Alpine/postmarketOS environment it now swaps the upstream KlipperScreen installer with an apk-aware wrapper before execution. The wrapper mirrors the original prompts but resolves dependency installation through
apk(ordoaswhensudois absent) so X11 packages install cleanly. - The translated dependency set covers the classic Xorg stack (
xorg-server,xf86-input-libinput,xf86-video-fbdev,xset, etc.) as well as the Wayland kiosk trio. Users can therefore continue accepting the default X11 backend even on phones where Wayland is not yet stable. - Systems booted with OpenRC automatically skip systemd unit creation while still provisioning the graphical backend packages, letting the downstream OpenRC autostart integration take over.
When KlipperScreen runs as a user-managed service (systemd --user, OpenRC
user units, or the login hook above) Moonraker's update-manager entry skips the
managed_services stanza so non-systemd autostart strategies remain unaffected
by future updates.
If wlr-randr or weston-info is present, KIAUH now detects the built-in
display during installation. The detected width, height, and rotation hint are
written to ~/printer_data/config/KlipperScreen.conf (or appended within the
existing [main] section if the file already exists). Adjust the values if
your compositor applies additional scaling, or if you rotate the panel within
Phosh/Plasma settings.
Touch rotation is still handled by the compositor—follow the upstream troubleshooting guide if pointer coordinates do not align after rotating.
- During installation KIAUH now asks whether KlipperScreen should run in a
panorama (horizontal) layout. Opting in rewrites the width/height defaults in
KlipperScreen.conf, ensuring wide touch panels advertise the correct horizontal resolution from the[main]section even when other printer profiles are present. - The same prompt seeds an executable helper under
~/.config/klipperscreen/panorama-xrandr.sh. When the X11 backend is active the patched launcher executes this helper before starting KlipperScreen so the selected output is configured with the requested mode and rotation. - You can rerun the KlipperScreen installer at any time to tweak the panorama resolution or disable the helper by removing the script.
- After panorama mode, the installer now offers to mirror the
postmarketOS auto-rotation workflow
for KlipperScreen. Opting in writes
~/.config/klipperscreen/autorotate.sh, a helper that listens tomonitor-sensorevents fromiio-sensor-proxyand applies orientation changes viawlr-randr(Wayland) orxrandr(X11). - The helper now understands both pure X11 console launches and desktop Wayland
sessions. It consumes backend hints from the launcher, waits for the target
display server to become ready, and falls back gracefully when neither
wlr-randrnorxrandris present. - The KlipperScreen launcher loads the helper in the background on every start.
Set
KIAUH_DISABLE_AUTOROTATE=1before launching if you need to pause the sensor listener temporarily. - To override the automatic backend detection entirely, export
KIAUH_AUTOROTATE_BACKEND=x11(orwayland) before starting KlipperScreen. - Because the helper relies on
monitor-sensor, KIAUH highlights when the binary is missing so you can installiio-sensor-proxybefore expecting rotation events. The log also warns when neitherwlr-randrnorxrandris available, giving you a chance to install the appropriate output utility.
To keep the postmarketOS port predictable, every Debian package requested by the
component installers under kiauh/components/** is mapped to the appropriate
Alpine apk name (where possible). The tables below list the exact inventory.
Entries marked as "Not available" are skipped at runtime and emit a warning so
that you can plan any manual workarounds.
| Debian package | Alpine package(s) |
|---|---|
| git | git |
| wget | wget |
| curl | curl |
| unzip | unzip |
| dfu-util | dfu-util |
| python3-virtualenv | py3-virtualenv |
| Debian package | Alpine package(s) |
|---|---|
| virtualenv | py3-virtualenv |
| python3-dev | python3-dev |
| libffi-dev | libffi-dev |
| build-essential | build-base |
| libncurses-dev | ncurses-dev |
| libusb-dev | libusb-dev |
| avrdude | avrdude |
| gcc-avr | avr-gcc |
| binutils-avr | avr-binutils |
| avr-libc | avr-libc |
| stm32flash | stm32flash |
| libnewlib-arm-none-eabi | newlib-arm-none-eabi |
| gcc-arm-none-eabi | arm-none-eabi-gcc |
| binutils-arm-none-eabi | arm-none-eabi-binutils |
| libusb-1.0 | libusb |
| Debian package | Alpine package(s) |
|---|---|
| python3-numpy | py3-numpy |
| python3-matplotlib | py3-matplotlib |
| libatlas-base-dev | atlas-dev |
| libopenblas-dev | openblas-dev |
| Debian package | Alpine package(s) |
|---|---|
| python3-virtualenv | py3-virtualenv |
| python3-dev | python3-dev |
| libopenjp2-7 | openjpeg |
| libsodium-dev | libsodium-dev |
| zlib1g-dev | zlib-dev |
| libjpeg-dev | libjpeg-turbo-dev |
| packagekit | Not available on Alpine* |
| wireless-tools | wireless-tools |
| iw | iw |
| python3-libcamera | py3-libcamera |
| curl | curl |
| build-essential | build-base |
ℹ️ Debian fallback on apk systems – Moonraker's dependency manifest currently ships a single Debian block. When KIAUH detects an Alpine/postmarketOS environment it now reuses that list, feeds the entries through the translation table above, and surfaces warnings for packages without a native apk port (e.g.,
packagekit).
✅ BusyBox-friendly policykit install – postmarketOS ships BusyBox utilities whose
greplacks the-Pflag used by Moonraker's policykit script. When that happens KIAUH now installs GNUgrepautomatically on apk-based systems and retries the helper so the policykit rules land correctly.
🔁 Policykit password retries – If Moonraker's policykit helper exits because sudo/doas authentication failed, KIAUH now reruns the helper so you can re-enter the password before it assumes BusyBox
grepis missing.
🧩 PackageKit-free system updates – Alpine/postmarketOS mirrors do not ship PackageKit, so KIAUH now installs an apt-compatible drop-in backed by
apk, leaves Moonraker's policykit helper in place, and keeps the Update Manager's system provider working without warning banners.
| Debian package | Alpine package(s) |
|---|---|
| git | git |
| crudini | crudini |
| bsdutils | util-linux |
| findutils | findutils |
| v4l-utils | v4l-utils |
| curl | curl |
| build-essential | build-base |
| make | make |
| libevent-dev | libevent, libevent-dev |
| libjpeg-dev | libjpeg-turbo-dev |
| libbsd-dev | libbsd-dev |
| pkg-config | pkgconf |
| Debian package | Alpine package(s) |
|---|---|
| cmake | cmake |
| libavformat-dev | ffmpeg-dev |
| libavutil-dev | ffmpeg-dev |
| libavcodec-dev | ffmpeg-dev |
| libcamera-dev | libcamera, libcamera-dev |
| libcamera-apps-lite | Not available on Alpine* |
| liblivemedia-dev | live555, live555-dev |
| pkg-config | pkgconf |
| xxd | xxd |
| build-essential | build-base |
| libssl-dev | openssl-dev |
| Debian package | Alpine package(s) |
|---|---|
| build-essential | build-base |
| dpkg-dev | dpkg |
| make | make |
| Debian package | Alpine package(s) |
|---|---|
| nginx | nginx |
*packagekit powers Moonraker's PackageKit integration on Debian systems but is
not shipped for Alpine/postmarketOS. libcamera-apps-lite provides optional
camera utilities that are also unavailable on Alpine. The helper warns when
these packages are skipped so you can review downstream tooling requirements.
**📋 Please see the Changelog for possible important
changes!**
- Mainly tested on Raspberry Pi OS Lite (Debian 10 Buster / Debian 11 Bullseye)
- Other Debian based distributions (like Ubuntu 20 to 22) likely work too
- Reported to work on Armbian as well but not tested in detail
- Automatic package manager detection now supports both
aptandapk- This allows running KIAUH on Alpine Linux derivatives such as postmarketOS
- The helper now inspects
/etc/os-releaseso Alpine/postmarketOS hosts always preferapk, even when compatibility wrappers exposeapt-get
- During the use of this script you will be asked for your sudo password. There
are several functions involved which need sudo privileges.
- When a privileged action needs
sudofor the first time KIAUH now offers to cache your credentials for the remainder of the session. Consenting keeps the password inside sudo's timestamp cache and clears it automatically when you leave the helper so long-running tasks only prompt once, while environments that lack the required sudo flags fall back to standard prompting without logging option errors.
- When a privileged action needs
![]() |
![]() |
|
|---|---|---|
| by KevinOConnor | by Arksine | by mainsail-crew |
![]() |
||
| by fluidd-core | by jordanruthe | by OctoPrint |
| by nlef | by Kragrathea | by Obico |
![]() |
||
| by Patrick Schmidt | by Quinn Damerell | by Christian Würthner |
| by Staubgeborener | by SimplyPrint |
- A big thank you to lixxbox for that awesome KIAUH-Logo!
- Also, a big thank you to everyone who supported my work with a Ko-fi !
- Last but not least: Thank you to all contributors and members of the Klipper Community who like and share this project!






