As a technical architect, I didn't want another rented cloud VPS running a generic shared hosting panel. I wanted to turn a Raspberry Pi 5 on my desk, backed by a static IP, into a genuine hybrid personal server—and HostPanel was the architectural initiative to build that system.

HostPanel dashboard

The Hybrid Personal Server Problem

Traditional control panels are built around a single paradigm: multi-tenant web hosting inside a remote cloud datacenter. Their entire architecture assumes a disposable virtual machine hosting hundreds of isolated customer websites.

A hybrid personal server requires a fundamentally different architecture. It lives on physical bare metal in my own workspace and simultaneously manages two distinct operating zones:

  1. Private Local Infrastructure: Internal databases (PostgreSQL, MariaDB, MongoDB), S3-compatible private object storage, and a WireGuard VPN gateway. These services must remain strictly private, accessible only across an encrypted VPN tunnel or local network.
  2. Hardened Public Workloads: Production web applications, custom API endpoints, automated ACME Let's Encrypt certificates, and an authoritative PowerDNS nameserver directly serving traffic to the internet over a dedicated static IP address.

Existing open-source control panels fail in this role. They act like monolithic installer scripts that seize control of the operating system. They scatter configuration files across /etc, dump logs into /var/log, inject unvetted PPAs into system apt sources, and trigger multi-hour source compiles that peg all four ARM cores.

When you run a hybrid appliance on a Raspberry Pi 5, system drift and OS pollution are unacceptable. If a public-facing service encounters an issue, or if a package update fails, it must never compromise the private network, corrupt the host operating system, or require re-flashing the SD card.

Design Constraints Before Code

Before writing the backend gateway or the React dashboard, I wrote a strict set of operational constraints (PROJECT_RULES.md). In systems architecture, jumping straight into feature development without firm boundaries produces brittle software that rots.

A few non-negotiables were established early and enforced throughout the codebase:

  • 100% Filesystem Isolation under /opt/hostpanel: The host operating system must remain completely clean. Every configuration, runtime, socket, database, and log lives under /opt/hostpanel:
    text
    /opt/hostpanel/
    ├── etc/          # Service configurations (Nginx, PHP-FPM, PowerDNS)
    ├── data/         # SQLite persistence (hostpanel.db)
    ├── logs/         # Centralized and per-service log streams
    ├── run/          # Unix domain sockets and PID files
    ├── packages/     # Package manifests, APIs, and micro-frontends
    ├── runtimes/     # Standalone language runtimes (PHP 8.4, Node.js 20)
    └── dump/         # Database snapshots and temporary archives
    
    If you remove /opt/hostpanel, the underlying Raspberry Pi OS remains completely untouched.
  • Precompiled Standalone Runtimes (Zero On-Host Compilation): A Raspberry Pi shouldn't spend two hours running gcc or make -j4 to compile PHP or MongoDB from source, nor should it borrow /usr/bin/php or /usr/bin/node from the host OS. Every runtime must be pre-vetted, architecture-specific (aarch64 / x86_64), completely self-contained, and isolated within /opt/hostpanel/runtimes/<pkg>/<version>.
  • Transactional Persistence with SQLite (WAL Mode): The earliest prototype used JSON files on disk for configuration. That worked until concurrent API requests created write-lock collisions and corrupted state. I migrated immediately to SQLite with Write-Ahead Logging (WAL). SQLite provides full ACID transaction guarantees without the memory overhead of running a dedicated external database daemon just for the control panel.
  • Real-Time Terminal Streaming via SSE: Silencing operational commands with >/dev/null 2>&1 is forbidden. In an infrastructure appliance, hidden execution is a liability. Package installations, runtime extractions, and service restarts must stream unbuffered stdout and stderr line-by-line via Server-Sent Events (SSE) directly to the browser's terminal modal.
  • Mandatory Audit Trail: Every state mutation—updating an S3 bucket ACL, issuing a Let's Encrypt certificate, provisioning a virtual host, or generating a WireGuard peer—must write permanently to the central audit log.

The Architecture: The Three-Repository Split

To keep the Raspberry Pi responsive and prevent monolithic bloat, HostPanel is decoupled into three independent GitHub repositories:

HostPanel packages

  1. hostpanel (Core Gateway / portald): A lightweight FastAPI gateway running on port 2081. It serves the React 18 Single Page Application, owns the central SQLite database, dynamically allocates loopback ports (9100–9199), and securely proxies requests to package daemons over loopback using HMAC tokens (X-HostPanel-Token).
  2. hostpanel-packages (Pluggable Services): A catalog of 15 self-contained packages (Nginx, Apache, PHP, Node.js, MariaDB, MongoDB, WireGuard, Storage, Mail, etc.). Each package runs as its own unprivileged systemd daemon under a dedicated user (e.g. hp-nginx, hp-php, hp-wireguard), executes elevated actions through a strictly scoped sudo runner (ops/hp-<pkg>), and ships a pre-bundled React micro-frontend (dist/main.js).
  3. hostpanel-binaries (Standalone Distributions): Pre-compiled, portable binaries for ARM64 (aarch64) and x86_64. When a package needs a runtime or daemon, it fetches the pre-vetted binary artifact directly from GitHub releases during installation, extracting it cleanly into /opt/hostpanel/runtimes/.

The Architectural Trade-off

This architecture requires discipline: maintaining separate repositories, coordinating version contracts, managing loopback port allocations, and validating micro-frontend bundles is more upfront engineering than building a single monolithic script.

However, it buys absolute fault isolation. If a background job in the email service locks up, WireGuard routing and PowerDNS resolution remain completely unaffected. If I upgrade PHP to 8.4, the core gateway never blinks. The blast radius of any individual service is strictly contained.

What's Next in This Series

This first post set the architectural foundation: why I built a hybrid personal server on a Raspberry Pi 5, the non-negotiables behind filesystem isolation, and the three-repository model.

In Part 2, we will go under the hood of the HostPanel Core Gateway (portald):

  • How the core gateway discovers packages and loads React micro-frontends dynamically.
  • The loopback daemon model (9100–9199) and HMAC token authentication.
  • How PowerDNS integrates natively with SQLite views for instant DNS record updates without daemon reloads.
  • Line-by-line SSE log streaming in action.

Repository: Developer-Geekay/hostpanel