Skip to content

Building from Source

dnaidoo621 edited this page May 30, 2026 · 1 revision

Building from Source

Prerequisites

  • Docker — the build runs inside debian:bookworm-slim for reproducibility
  • Git
  • That's it — no Python, no dpkg tools needed on your build machine

Build steps

git clone https://github.com/dnaidoo621/htpc-remote
cd htpc-remote
bash build-deb.sh

This produces htpc-remote_1.0.0_all.deb in the project root.

To specify a version:

bash build-deb.sh 1.0.2

What the build script does

  1. Creates a staging tree at /tmp/htpc-remote-pkg/ with the required Debian layout:
htpc-remote-pkg/
├── DEBIAN/
│   ├── control      (package metadata)
│   ├── postinst     (install script)
│   └── prerm        (uninstall script)
└── opt/
    └── htpc-remote/
        ├── server/  (Python source)
        ├── web/     (React UI)
        └── run.py   (entry point)
  1. Runs dpkg-deb --build inside debian:bookworm-slim — avoids needing Debian tooling on macOS or other hosts.

  2. Copies the resulting .deb back out of the container.


Deploying to the HTPC

# Copy
scp htpc-remote_1.0.2_all.deb darren@192.168.1.x:/home/darren/

# Install
ssh darren@192.168.1.x 'sudo apt install -y ~/htpc-remote_1.0.2_all.deb'

# Restart service
ssh darren@192.168.1.x 'systemctl --user restart htpc-remote'

Or as a one-liner:

VERSION=1.0.2
HOST=192.168.1.x

scp htpc-remote_${VERSION}_all.deb darren@${HOST}:/home/darren/ && \
ssh darren@${HOST} "sudo apt install -y ~/htpc-remote_${VERSION}_all.deb && \
                    systemctl --user restart htpc-remote && \
                    systemctl --user status htpc-remote --no-pager"

Package metadata

packaging/DEBIAN/control:

Package: htpc-remote
Version: 1.0.2
Architecture: all
Maintainer: Darren Naidoo <dnaidoo621@users.noreply.github.com>
Depends: python3 (>= 3.9), python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, xdotool
Pre-Depends: python3-pip, python3-venv
Recommends: wtype, brightnessctl

Pre-Depends on python3-pip and python3-venv ensures those tools are available before postinst runs (which creates the virtualenv).


What postinst does

The post-install script runs as root with the package contents already in place:

  1. Detect the logged-in user — tries who :0, then loginctl, then falls back to scanning /home
  2. Create the virtualenvpython3 -m venv /opt/htpc-remote/venv --system-site-packages
  3. Install pip deps — FastAPI, uvicorn, pynput, evdev, qrcode, pillow
  4. Write udev rule/etc/udev/rules.d/99-uinput.rules for Wayland uinput access
  5. Add user to input groupusermod -aG input <user>
  6. Enable service globallysystemctl --user --global enable htpc-remote
  7. Start for current sessionsystemctl --user start htpc-remote (if the detected user is logged in)

Modifying the UI

The phone UI lives in web/static/ as JSX files processed in-browser by Babel standalone. Edit them directly — no build step, no npm.

To test changes locally:

cd web
python3 -m http.server 8900
# Open http://localhost:8900?debug=controller in a browser

URL params for development:

  • ?debug=controller — loads the controller directly without needing a WebSocket
  • (no param) — loads the connection flow (will show "Connecting…" since there's no WS server)

Clone this wiki locally