← All guides

Install PiChamber

Install the desktop application or the PiChamber server.

Desktop

Download PiChamber from the GitHub Releases page. The desktop application starts its PiChamber backend in-process.

On Linux, choose the package for your distribution when possible:

  • Ubuntu, Debian, Linux Mint, and other Debian-family distributions: download the .deb package and install it with sudo apt install ./PiChamber-...-linux-amd64.deb.
  • Fedora, RHEL, openSUSE, and other RPM-family distributions: download the .rpm package and install it with sudo dnf install ./PiChamber-...-linux-x86_64.rpm.
  • Other distributions or a portable install: use the AppImage. Copy it to a writable Linux filesystem, make it executable with chmod +x, and launch it from that location. AppImages use Electron's compatibility --no-sandbox mode because a user-mounted AppImage cannot provide the root-owned Chromium sandbox helper; use a .deb or .rpm package when the full Chromium sandbox is required.

AppImage updates keep the existing file path so desktop shortcuts remain valid. The update is validated before replacement, and the previous image is retained until the new version starts successfully.

Server

PiChamber server needs Node.js 22.19 or newer (24 recommended) or Bun 1.4 or newer (1.4.2 recommended). Install the CLI package with a package manager.

Bun (recommended):

bun add -g @pi-chamber/web

Other package managers:

npm install -g @pi-chamber/web
pnpm add -g @pi-chamber/web
yarn global add @pi-chamber/web

Run pichamber serve after installation. In an interactive terminal, the command asks where the server should listen, which port to use, how to protect the UI, whether to serve the browser UI, and whether to run in the background. It shows a review before starting. The server creates and owns its local Pi session daemon automatically.

Background serve picks Node first with Bun fallback. Foreground serve --foreground runs in the current runtime. Startup services reuse the pinned runtime from startup enable. The desktop app runs its bundled Node in-process. The mobile app connects to an existing server.

Termux (Android)

PiChamber server can run in Termux. Install Node.js and the native build tools, then point npm at Termux's local Node headers:

pkg install nodejs clang make python
npm install -g @pi-chamber/web --nodedir="$PREFIX"

Termux reports Node's platform as Android. Without --nodedir="$PREFIX", node-gyp downloads upstream Node headers whose Android configuration expects a separate NDK and node-pty fails with an undefined android_ndk_path. Termux's packaged headers are already configured for its bionic toolchain. This workaround is required while nodejs/node-gyp#3355 remains unresolved. npm currently warns that forwarding the --nodedir option may stop working in a future major release.

Start PiChamber with pichamber serve and use its normal status, stop, and restart commands. Do not wrap pichamber serve --foreground in nohup: foreground mode expects a process manager to restart it after pichamber restart stops it. pichamber startup enable manages systemd units and does not configure Android boot startup.

If your system still runs Bun 1.3.14, update Bun before you restart a Bun-pinned service. The source packageManager pin does not replace the installed binary. Node 22.0 through 22.18 is unsupported. No session migration is needed.

To install a server release candidate from npm, request the rc dist-tag explicitly:

npm install -g @pi-chamber/web@rc

After installation, connect to that server from Electron and select Server update channel → Release candidate in Settings → About. pichamber update then compares the latest stable and numbered RC releases and offers the higher version. Return the server to stable by selecting Stable. The CLI can override that saved default for one run with pichamber update --channel stable or pichamber update --channel rc.

Desktop app update channel remains visible in the same Settings section. That separate setting controls the local Electron package and never changes a server's npm installation. When Electron uses its Local instance, only the desktop app channel is shown; when it connects to a server, both channels are shown. Native mobile application updates remain on the stable application channel; the server preference controls only package updates for the connected server.

For scripts, CI, and non-interactive shells, pass the setup flags explicitly:

pichamber serve --port 3000 --ui-password "choose-a-strong-password"

Use one package manager for install and update. pichamber update detects the owning package manager (Bun, npm, pnpm, or Yarn), shows the current version, target version, package manager, and restart plan, then asks for confirmation in an interactive terminal. Use pichamber update --yes or -y to skip that confirmation. Servers configured by pichamber startup enable can update from the web UI or terminal; PiChamber runs the installer in a temporary systemd unit, verifies the installed version, and restarts the server. Docker deployments must pull a new image and recreate the container instead of using in-app replacement.

On a root VPS, pichamber startup enable creates a system unit at /etc/systemd/system/pichamber.service (systemctl restart pichamber.service) instead of a user unit, so it works without loginctl enable-linger. A normal user gets a user unit at ~/.config/systemd/user/pichamber.service (systemctl --user). In an interactive terminal, startup enable guides you through the bind address, port, password, and final confirmation. Pass the setup flags for a non-interactive install. Both scopes store the host and UI password in the data directory's startup.env (0600) and keep that file across upgrades.

Docker

The published server image is ghcr.io/ryderasking/pichamber. Tags are the release version, latest on stable releases, and rc on release candidates. Copy docker-compose.yml into an empty directory, then run:

mkdir -p data/pichamber data/pi/agent data/ssh data/workspaces
export PICHAMBER_UI_PASSWORD="$(openssl rand -base64 24)"
printf 'PiChamber password: %s\n' "$PICHAMBER_UI_PASSWORD"
docker compose up -d
docker compose logs -f

Save the password and open http://127.0.0.1:32145. Config, Pi sessions, SSH keys, and workspaces persist under ./data/ when the container is recreated.

See Run PiChamber in Docker for adding projects, reusing an existing ~/.pi/agent, handling symlinked dotfiles, backups, upgrades, network access, and multiple containers.

Run without installing

bunx @pi-chamber/web serve
npx @pi-chamber/web serve
pnpm dlx @pi-chamber/web serve

This downloads the package into a cache and runs it. It does not install pichamber on PATH. Prefer a global install for daily use and pichamber startup enable.

External access via Cloudflare Tunnel

You can expose a private PiChamber server without opening inbound ports via Cloudflare Tunnel (cloudflared). PiChamber manages the tunnel as a child of the server process and integrates it with the normal auth flow.

  1. Install cloudflared: brew install cloudflared (macOS), winget install --id Cloudflare.cloudflared (Windows), or download from https://developers.cloudflare.com/cloudflare-one/networks/connectors/cloudflared/downloads/ (Linux).
  2. Choose a mode in Settings → External Tunnel or run pichamber tunnel start in an interactive terminal. The CLI can select a saved profile, choose a mode, collect a managed-remote hostname and token, find a managed-local config, and offer to save a reusable profile. For a non-interactive run, provide the mode and required values explicitly, such as pichamber tunnel start --mode quick for an ephemeral *.trycloudflare.com URL, or pichamber tunnel start --mode managed-remote --token-file ~/.secrets/cloudflare-token --hostname pichamber.example.com for a persistent hostname. The token is stored at <dataDir>/cloudflare-tunnel-token.json (0600) and never returned in API responses or logs.
  3. When active, the Tunnel Settings page shows the public URL with copy/open actions and the tunnel status (not configured, connected/healthy, reconnecting, degraded, stopped, error). Use Stop or Remove to shut it down cleanly; the local cloudflared child is terminated and the bootstrap token is revoked.

Quick tunnels are best-effort (no SSE SLA); managed remote/local tunnels are the recommended persistent modes. The tunnel proxies to http://127.0.0.1:<port> and preserves Host/X-Forwarded-* headers, the Pi event SSE stream, WebSocket upgrades (/api/terminal/ws and /api/stt/ws), and authentication (UI sessions and oc_client_* bearer tokens). Only the PiChamber web UI is exposed; localhost-only admin endpoints remain bound to loopback.

If you manage Cloudflare yourself, paste an existing tunnel token in the Manual token field. PiChamber does not ask for your Cloudflare account password. Managed remote tunnels need a tunnel token and hostname; managed local tunnels use an existing cloudflared config file.

Run from source

git clone https://github.com/RyderAsKing/PiChamber.git
cd PiChamber
bun install
bun run dev

bun run start:web starts the packaged web server. bun run electron:dev starts the desktop shell. See the repository contributing guide for ports and other scripts.

These guides are synced from the PiChamber repository at 720cb33 and may lag behind main. Spot something stale? Propose an edit upstream, then re-run npm run sync:docs here.