Files
peardock/README.md
T
snxraven 244ff569f5 Enable Holesail tunnels by default; keep holesail as required dep
Holesail is on unless ENABLE_HOLESAIL=0/false/off. The holesail package remains a required dependency; docs and UI copy match the new default.
2026-07-10 22:56:17 -04:00

182 lines
5.4 KiB
Markdown

# 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://<your-app-key>
```
---
## 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