snxraven 5a86103a9a
Rolling release / build ubuntu (servers + linux clients) (push) Has been cancelled
Rolling release / build client darwin-arm64 (push) Has been cancelled
Rolling release / build client win32-x64 (push) Has been cancelled
Rolling release / Publish rolling + OTA deploy bundles (push) Has been cancelled
Rolling release / Pear stage OTA channels (push) Has been cancelled
CI / test (push) Has been cancelled
Configure Pear OTA channels, stage/seed scripts, and CI deploy artifacts
Create real pear:// links for server/client/shared, bootstrap stage them,
add config/ota.json and ota-stage/seed tooling, attach OTA deploy zips in
rolling release CI, and document the full flow in docs/OTA.md.
2026-07-11 01:08:40 -04:00
2024-12-03 01:00:56 -05:00
2025-11-24 15:17:04 -05:00
2026-07-10 20:04:47 -04:00

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

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

Binary Kind Command
peardock-server Bare standalone (all modules embedded) npm run make:server:linux-x64
peardock-client Full Pear GUI (Electron; same UI as pear run) npm run make:client
npm ci
npm run make:server:linux-x64
# → out/server/linux-x64/peardock-server

npm run make:client
# → out/peardock-linux-x64/peardock-client  (+ AppImage/zip under out/make/)

./out/server/linux-x64/peardock-server
./out/peardock-linux-x64/peardock-client   # full desktop app

Dev UI (unchanged):

npm run dev            # pear run -d .
npm run start:client   # Electron shell of the same GUI

Gitea CI publishes a rolling release (RELEASE_TOKEN) plus OTA deploy zips. Pear P2P OTA channels are configured in config/ota.json.

npm run ota:check      # show upgrade links
npm run deploy:dir     # assemble deploy/{server,client,shared}
npm run ota:stage      # pear stage (needs pear write keys)
npm run ota:seed       # keep seeders online

See docs/OTA.md and 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

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%