feat: add native user service installs

This commit is contained in:
Federico Jaramillo Martinez
2026-05-25 16:28:09 +02:00
parent 711c4f3d98
commit 824728174b
10 changed files with 633 additions and 227 deletions
+19 -22
View File
@@ -54,8 +54,8 @@
<p class="eyebrow"><span class="pulse"></span> FAQ & troubleshooting</p>
<h1>Fix the things that usually go wrong first.</h1>
<p>
Most PI WEB install issues are environment issues: systemd availability, PATH setup, Node version managers,
or remote access expectations.
Most PI WEB install issues are environment issues: native service manager availability, PATH setup, Node
version managers, or remote access expectations.
</p>
</div>
</section>
@@ -64,11 +64,11 @@
<div class="container doc-layout">
<aside class="toc" aria-label="FAQ contents">
<strong>Questions</strong>
<a href="#is-this-linux-only">Is this Linux only?</a>
<a href="#is-this-linux-only">What platforms are supported?</a>
<a href="#tools-are-not-found">Tools are failing / node not found</a>
<a href="#doctor-fails">What does doctor check?</a>
<a href="#nvm-fnm-asdf">nvm, fnm, or asdf issues</a>
<a href="#systemd-not-found">systemctl is not available</a>
<a href="#systemd-not-found">User service manager is unavailable</a>
<a href="#cannot-open">I cannot open the web UI</a>
<a href="#public-internet">Can I expose this publicly?</a>
<a href="#laptop-or-server">Laptop or server?</a>
@@ -79,18 +79,16 @@
<div class="faq-list">
<article id="is-this-linux-only" class="faq-item">
<h2>Is this Linux only?</h2>
<h2>What platforms are supported?</h2>
<p>
No. PI WEB can run anywhere its runtime dependencies work, including macOS and Windows through WSL. The
automatic <code>pi-web install</code> command is the Linux-specific part because it writes and manages
<code>systemctl --user</code> services.
PI WEB can run anywhere its runtime dependencies work. The automatic <code>pi-web install</code> command uses
a supported per-user service manager when one is available.
</p>
<ul>
<li><strong>Linux with systemd:</strong> use <code>npm install -g @jmfederico/pi-web</code> and <code>pi-web install</code>.</li>
<li><strong>macOS:</strong> install the package, then run <code>pi-web-sessiond</code> and <code>pi-web-server</code> manually.</li>
<li><strong>Windows:</strong> use WSL. If your WSL distro has systemd enabled, the installer may work; otherwise use the manual run path.</li>
<li><strong>User-service install:</strong> use <code>npm install -g @jmfederico/pi-web</code> and <code>pi-web install</code>.</li>
<li><strong>WSL:</strong> if your distro has systemd enabled, the installer may work; otherwise use the manual run path.</li>
<li><strong>Native Windows:</strong> outside WSL is not the recommended path today.</li>
</ul>
<p>Native Windows outside WSL is not the recommended path today.</p>
</article>
<article id="tools-are-not-found" class="faq-item">
@@ -122,8 +120,8 @@
<article id="doctor-fails" class="faq-item">
<h2>What does <code>pi-web doctor</code> check?</h2>
<p>
It checks whether the service shell and systemd user environment can find Node 22+, npm, Pi, and the Pi
Web binaries. It also reports whether user service lingering is enabled for server-style installs.
It checks whether the service shell and native service environment can find Node 22+, npm, Pi, and the Pi
Web binaries. It also reports user service lingering when relevant for server-style installs.
</p>
<p>
If something works in your terminal but fails in doctor, treat that as a login-shell PATH mismatch and
@@ -147,10 +145,10 @@
</article>
<article id="systemd-not-found" class="faq-item">
<h2><code>systemctl --user</code> is not available</h2>
<h2>User service manager is unavailable</h2>
<p>
The automatic installer needs Linux user systemd. On macOS, WSL without systemd, containers without a
user systemd manager, or minimal Linux environments, run the two processes manually:
The automatic installer needs a supported per-user service manager. On WSL without systemd, containers
without a user service manager, or minimal environments, run the two processes manually:
</p>
<div class="code-card">
<div class="copy-row">
@@ -224,21 +222,20 @@
<strong>Session daemon logs</strong>
<button class="copy-button" data-copy="#session-logs">Copy</button>
</div>
<pre id="session-logs"><code><span class="prompt">$</span> systemctl --user status pi-web-sessiond.service
<span class="prompt">$</span> journalctl --user -u pi-web-sessiond.service -f</code></pre>
<pre id="session-logs"><code><span class="prompt">$</span> pi-web status
<span class="prompt">$</span> pi-web logs</code></pre>
</div>
</article>
<article id="logs" class="faq-item">
<h2>Where are logs?</h2>
<p>For the Linux systemd install, use:</p>
<p>Use the service log command:</p>
<div class="code-card">
<div class="copy-row">
<strong>Logs</strong>
<button class="copy-button" data-copy="#logs-command">Copy</button>
</div>
<pre id="logs-command"><code><span class="prompt">$</span> pi-web logs
<span class="prompt">$</span> journalctl --user -u pi-web-sessiond.service -u pi-web.service -f</code></pre>
<pre id="logs-command"><code><span class="prompt">$</span> pi-web logs</code></pre>
</div>
</article>
</div>
+7 -7
View File
@@ -103,7 +103,7 @@
<span class="prompt">$</span> pi-web doctor
✓ login shell can find node >= 22
systemd user shell can find pi
native service shell can find pi
✓ ready for persistent agent work</code></pre>
</aside>
</div>
@@ -237,10 +237,10 @@
<div class="container install-panel">
<div class="install-card">
<p class="eyebrow"><span class="pulse"></span> Quick install</p>
<h2>Linux servers get the smooth path.</h2>
<h2>Run PI WEB as user services.</h2>
<ol>
<li>Install the package globally with npm.</li>
<li>Run the installer to create user-level systemd services.</li>
<li>Run the installer to create native per-user services.</li>
<li>Open the local URL, or tunnel it from a remote machine.</li>
</ol>
<div class="doc-actions">
@@ -251,7 +251,7 @@
<div class="terminal quick-install">
<div class="copy-row">
<strong>Recommended Linux install</strong>
<strong>User service install</strong>
<button class="copy-button" data-copy="#home-install">Copy</button>
</div>
<pre id="home-install"><code><span class="prompt">$</span> npm install -g @jmfederico/pi-web
@@ -265,10 +265,10 @@
<section class="section compact">
<div class="container doc-grid">
<article class="doc-card">
<h3>macOS and WSL?</h3>
<h3>WSL and containers?</h3>
<p>
PI WEB itself is not Linux-only. The one-command service installer targets Linux systemd. macOS and WSL can
run PI WEB manually; WSL with systemd can use the installer too.
Use <code>pi-web install</code> where a supported per-user service manager is available. WSL works with the
installer when systemd is enabled; otherwise use the manual run path.
</p>
<a href="faq.html#is-this-linux-only">Read compatibility notes →</a>
</article>
+25 -20
View File
@@ -54,8 +54,8 @@
<p class="eyebrow"><span class="pulse"></span> Installation guide</p>
<h1>Get PI WEB running where your agents work.</h1>
<p>
The best production-style setup is a Linux machine with user-level systemd services. macOS and Windows WSL
are useful too: run the two PI WEB processes manually, or use the installer in WSL when systemd is enabled.
The recommended setup runs PI WEB as per-user services. PI WEB chooses the native user-service backend for
your operating system.
</p>
</div>
</section>
@@ -65,10 +65,10 @@
<aside class="toc" aria-label="Install page contents">
<strong>On this page</strong>
<a href="#requirements">Requirements</a>
<a href="#linux-systemd">Linux systemd install</a>
<a href="#user-services">User service install</a>
<a href="#one-line">One-line install</a>
<a href="#pi-package">Install through Pi</a>
<a href="#manual-run">macOS / WSL manual run</a>
<a href="#manual-run">WSL / manual run</a>
<a href="#remote-access">Remote access</a>
<a href="#manage-services">Manage services</a>
<a href="#configure">Configure</a>
@@ -82,7 +82,7 @@
<li><strong>Node.js 22 or newer</strong> and npm.</li>
<li><strong>Pi Coding Agent</strong> installed/configured so the <code>pi</code> command works for your user.</li>
<li>A shell login environment that exposes Node, npm, Pi, git, and any tools your agents need.</li>
<li>For the automatic installer: Linux with <code>systemctl --user</code>.</li>
<li>For the automatic installer: a supported per-user service manager.</li>
</ul>
<div class="callout warning">
<strong>Important PATH detail:</strong>
@@ -91,24 +91,24 @@
</div>
</section>
<section id="linux-systemd">
<h2>Recommended: Linux systemd install</h2>
<section id="user-services">
<h2>Recommended: run PI WEB as user services</h2>
<p>
This creates two user services: one long-lived session daemon and one web/API service. It is the easiest
way to keep sessions available after SSH disconnects or browser restarts.
This creates two per-user services: one long-lived session daemon and one web/API service. The CLI chooses
the native user-service backend automatically. It is the easiest way to keep sessions available after SSH
disconnects, browser restarts, or web/API restarts.
</p>
<div class="code-card">
<div class="copy-row">
<strong>Linux install</strong>
<strong>User service install</strong>
<button class="copy-button" data-copy="#linux-install">Copy</button>
</div>
<pre id="linux-install"><code><span class="prompt">$</span> npm install -g @jmfederico/pi-web
<span class="comment"># Recommended on servers so user services survive logout/reboot:</span>
<span class="prompt">$</span> sudo loginctl enable-linger "$USER"
<span class="prompt">$</span> pi-web install
<span class="prompt">$</span> pi-web doctor</code></pre>
</div>
<p>Then open <a href="http://127.0.0.1:8504">http://127.0.0.1:8504</a>.</p>
<p>On Linux servers, also consider <code>sudo loginctl enable-linger "$USER"</code> so user services survive logout/reboot.</p>
</section>
<section id="one-line">
@@ -143,10 +143,10 @@
</section>
<section id="manual-run">
<h2>macOS / WSL manual run</h2>
<h2>WSL / manual run</h2>
<p>
PI WEB is not Linux-only, but the <code>pi-web install</code> service setup is Linux/systemd-specific. On macOS
or WSL without systemd, install the package and run the daemon and web server yourself.
On WSL without systemd, containers without a user service manager, or other unsupported environments,
install the package and run the daemon and web server yourself.
</p>
<div class="code-card">
<div class="copy-row">
@@ -162,9 +162,13 @@
<span class="prompt">$</span> PI_WEB_PORT=8504 pi-web-server</code></pre>
</div>
<p>
On modern WSL distributions with systemd enabled, the Linux installer can work. Without systemd, use the
On modern WSL distributions with systemd enabled, the installer can work. Without systemd, use the
manual run approach above.
</p>
<p>
From a PI WEB checkout, <code>pi-web install --dev</code> installs the split development services on supported user-service platforms.
<code>pi-web uninstall</code> removes both production and development service files; no uninstall flags are needed.
</p>
</section>
<section id="remote-access">
@@ -200,8 +204,9 @@
<span class="prompt">$</span> pi-web logs
<span class="prompt">$</span> pi-web restart
<span class="prompt">$</span> pi-web doctor
<span class="prompt">$</span> systemctl --user status pi-web-sessiond.service pi-web.service
<span class="prompt">$</span> journalctl --user -u pi-web-sessiond.service -u pi-web.service -f</code></pre>
<span class="comment"># From a checkout, install the split development services:</span>
<span class="prompt">$</span> pi-web install --dev</code></pre>
</div>
</section>
@@ -239,8 +244,8 @@
<section id="uninstall">
<h2>Uninstall</h2>
<p>
<code>pi-web uninstall</code> stops, disables, and removes the systemd user services. It does not remove
the npm package, config file, or data directory.
<code>pi-web uninstall</code> stops, disables, and removes PI WEB's production and development service files.
It does not remove the npm package, config file, or data directory.
</p>
<div class="code-card">
<div class="copy-row">
+1 -1
View File
@@ -168,7 +168,7 @@ After editing, check the manifest endpoint and browser-console failure cases.</c
<section id="production">
<h2>Production usage</h2>
<p>
Local plugins work with the production npm/systemd install. Put each plugin under
Local plugins work with the production native-service install. Put each plugin under
<code>~/.pi-web/plugins/&lt;plugin-id&gt;/</code>, or symlink it there while developing. No PI WEB rebuild or
session-daemon restart is required.
</p>
+1 -1
View File
@@ -116,7 +116,7 @@ PI WEB also ships a `pi-web` status plugin that demonstrates dynamic `visible` a
## Local plugin usage
This works with the production npm/systemd install. PI WEB discovers plugins from `~/.pi-web/plugins/<plugin-package>/` on the web/API side; no PI WEB rebuild or session-daemon restart is required. If `PI_WEB_DATA_DIR` is set, use `$PI_WEB_DATA_DIR/plugins` instead.
This works with the production native-service install. PI WEB discovers plugins from `~/.pi-web/plugins/<plugin-package>/` on the web/API side; no PI WEB rebuild or session-daemon restart is required. If `PI_WEB_DATA_DIR` is set, use `$PI_WEB_DATA_DIR/plugins` instead.
Symlink a plugin folder into PI WEB's local plugin directory: