# peardock Decentralized Docker management on the modern Holepunch stack. | Layer | Technology | |-------|------------| | Transport | **HyperDHT** (Noise-encrypted P2P) | | RPC | **protomux-rpc** + **compact-encoding** JSON | | Client | **Pear** desktop app | | Docker | **dockerode** | No central control plane. The server announces a keypair on the DHT; clients connect with its public key. --- ## Quick start ### 1. Install ```bash npm install # Node.js ≥ 20 required ``` ### 2. Run the server (machine with Docker) ```bash npm run server ``` You will see: ``` peardock server ready Public key (paste into the client): <64 hex characters> ``` Keep this process running. Identity is stored in `.env`: | Variable | Meaning | |----------|---------| | `SERVER_SEED` | Secret 32-byte seed (never share) | | `SERVER_PUBLIC_KEY` | Derived public key (share with clients) | | `SERVER_KEY` | Legacy alias for the seed (still accepted) | ### 3. Run the desktop client Ensure the Pear binary is on your `PATH` (one-time): ```bash # macOS export PATH="$HOME/Library/Application Support/pear/bin:$PATH" # make permanent in fish: # fish_add_path "$HOME/Library/Application Support/pear/bin" ``` Then: ```bash npm run dev # or: pear run -d . ``` Paste the **public key** into the sidebar connection field. > **Note:** Pear may print `DEPRECATED: pear run is deprecated`. That is a platform-wide message. > This app uses the supported **pear-electron + pear-bridge** entry (`index.js`) so it is not a legacy HTML app. > Long-term OTA packaging uses [hello-pear-electron](https://github.com/holepunchto/hello-pear-electron) / `pear-runtime`. ### Production Pear app ```bash pear stage . pear release . pear run pear:// ``` --- ## Architecture ``` shared/ Protocol constants + encodings (both sides) server/ server.js Entry: HyperDHT listen core/ Keys, peer registry rpc/ PeerSession (protomux-rpc), handler registration handlers/ Domain methods (containers, images, volumes, …) services/ Docker client, stats, event stream utils/ Validation, rate limit, logging, compose client/ connection.js Single HyperDHT + protomux-rpc link manager.js Multi-server connections + persistence api.js Typed RPC helpers app.js + libs/ Pear UI ``` ### RPC model **Client → server** methods (examples): `handshake`, `ping`, `listContainers`, `killContainer`, `containerTop`, `deployContainer`, `pruneImages`, `getSystemDf`, `startTerminal`, … **Server → client** pushes: `push:containers`, `push:allStats`, `push:logs`, `push:pullProgress`, `push:buildProgress`, `push:dockerEvent`, `push:terminalOutput`, … Defined in `shared/protocol.js` (`PROTOCOL_VERSION` negotiated on connect). See `ROADMAP.md` for coverage and remaining work. --- ## Deployment 1. **Host** — Linux/macOS with Docker socket access for the server user. 2. **Process** — `systemd` / `pm2` / Docker supervising `node server/server.js`. 3. **Network** — HyperDHT holepunches; allow UDP when possible. Bootstrap peers are built into `hyperdht`. 4. **Secrets** — Back up `SERVER_SEED`. Rotating seed changes the public key; clients must reconnect. 5. **Pear** — Stage/release the desktop app separately from the control-plane server. 6. **Security** — Connections are E2E encrypted (Noise). Rate limits apply per peer. RPC methods are gated by role (`viewer` / `operator` / `admin`; default admin). Privileged actions append to an audit log. Docker CLI is allow-listed to read-only style commands. Optional env: `PEARDOCK_DEFAULT_ROLE`, `PEARDOCK_ADMIN_KEYS`, `PEARDOCK_BROWSE_ROOTS`, `PEARDOCK_AUDIT`. 7. **Holesail tunnels (on by default)** — Expose published container/host ports over [Holesail](https://github.com/holesail/holesail) `hs://` keys (separate from control-plane RPC). Opt out with `ENABLE_HOLESAIL=0`. See [docs/HOLESAIL.md](docs/HOLESAIL.md). Note: the required `holesail` dependency is AGPL-3.0. Example systemd unit: ```ini [Unit] Description=peardock HyperDHT server After=docker.service Requires=docker.service [Service] WorkingDirectory=/opt/peardock ExecStart=/usr/bin/node server/server.js Restart=on-failure Environment=NODE_ENV=production [Install] WantedBy=multi-user.target ``` --- ## Scripts | Command | Description | |---------|-------------| | `npm run server` | Start HyperDHT Docker control plane | | `npm run dev` | Pear desktop app (dev) | | `npm test` | Unit + fuzz + load + integration tests | | `npm run healthcheck` | Docker socket health probe | | `npm run soak` / `soak:24h` | Certification soak against Docker | | `npm run release:checksums` | Release tarball + SHA-256 (+ optional GPG) | See **`ROADMAP.md`** (complete) and **`docs/`** for operators, threat model, and releases. --- ## Dependencies (current) - `hyperdht` ^6.33 - `protomux-rpc` ^1.10 - `protomux` ^3.11 - `compact-encoding` ^3.3 - `b4a` ^1.8 - `hypercore-crypto` ^3.7 - `dockerode` ^5 - `dotenv` ^17 - `graceful-goodbye` ^1.3 --- ## Breaking changes from v1 | v1 (legacy) | v2 (current) | |-------------|--------------| | Hyperswarm topic = `SERVER_KEY` | HyperDHT listen on keypair from seed | | Share topic hex with clients | Share **public key** with clients | | Raw JSON on duplex streams | protomux-rpc methods + push channels | | Monolithic `server.js` switch | Modular handlers under `server/handlers/` | --- ## License Apache-2.0