Document seed proof, roles, pd1 capabilities, redeem/reconnect, and revoke, and link it from the README, threat model, operator, and protocol docs.
PearDock documentation
Complete technical documentation for the peardock codebase (v2.x / protocol version 2).
PearDock is decentralized Docker management: a HyperDHT control plane, structured protomux-rpc, a desktop client (Electron or Pear), and optional Holesail L4 tunnels. There is no SaaS broker. You share a public key; peers hole-punch and talk end-to-end encrypted.
| License | AGPL-3.0 |
| Package | peardock 2.0.1 (package.json) |
| Protocol | peardock/rpc · PROTOCOL_VERSION = 2 (shared/protocol.js) |
| Site | peardock.boats |
| Install | curl -fsSL https://install.peardock.boats | bash |
| Source | git.ssh.surf/snxraven/peardock |
Documentation map
Understanding the system
| Document | What you will learn |
|---|---|
| ARCHITECTURE.md | End-to-end design, two planes, connection lifecycle, mermaid diagrams |
| CODEBASE-MAP.md | Every top-level directory and major module, responsibilities, entry points |
| PROTOCOL.md | RPC methods, pushes, roles (MethodRoles), encodings, handshake |
| SERVER.md | Server boot, PeerSession middleware, handlers, services, persistence |
| CLIENT-UI.md | ConnectionManager, Electron vs Pear, UI views, jobs, local Holesail |
| FEATURES.md | Feature catalog by domain (containers, Swarm, tunnels, vault, …) |
Operating and shipping
| Document | What you will learn |
|---|---|
| OPERATOR.md | Install, systemd, ACL, env flags, logging, backup |
| SECURITY_AUTH.md | Admin seed proof, roles, pd1 invites, redeem/revoke (full model) |
| HOLESAIL.md | Data-plane tunnels in depth |
| THREAT_MODEL.md | Assets, adversaries, controls, hardening checklist |
| RELEASE.md | Host matrix, Bare + Electron builds, rolling CI |
| SBOM.md | SBOM generation and license notes |
Product planning
| Document | What you will learn |
|---|---|
| ../ROADMAP.md | Feature tracks and status |
| ../README.md | Project overview and quick start |
One-picture overview
flowchart TB
subgraph ClientHost["Operator machine"]
UI["Desktop UI<br/>index.html + ui/ + libs/"]
CM["ConnectionManager<br/>client/manager.js"]
CONN["PearDockConnection<br/>client/connection.js"]
HL["Holesail local client<br/>client/holesailLocal.js"]
UI --> CM --> CONN
UI --> HL
end
subgraph Network["Holepunch network"]
DHT["HyperDHT<br/>discovery + Noise stream"]
end
subgraph ServerHost["Docker host"]
SRV["server/server.js<br/>DHT createServer"]
PS["PeerSession<br/>protomux-rpc"]
H["handlers/*"]
DK["dockerode → dockerd"]
HS["HolesailServer<br/>services/holesail-tunnels.js"]
SRV --> PS --> H --> DK
H --> HS
end
CONN -->|"dial public key"| DHT
DHT --> SRV
HL -.->|"hs:// data plane"| HS
HS --> PORT["127.0.0.1:published-port"]
Mental model in five minutes
1. Identity is a keypair, not a topic
The server derives a HyperDHT keypair from SERVER_SEED (persisted in .env). Clients dial the 64-character public key. This replaced v1’s Hyperswarm “topic = seed” model.
2. Control plane is structured RPC
Once the Noise-encrypted stream is up, both sides speak protomux-rpc with protocol id peardock/rpc. The client calls methods (listContainers, deployStack, …). The server may push channels (push:containers, push:allStats, push:logs, …).
3. Docker stays on the server host
All Engine access goes through dockerode on the machine running peardock-server (typically the Unix socket). The client never holds the Docker socket.
4. Two planes
| Plane | Path | Purpose |
|---|---|---|
| Control | HyperDHT + protomux-rpc | Manage Docker, ACL, audit, live UI |
| Data | Holesail hs:// |
Tunnel published TCP/UDP ports without firewall holes |
5. Capabilities are gated by role
Every method has a minimum role in MethodRoles (viewer < operator < admin). Unknown methods default to admin. Default peer role is viewer (read-only); elevate with admin seed proof, HMAC capability (pd1. invite), PEARDOCK_ADMIN_KEYS, or PEARDOCK_INSECURE_OPEN_ADMIN=1 for single-operator dev.
Connection lifecycle
sequenceDiagram
participant C as Desktop client
participant DHT as HyperDHT
participant S as peardock-server
participant D as dockerd
S->>DHT: listen(keyPair)
Note over S: Print SERVER_PUBLIC_KEY
C->>DHT: connect(publicKey)
DHT-->>C: secret stream (Noise)
C->>S: protomux-rpc open
C->>S: handshake { protocolVersion, adminProof? | capability? }
S-->>C: { peerId, role, protocolVersion, auth.mode }
C->>S: listContainers / deploy / …
S->>D: dockerode API
D-->>S: result
S-->>C: RPC response
S-->>C: push:containers / push:allStats / …
Client reconnect: ConnectionManager retries every 5 seconds (configurable) after unexpected drops until success or intentional disconnect. Last active peer is restored from disk cache (~/.config/peardock style paths via peerCache.js).
Repository layout (summary)
peardock/
├── shared/ # Protocol + encodings + arg schema (both sides)
├── server/ # HyperDHT control plane + dockerode
│ ├── server.js # Process entry
│ ├── core/ # Keys, ACL, audit, peer policy, vault crypto
│ ├── rpc/ # PeerSession, handler registration, binary streams
│ ├── handlers/ # One module per domain
│ ├── services/ # Docker client, events, stats, tunnels, schedules
│ └── utils/ # Logger, rate limit, compose, validation
├── client/ # Connection stack used by the UI
├── ui/ + libs/ # Desktop presentation + helpers
├── electron/ # Packaged Electron main / preload / OTA
├── index.js # Pear entry (pear-electron + holesail Bare control)
├── index.html # App shell markup
├── scripts/ # install.sh, make, rolling release, soak
├── deploy/ # systemd unit
├── test/ # brittle tests
└── docs/ # You are here
Full module-by-module guide: CODEBASE-MAP.md.
Runtime topologies
flowchart LR
subgraph Dev["Development"]
N1["node server/server.js"]
E1["npm run start:client<br/>Electron"]
P1["npm run dev<br/>Pear"]
end
subgraph Prod["Production package"]
B["peardock-server<br/>Bare binary"]
EC["peardock-client<br/>Electron app"]
SYS["systemd peardock.service"]
SYS --> B
end
E1 --> N1
P1 --> N1
EC --> B
| Mode | Server | Client |
|---|---|---|
| Dev | npm run server |
npm run start:client or npm run dev |
| Package | /opt/peardock/peardock-server |
Rolling Electron tarball / .app |
| Installer | install.peardock.boats → systemd + binary |
same script --client |
Feature flags at a glance
| Flag | Default | Surface |
|---|---|---|
ENABLE_HOLESAIL |
on | Tunnel RPC + Holesail servers |
ENABLE_SWARM |
on | Swarm services/nodes/tasks/secrets/configs |
ENABLE_PLUGINS |
off | Plugin install/enable/remove |
PEARDOCK_DEFAULT_ROLE |
admin |
Role for unknown peers |
PEARDOCK_PEER_ALLOWLIST |
off | Require registered peers |
PEARDOCK_AUDIT |
off | Append-only privileged audit log |
Details: OPERATOR.md, THREAT_MODEL.md.
Security snapshot
flowchart TB
PK["Knows public key"] --> DIAL["Can dial DHT"]
DIAL --> HS["handshake"]
HS --> AUTH{"Auth mode"}
AUTH -->|pubkey only| VIEW["viewer"]
AUTH -->|adminProof seed| ADMIN["admin"]
AUTH -->|capability / pd1 invite| CAP["grant role"]
VIEW --> MR["MethodRoles check"]
ADMIN --> MR
CAP --> MR
MR --> RL["Rate limiter"]
RL --> SCH["schema validateMethodArgs"]
SCH --> HND["Handler → dockerode"]
HND --> AUD["Audit if privileged"]
Hardening checklist and residual risks: THREAT_MODEL.md.
How to read this docs set
- New to PearDock? Start with this page + ARCHITECTURE.md, then OPERATOR.md.
- Implementing a feature? CODEBASE-MAP.md → domain handler under
server/handlers/→ method inshared/protocol.js→ client helper inclient/api.js→ UI inui/orlibs/. - Debugging connectivity? PROTOCOL.md handshake + CLIENT-UI.md reconnect + server logs (
LOG_FORMAT=json). - Tunnels? HOLESAIL.md + FEATURES.md.
- Shipping binaries? RELEASE.md.
Conventions used in these docs
- Paths are repo-relative unless noted.
- “Server” means the HyperDHT control-plane process (
server/server.jsor Barepeardock-server). - “Client” means the desktop app stack (
client/+ UI), packaged as Electron or run under Pear. - Mermaid diagrams render on GitHub, Gitea, and many IDEs; if not, the surrounding text still stands alone.
- Public website HTML under peardock-website is a mirror of operator docs, not the source of truth for code architecture. This
docs/tree is the code documentation.
Keeping docs honest
When you change behavior, update:
shared/protocol.js(Methods,MethodRoles,Pushes,PROTOCOL_VERSION)- The matching handler + any client API wrapper
- The relevant file in
docs/(especially PROTOCOL, FEATURES, SERVER, CLIENT-UI) - Root
README.mdif install/flags/scripts changed - Website legal/docs only if product claims change
Last aligned with codebase layout and protocol as of peardock 2.0.1 / PROTOCOL_VERSION 2.