Raven Scott ac8419029d
Release rolling / release (push) Successful in 9m3s
Fix CPU and memory usage display in containers table
Parse Docker stats streams as NDJSON so samples actually land, ship
memory limit for accurate bars, keep CPU/Memory columns visible with a
compact stacked meter, and match stats updates to table rows reliably.
2026-07-11 17:26:49 -04:00
CI
2026-07-11 11:39:59 -04:00
2026-07-11 12:58:31 -04:00
2024-12-03 01:00:56 -05:00
2025-11-24 15:17:04 -05:00
CI
2026-07-11 11:39:59 -04:00
2026-07-11 12:26:16 -04:00

PearDock

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

Interactive installer — detects OS/arch, asks server vs client, installs a Linux systemd service for the server or a desktop client for your platform:

curl -fsSL https://git.ssh.surf/snxraven/peardock/raw/branch/main/scripts/install.sh | bash

Non-interactive examples:

# Server (Linux systemd → peardock.service)
curl -fsSL https://git.ssh.surf/snxraven/peardock/raw/branch/main/scripts/install.sh | bash -s -- --server --yes

# Desktop client only
curl -fsSL https://git.ssh.surf/snxraven/peardock/raw/branch/main/scripts/install.sh | bash -s -- --client --yes

Downloads artifacts from the rolling release (peardock-server-* / peardock-client-*).

1. Install from source

npm install
# Node.js ≥ 20 required

2. Run the server (machine with Docker)

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):

# macOS
export PATH="$HOME/Library/Application Support/pear/bin:$PATH"
# make permanent in fish:
# fish_add_path "$HOME/Library/Application Support/pear/bin"

Then:

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 / pear-runtime.

Production Pear app

pear stage .
pear release .
pear run pear://<your-app-key>

Standalone binaries (CI / release)

64-bit only: linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64, win32-arm64.

# Everything CI ships (cross-compile server + client for all hosts)
npm run make

# Or one target:
npm run make:server:linux-x64
npm run make:client:win32-arm64
# → out/peardock-server-<host>/  and  out/peardock-<platform>-<arch>/

Gitea CI (Ubuntu) cross-builds all of those hosts and publishes tag rolling (secret RELEASE_TOKEN). See docs/RELEASE.md.


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
assets/           App logos + favicons (from peardock-branding/)
build/icon.*      Electron package icons (.png / .icns / .ico)
peardock-branding/ Master brand package (source of truth)

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. Processsystemd / 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 hs:// keys (separate from control-plane RPC). Opt out with ENABLE_HOLESAIL=0. See docs/HOLESAIL.md. Note: the required holesail dependency is AGPL-3.0.

Example systemd unit:

[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

S
Description
No description provided
Readme AGPL-3.0
79 MiB
Languages
JavaScript 74.5%
CSS 12.3%
HTML 11.8%
Shell 1.4%