Update docs
Release rolling / release (push) Successful in 7m40s

This commit is contained in:
Raven Scott
2026-07-16 04:47:12 -04:00
parent 67dffcadb8
commit 984a5e1e95
9 changed files with 195 additions and 66 deletions
+7 -3
View File
@@ -116,11 +116,14 @@ Pear may print `DEPRECATED: pear run is deprecated` (platform-wide). For day-to-
## What you get
- **Full Engine surface** over P2P: containers, images, volumes, networks, compose stacks, logs, stats, terminals, prune, schedules, registry vault
- **Full Engine surface** over P2P: containers, images, volumes, networks, compose stacks, logs, stats, terminals, prune, schedules
- **Registry vault + browser**: encrypted credentials, Hub search, remote catalog/tags/manifests, pull/push with vault auth
- **Image update indicators** on containers (digest vs remote tag) with **Check updates** in the job tray
- **Deploy templates** (Portainer-compatible container + stack templates) and blank **Add container** create form
- **Docker Swarm** UI and RPC (services, nodes, tasks, secrets, configs, scale). On by default; set `ENABLE_SWARM=0` to disable
- **Holesail tunnels** for published ports without firewall holes. On by default; set `ENABLE_HOLESAIL=0` to disable. See [docs/HOLESAIL.md](docs/HOLESAIL.md)
- **Roles**: `viewer` / `operator` / `admin` (default **viewer**; admin via seed proof or pd1. invite)
- **Multi-peer fleet** in one desktop client with reconnect and job tray
- **Multi-peer fleet** in one desktop client with reconnect and a multi-step **job tray** (hybrid image pull progress)
- **Standalone binaries** for six 64-bit hosts (server Bare + client Electron)
---
@@ -140,9 +143,10 @@ client/
connection.js Single HyperDHT + protomux-rpc link
manager.js Multi-server connections + persistence
api.js Typed RPC helpers
jobs.js Job tray model + hybrid pull progress helpers
holesailLocal.js Local Holesail client (data plane)
electron/ Electron main / packaged desktop shell
ui/ + app.js + libs/ Desktop UI
ui/ + app.js + libs/ Desktop UI (deploy, registry, add-container, …)
assets/ Logos + favicons
peardock-branding/ Master brand package
deploy/ systemd unit
+4 -3
View File
@@ -74,7 +74,8 @@ flowchart TB
API[client/api.js]
MGR[client/manager.js]
CON[client/connection.js]
JOB[client/jobs.js]
JOB[client/jobs.js + jobActions + pullProgress]
TPL[client/templateResolve.js]
CACHE[client/peerCache.js]
end
@@ -219,7 +220,7 @@ flowchart TB
- Disk-backed peer list + last active id.
- Switching peers rebinds UI subscriptions to the active connections pushes.
- Jobs (`client/jobs.js`) track long ops (pull, deploy, build) with step logs.
- Jobs (`client/jobs.js` + `client/jobActions.js`) track long ops (pull, deploy, build, bulk lifecycle, prune) with step logs and hybrid image-pull progress (`client/pullProgress.js`).
---
@@ -323,7 +324,7 @@ Files (server data dir / cwd):
## Protocol versioning
- Constant: `PROTOCOL_VERSION` in `shared/protocol.js` (currently **2**).
- Constant: `PROTOCOL_VERSION` in `shared/protocol.js` (currently **3** — HMAC auth handshake with capability + adminProof).
- Negotiated in `handshake`.
- **Bump** when breaking RPC argument/result shapes.
- Additive methods may land without a bump if clients ignore unknowns.
+47 -10
View File
@@ -45,10 +45,15 @@ flowchart TB
- **Reconnect**: every **5s** after unexpected drop (unlimited by default).
- Persists peers via `peerCache.js`.
- Restores last active peer on launch.
- Longer timeouts for slow methods (`checkImageUpdates`, `deployStack`, pulls).
### `client/api.js`
Thin typed wrappers around `Methods.*` for UI code (e.g. `listContainers`, `createTunnel`, `swarmInspect`).
Thin typed wrappers around `Methods.*` for UI code (e.g. `listContainers`, `checkImageUpdates`, `createTunnel`, `swarmInspect`).
### `client/identity.js`
Stable client DHT keypair helpers for reconnect identity.
---
@@ -61,11 +66,34 @@ Thin typed wrappers around `Methods.*` for UI code (e.g. `listContainers`, `crea
Location: config directory suitable for the runtime (XDG / Pear storage / Electron userData depending on path helpers).
Client saved hosts are edited under **Settings → Peers** (not a top-level sidebar item). Server ACL / invites live under **Access**.
---
## Jobs
## Jobs and job tray
`client/jobs.js` models multi-step operations (pull, deploy, build) for the **job drawer** in the UI: progress, logs, success/failure.
Long-running Docker ops use a multi-step **job tray** (activity panel) instead of only status toasts.
| Module | Role |
|--------|------|
| `client/jobs.js` | Job model: create/run, steps, logs, progress, rAF-coalesced paints, card rendering |
| `client/jobActions.js` | Preferable entry for bulk lifecycle, recreate, image remove/push/build, prune, stack remove, single-container actions |
| `client/pullProgress.js` | Aggregates Docker layer pull/push events into hybrid phase/%/bytes + fixed-height layer track |
Typical jobs: pull/push image, deploy container, add container, deploy stack (validate → pull images → compose up), check image updates, bulk start/stop/remove, prune.
Stack deploy job steps: `ui/ops-app.js``deployStackWithSteps`.
---
## Templates
| Module | Role |
|--------|------|
| `client/templateLists.js` | Catalog list URLs / sources |
| `client/templateResolve.js` | Portainer type 1 (container) vs 2/3 (stack): fetch stackfile, parse compose, pick app service, merge into form shape |
| `libs/templateDeploy.js` | Deploy form, full Portainer field mapping, Duplicate/Edit modal |
| `libs/addContainer.js` | Blank create form from Containers toolbar |
---
@@ -77,34 +105,39 @@ Sidebar `data-view="…"` sections, including:
| View | Purpose |
|------|---------|
| containers | Table + details, lifecycle actions; **Add container** header button |
| containers | Table + details, lifecycle actions; **Add container** + **Check updates** in toolbar/action bar |
| add-container | Blank create form (always-pull, ports, advanced); not in sidebar |
| images | Local engine images (pull/push/build/prune) |
| registry | Vault, Hub search, remote catalog/tags/manifests/delete |
| networks / volumes | Resource management |
| stacks | Compose projects |
| stacks | Compose projects + stack deploy form (job tray) |
| deploy | Templates + container configuration form |
| swarm | Services, nodes, tasks, secrets, configs |
| tunnels | Holesail create/list/close |
| host | System info / df / maintenance |
| access | Server peer ACL, invites, vault quick-store |
| settings | Prefs + **Peers** subtab (client saved hosts) |
| access | Server peer ACL, invites, revoke list |
| settings | Prefs, **Peers** subtab (client saved hosts), **hidden-container label filters** |
### Controllers
| Module | Role |
|--------|------|
| `ui/ops-app.js` | View loading, Swarm tables, tunnels, settings, connect hooks |
| `ui/ops-app.js` | View loading, Swarm tables, tunnels, settings (hidden labels), connect hooks, stack deploy steps |
| `ui/track-g-ux.js` | Keyboard shortcuts (`g` then key), command palette, go-map |
| `ui/track-f-extras.js` | Extra polish features |
| `libs/templateDeploy.js` | Deploy form / templates (large) |
| `libs/addContainer.js` | Add container blank create form |
| `libs/registryManager.js` | Registry view: vault, browser, pull/push helpers |
| `libs/terminal.js` etc. | xterm integration |
| `app.js` | Large shell glue: tables, container details, image-update column, list filtering |
### Settings: hide containers by label
Stored in client settings (`hiddenContainerLabels`): array of `{ name, value? }`. Empty `value` matches any value for that label key. Applied when rendering the containers list (client-side only).
### Auto-refresh
When a view is active, silent polls refresh lists (e.g. Swarm fingerprint skip if unchanged).
When a view is active, silent polls refresh lists (e.g. Swarm fingerprint skip if unchanged). Logs re-follow correctly after leaving and returning to the Logs tab.
---
@@ -153,7 +186,7 @@ OTA helpers: `electron/ota.cjs`. Preload isolates privileged APIs.
- Map RPC codes to human messages.
- Background methods may soft-fail without modal spam.
- Job tray owns multi-step failure UX.
- Job tray owns multi-step failure UX (title, message, recovery).
---
@@ -174,6 +207,10 @@ Server env flags do not automatically apply to the client; the server enforces f
- `test/peer-cache.test.js`
- `test/holesail-local.test.js`
- `test/visual-structure.test.js` (critical `index.html` ids)
- `test/template-resolve.test.js`
- `test/pull-progress.test.js`
- `test/image-updates.test.js`
- `test/registry-client.test.js`
- `test/terminal-shells.test.js`
- `test/feedback.test.js` / `errors.test.js`
+34 -18
View File
@@ -70,9 +70,10 @@ flowchart LR
| File | Role |
|------|------|
| `protocol.js` | `PROTOCOL`, `PROTOCOL_VERSION`, `Roles`, `MethodRoles`, `Methods`, `Pushes`, `roleAllows()` |
| `protocol.js` | `PROTOCOL`, `PROTOCOL_VERSION` (**3**), `Roles`, `MethodRoles`, `Methods`, `Pushes`, `roleAllows()` |
| `encodings.js` | compact-encoding setup for protomux-rpc value codec |
| `schema.js` | `validateMethodArgs()` lightweight arg validation + `SCHEMA_VERSION` |
| `crypto-auth.js` | HKDF + HMAC for admin seed proof and pd1. capability grants |
**Rule:** any new RPC method needs:
@@ -105,7 +106,9 @@ Process bootstrap:
| `audit.js` | Privileged method audit log append |
| `peer-policy.js` | Invites, allowlist, revoke, redeem invite |
| `peer-registry.js` | Live connected sessions map |
| `registry-vault.js` | AES-GCM credential crypto helpers |
| `registry-vault.js` | AES-GCM credential crypto helpers (Bare-safe KDF; no Node-only scryptSync) |
| `auth-keys.js` | Auth key material helpers for seed/capability verification |
| `connection-invites.js` | Connection invite packaging helpers (pd1. flow) |
### `server/rpc/`
@@ -119,20 +122,21 @@ Process bootstrap:
| File | Domain |
|------|--------|
| `containers.js` | list/start/stop/inspect/exec/… |
| `images.js` | pull/push/build/prune/search/load/save |
| `containers.js` | list/start/stop/inspect/exec/…; graceful stop-then-remove; `checkImageUpdates` |
| `images.js` | pull/push/build/prune/search/load/save (vault `credentialId`) |
| `networks.js` | network CRUD + connect/disconnect |
| `volumes.js` | volume CRUD + browse |
| `stacks.js` | compose stacks, ps, logs, git sync |
| `deploy.js` | high-level `deployContainer` / deploy flows |
| `stacks.js` | compose stacks, ps, logs, git sync; remove removes project networks |
| `deploy.js` | high-level `deployContainer` / always-pull / deploy flows |
| `terminal.js` | interactive shells (multi-shell probe) |
| `logs.js` | log streams |
| `logs.js` | log streams (re-follow safe across tab switches) |
| `docker-cli.js` | allow-listed docker CLI passthrough |
| `system.js` | info, df, prune, metrics, schedules, browse host |
| `swarm.js` | Swarm mode APIs (`ENABLE_SWARM`) |
| `plugins.js` | Engine plugins (`ENABLE_PLUGINS`) |
| `peers.js` | list/invite/revoke/role |
| `vault.js` | registry credential vault RPC |
| `vault.js` | registry credential vault RPC (store/use/test/session) |
| `registry.js` | Remote Registry HTTP API V2 browser (catalog/tags/manifest/delete) |
| `tunnels.js` | Holesail tunnel RPC |
| `suggestions.js` | smart defaults for deploy UI |
@@ -140,13 +144,15 @@ Process bootstrap:
| File | Role |
|------|------|
| `docker.js` | Shared dockerode instance / socket |
| `docker.js` | Shared dockerode instance / socket; timed raw stop/kill/delete helpers |
| `events.js` | Docker event stream → pushes |
| `stats.js` | Periodic stats broadcast |
| `stats-history.js` | In-memory stats history for charts |
| `metrics.js` | Process + RPC metrics |
| `holesail-tunnels.js` | Create/list/close/restore Holesail servers |
| `schedules.js` | Persisted scheduled maintenance jobs |
| `image-updates.js` | Compare local `RepoDigest` to remote registry manifests |
| `registry-client.js` | Registry HTTP V2 client (auth, catalog, tags, manifests, delete) |
### `server/utils/`
@@ -154,9 +160,9 @@ Process bootstrap:
|------|------|
| `logger.js` | Structured pretty/json logger + banner |
| `rateLimiter.js` | Per-peer method rate limits; stream hot methods |
| `validation.js` | Shared validation helpers |
| `validation.js` | Shared validation helpers (deploy/duplicate configs) |
| `dockerErrors.js` | Sanitize Docker errors for clients |
| `composeManager.js` | Compose file deploy orchestration |
| `composeManager.js` | Compose deploy/up; **remove** tears down project networks (`compose down` parity) |
| `containerConfig.js` | Normalize create/deploy options |
| `engine-capabilities.js` | Probe what Engine supports |
| `gitops.js` | Git pull for stack sync |
@@ -172,12 +178,16 @@ Process bootstrap:
| `manager.js` | Multi-peer manager, active peer, reconnect loop |
| `api.js` | Typed `request` wrappers for Methods |
| `peerCache.js` | Persist peers + last active to disk |
| `jobs.js` | Long-running job tray model |
| `identity.js` | Client DHT identity helpers |
| `jobs.js` | Job tray model: steps, logs, hybrid progress, rAF-coalesced UI |
| `jobActions.js` | Multi-step tray actions (bulk lifecycle, pull/push, prune, stacks, …) |
| `pullProgress.js` | Aggregate Docker layer pull/push events → hybrid tray snapshot |
| `templateResolve.js` | Portainer type 1/2/3 template → form/stack resolve (compose fetch) |
| `templateLists.js` | Template catalog lists |
| `errors.js` | Normalize RPC errors for UI |
| `holesailLocal.js` | Local hs:// client (HTTP to Bare control or in-process) |
| `holesailBareControl.cjs` | Bare-side real `holesail` control HTTP API |
| `snapshot.js` | UI snapshot helpers |
| `templateLists.js` | Template catalog lists |
| `index.js` | Small re-export surface |
```mermaid
@@ -190,6 +200,10 @@ flowchart TB
CON --> RPC[protomux-rpc]
MGR --> CACHE[peerCache.js]
UI --> JOBS[jobs.js]
UI --> JA[jobActions.js]
JA --> JOBS
JA --> PP[pullProgress.js]
UI --> TR[templateResolve.js]
UI --> HS[holesailLocal.js]
```
@@ -201,18 +215,20 @@ flowchart TB
| File | Role |
|------|------|
| `ops-app.js` | Main ops controller: views, Swarm, tunnels, host, settings hooks |
| `ops-app.js` | Main ops controller: views, Swarm, tunnels, host, settings (incl. hidden-label filters), stack deploy job steps |
| `track-g-ux.js` | Keyboard shortcuts, go-to view map, command palette pieces |
| `track-f-extras.js` | Additional UI extras from roadmap track F |
| `track-f-extras.js` | Additional UI extras |
| `components.js` | Shared UI components |
| `modern.css` / `ops.css` / `styles.css` | Styling layers |
| `modern.css` / `ops.css` / `styles.css` | Styling layers (tables, job tray, deploy cards) |
### `libs/`
| File | Role |
|------|------|
| `templateDeploy.js` | Large deploy/template wizard logic |
| `templateDeploy.js` | Deploy/template wizard; Portainer field mapping; Duplicate/Edit modal |
| `templateStorage.js` | Template persistence |
| `addContainer.js` | Blank **Add container** create form (always-pull, ports, advanced) |
| `registryManager.js` | Registry view: vault, Hub search, remote catalog/tags/manifests |
| `terminal.js` / `dockerTerminal.js` / `xtermUtils.js` / `termInput.js` | Terminal UX |
| `notifications.js` | Toasts / activity |
| `uiUtils.js` | DOM helpers, job stepper integration |
@@ -220,7 +236,7 @@ flowchart TB
### `index.html`
Single-page app shell: sidebar views (containers, images, networks, volumes, stacks, deploy, Swarm, tunnels, host, peers, settings, …), modals, job drawer, toast stack.
Single-page app shell: sidebar views (containers, images, **registry**, networks, volumes, stacks, deploy, Swarm, tunnels, host, **access**, settings, …), add-container page, modals, **job tray** / activity panel, toast stack. Client saved hosts live under **Settings → Peers** (not a top-level sidebar item).
---
+41 -5
View File
@@ -12,7 +12,8 @@ What PearDock can do today, mapped to code and protocol surfaces.
| Image pull/build/load/save | shipped | on | `handlers/images.js` |
| Networks / volumes | shipped | on | `handlers/networks.js`, `volumes.js` |
| Compose stacks + GitOps | shipped | on | `handlers/stacks.js`, `utils/gitops.js` |
| Deploy templates UI | shipped | on | `libs/templateDeploy.js` |
| Deploy templates UI | shipped | on | `libs/templateDeploy.js`, `client/templateResolve.js` |
| Image update indicators | shipped | on | `services/image-updates.js`, containers UI |
| Logs follow | shipped | on | `handlers/logs.js` |
| Interactive terminals | shipped | on | `handlers/terminal.js` |
| Multi-shell probe | shipped | on | terminal handler + tests |
@@ -21,6 +22,7 @@ What PearDock can do today, mapped to code and protocol surfaces.
| System prune / df / info | shipped | on | `handlers/system.js` |
| Schedules | shipped | on | `services/schedules.js` |
| Registry vault | shipped | on | `handlers/vault.js`, `core/registry-vault.js` |
| Registry browser (V2 API) | shipped | on | `handlers/registry.js`, `services/registry-client.js` |
| Peer invites / revoke / roles | shipped | on | `handlers/peers.js`, `core/peer-policy.js` |
| Audit log | shipped | opt-in env | `core/audit.js` |
| Holesail tunnels | shipped | **on** | `handlers/tunnels.js`, `services/holesail-tunnels.js` |
@@ -30,7 +32,8 @@ What PearDock can do today, mapped to code and protocol surfaces.
| Binary streams | shipped | on | `rpc/binary-stream.js` |
| Multi-peer fleet UI | shipped | on | `client/manager.js` |
| Auto-reconnect 5s | shipped | on | `client/manager.js` |
| Job tray | shipped | on | `client/jobs.js` |
| Job tray + hybrid pull progress | shipped | on | `client/jobs.js`, `jobActions.js`, `pullProgress.js` |
| Hidden containers by label | shipped | on | Settings → label filters (`ui/ops-app.js`) |
| Keyboard UX | shipped | on | `ui/track-g-ux.js` |
| Rolling binaries | shipped | CI | `scripts/gitea-rolling-release.sh` |
| One-line installer | shipped | public | `scripts/install.sh` |
@@ -42,11 +45,15 @@ What PearDock can do today, mapped to code and protocol surfaces.
**UI:** Containers view + detail pane + **Add container** page (header button).
**RPC:** list/inspect/start/stop/restart/kill/pause/unpause/remove/recreate/rename/update/deploy/bulk/top/stats/logs/exec/attach/commit/export/archive/duplicate/prune.
**Image update indicators** (style): **Updates** column compares each containers local image `RepoDigest` to the remote registry manifest digest for the same tag. Green check = up to date, orange up-arrow = update available (click to pull), grey dash = unknown/skipped. **Check updates** forces a recheck. Server caches digests (~5m). Uses vault credentials for private registries. RPC: `checkImageUpdates`.
**Image update indicators** (style): **Updates** column compares each containers local image `RepoDigest` to the remote registry manifest digest for the same tag. Green check = up to date, orange up-arrow = update available (click to pull), grey dash = unknown/skipped. **Check updates** lives in the containers action bar and reports results in the **job tray**. Server caches digests (~5m). Uses vault credentials for private registries. RPC: `checkImageUpdates`.
**Add container** (`#add-container-view`, `libs/addContainer.js`) is a blank create form separate from **Deploy** templates: name, image, **Always pull the image**, ports (manual + publish-all-exposed), auto-remove, and advanced sections (command, volumes, network, env, labels, restart, runtime/resources). Submit uses `deployContainer` via the job tray.
**Duplicate / Edit** (`#duplicateModal`, `libs/templateDeploy.js`) reuses the same deploy path with a full config editor (name, image, **Always pull the image**, ports, volumes, env, resources, security, health, etc.). When always-pull is off, the server uses a local image if present.
**Duplicate / Edit** (`#duplicateModal`, `libs/templateDeploy.js`) reuses the same deploy path with a full config editor (name, image, **Always pull the image**, ports, volumes, env, resources, security, health, etc.). Cloning preserves volumes/settings correctly. When always-pull is off, the server uses a local image if present.
**Remove** stops the container gracefully (short grace period, then kill fallback) before delete, with timed raw Docker operations so force-remove cannot hang the RPC.
**Hidden by label** (Settings): global filters `{ name, value? }` hide matching containers from the containers list (empty value matches any value for that label key). Client-side only; does not affect the Engine.
Deploy templates form remains under the Deploy tab for catalog-driven deploys.
@@ -93,9 +100,24 @@ Full CRUD for operators/admins per role table. Volume browse for inspecting file
## Stacks / Compose
- Deploy compose content (+ override, env file, profiles, build).
- Deploy compose content (+ override, env file, profiles, build) via **Stacks** UI and job-tray steps: validate → pull images (hybrid progress) → `compose up` (`ui/ops-app.js` `deployStackWithSteps`).
- List stacks, `ps`, logs, pull.
- `syncStackFromGit` for GitOps-style refresh (`utils/gitops.js`).
- **Remove stack** tears down project containers **and project-scoped networks** (compose `down` parity — volumes are kept). Built-in Docker networks are never removed.
---
## Deploy templates (Portainer-compatible)
**UI:** Deploy view + template catalog (`libs/templateDeploy.js`, `client/templateLists.js`, `client/templateResolve.js`).
| Template type | Behavior |
|---------------|----------|
| Type 1 — container | Maps Portainer fields (image, ports, volumes, env, restart, command, labels, …) into the deploy form |
| Type 2 / 3 — stack | Resolves Git repository + stackfile, fetches compose, picks primary app service, merges into form or stack deploy path |
| Long descriptions | Truncated in the catalog so the Deploy action stays on-screen |
Stack templates without a top-level `image` resolve compose from the repo so the form is not left empty.
---
@@ -144,6 +166,20 @@ See [HOLESAIL.md](./HOLESAIL.md).
---
## Job tray
Long-running ops report in a dedicated **job tray** (activity panel), not only toasts:
| Piece | Role |
|-------|------|
| `client/jobs.js` | Job model, steps, logs, progress patches, UI rendering |
| `client/jobActions.js` | Bulk container ops, recreate, image remove/push/build, prune, stack remove, … |
| `client/pullProgress.js` | Per-layer Docker pull/push aggregation → hybrid % + layer track |
Used by: image pull/push, container deploy/add, stack deploy, check-updates, bulk lifecycle, prune, and related ops.
---
## Observability
- Live stats push for container CPU/memory.
+13 -4
View File
@@ -120,14 +120,17 @@ PEARDOCK_AUDIT=1
See [SECURITY_AUTH.md](./SECURITY_AUTH.md) for the full auth and invite model, and [THREAT_MODEL.md](./THREAT_MODEL.md) for hardening rationale.
## Registry vault
## Registry vault and browser
Credentials encrypted at rest (AES-GCM derived from `SERVER_SEED`):
Credentials encrypted at rest (AES-GCM; KDF is Bare-safe — no Node-only `scryptSync`):
- UI: **Access → Registry vault**
- RPC: `vaultStoreCredential`, `vaultUseCredential`, `listVaultCredentials`
- UI: top-level **Registry** view (vault credentials, Docker Hub search, remote catalog/tags/manifests)
- RPC vault: `vaultStoreCredential`, `vaultUseCredential`, `vaultTestCredential`, `vaultClearSession` / `registryLogout`, `listVaultCredentials`
- RPC browser: `registryCatalog`, `registryListTags`, `registryGetManifest`, `registryDeleteTag(s)`, `registryNormalizeEndpoint`
- File: `peardock-vault.json` (mode 600). Override with `PEARDOCK_VAULT_PATH`.
Pull/push from **Images** and the registry browser can select a vault credential for private registries.
## Feature flags
| Env | Effect |
@@ -171,6 +174,12 @@ sudo journalctl -u peardock -f
- `profiles`: array or comma string
- `build: true`: runs `docker compose up --build`
The desktop **Stacks** view deploys through the job tray (validate → optional image pulls → compose up). **Remove stack** deletes project containers and project-scoped networks (volumes are kept), matching `docker compose down` network behavior.
## Image update checks
Containers list can show whether a newer image digest is available for the running tag (`checkImageUpdates`). **Check updates** in the action bar runs a recheck and reports in the job tray. Private registries use vault credentials. Digests are cached on the server (~5 minutes).
## Swarm
When Docker is in Swarm mode, the client **Swarm** view lists services, nodes, tasks, secrets, and configs, and can scale replicated services. Server RPC covers init/join/leave, service CRUD, scale, logs, nodes, tasks, secrets, and configs. Disable the whole surface with `ENABLE_SWARM=0`.
+18 -5
View File
@@ -127,10 +127,12 @@ Below is a **catalog** of `Methods` names. Minimum roles are in `MethodRoles` (s
| Method | Min role |
|--------|----------|
| `listContainers`, `inspectContainer`, `containerTop`, `containerStats`, `getStatsHistory`, `getContainerLogs` | viewer |
| `listContainers`, `inspectContainer`, `checkImageUpdates`, `containerTop`, `containerStats`, `getStatsHistory`, `getContainerLogs` | viewer |
| `startContainer`, `stopContainer`, `restartContainer`, `killContainer`, `pauseContainer`, `unpauseContainer`, `renameContainer`, `updateContainer`, `createContainer`, `deployContainer`, `bulkContainerOperation`, `waitContainer`, `attachContainer`, `attachInput`, `execContainer`, `execInput` | operator |
| `removeContainer`, `recreateContainer`, `commitContainer`, `exportContainer`, `duplicateContainer`, `pruneContainers`, `archiveContainerGet`, `archiveContainerPut` | admin |
`checkImageUpdates` compares local image digests to remote registry manifests (vault credentials for private hosts). `removeContainer` stops gracefully (short grace + kill fallback) before delete so force-remove does not hang.
### Images
| Method | Min role |
@@ -170,15 +172,26 @@ Below is a **catalog** of `Methods` names. Minimum roles are in `MethodRoles` (s
| Method | Min role |
|--------|----------|
| `listVaultCredentials` | viewer |
| `vaultUseCredential` | operator |
| `vaultStoreCredential`, `vaultDeleteCredential` | admin |
| `vaultUseCredential`, `vaultTestCredential`, `vaultClearSession` / `registryLogout` | operator |
| `vaultStoreCredential`, `vaultDeleteCredential`, `registryLogin` | admin |
### Remote registry browser (Registry HTTP API V2)
| Method | Min role |
|--------|----------|
| `registryCatalog`, `registryListTags`, `registryGetManifest`, `registryNormalizeEndpoint` | viewer |
| `registryDeleteTag`, `registryDeleteTags` | admin |
Uses vault credentials when the registry host matches a stored entry. Implemented in `handlers/registry.js` + `services/registry-client.js`.
### Peers / ACL
| Method | Min role |
|--------|----------|
| `listPeers`, `listInvites` | viewer |
| `invitePeer`, `revokePeer`, `unrevokePeer`, `setPeerRole` | admin |
| `listPeers` | viewer |
| `listInvites`, `invitePeer`, `deleteInvite`, `revokePeer`, `unrevokePeer`, `listRevokedPeers`, `clearRevokedPeers`, `setPeerRole` | admin |
Invite strings are secrets — `listInvites` is **admin only**.
### Terminals / logs streams
+10 -10
View File
@@ -1,6 +1,6 @@
# PearDock documentation
**Complete technical documentation for the peardock codebase (v2.x / protocol version 2).**
**Complete technical documentation for the peardock codebase (v2.x product / protocol version 3).**
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.
@@ -8,7 +8,7 @@ PearDock is **decentralized Docker management**: a HyperDHT control plane, struc
|--|--|
| **License** | [AGPL-3.0](../LICENSE) |
| **Package** | `peardock` **2.0.1** (`package.json`) |
| **Protocol** | `peardock/rpc` · `PROTOCOL_VERSION = 2` (`shared/protocol.js`) |
| **Protocol** | `peardock/rpc` · `PROTOCOL_VERSION = 3` (`shared/protocol.js`) |
| **Site** | [peardock.boats](https://peardock.boats) |
| **Install** | `curl -fsSL https://install.peardock.boats \| bash` |
| **Source** | [git.ssh.surf/snxraven/peardock](https://git.ssh.surf/snxraven/peardock) |
@@ -26,7 +26,7 @@ PearDock is **decentralized Docker management**: a HyperDHT control plane, struc
| **[PROTOCOL.md](./PROTOCOL.md)** | RPC methods, pushes, roles (`MethodRoles`), encodings, handshake |
| **[SERVER.md](./SERVER.md)** | Server boot, PeerSession middleware, handlers, services, persistence |
| **[CLIENT-UI.md](./CLIENT-UI.md)** | ConnectionManager, Electron vs Pear, UI views, jobs, local Holesail |
| **[FEATURES.md](./FEATURES.md)** | Feature catalog by domain (containers, Swarm, tunnels, vault, …) |
| **[FEATURES.md](./FEATURES.md)** | Feature catalog by domain (containers, registry, templates, Swarm, tunnels, vault, …) |
### Operating and shipping
@@ -140,16 +140,16 @@ sequenceDiagram
```
peardock/
├── shared/ # Protocol + encodings + arg schema (both sides)
├── shared/ # Protocol + encodings + schema + crypto-auth (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
│ ├── handlers/ # One module per domain (incl. registry, vault, stacks)
│ ├── services/ # Docker, events, stats, tunnels, image-updates, registry-client
│ └── utils/ # Logger, rate limit, compose, validation
├── client/ # Connection stack used by the UI
├── ui/ + libs/ # Desktop presentation + helpers
├── client/ # Connection stack, jobs, pull progress, template resolve
├── ui/ + libs/ # Desktop presentation + helpers (deploy, registry, add-container)
├── electron/ # Packaged Electron main / preload / OTA
├── index.js # Pear entry (pear-electron + holesail Bare control)
├── index.html # App shell markup
@@ -200,7 +200,7 @@ flowchart LR
| `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_DEFAULT_ROLE` | `viewer` | Role for unknown peers |
| `PEARDOCK_PEER_ALLOWLIST` | off | Require registered peers |
| `PEARDOCK_AUDIT` | off | Append-only privileged audit log |
@@ -261,4 +261,4 @@ When you change behavior, update:
4. Root `README.md` if install/flags/scripts changed
5. Website legal/docs only if product claims change
Last aligned with codebase layout and protocol as of peardock **2.0.1** / `PROTOCOL_VERSION` **2**.
Last aligned with codebase layout and protocol as of peardock **2.0.1** / `PROTOCOL_VERSION` **3**.
+21 -8
View File
@@ -80,7 +80,7 @@ Handlers/services call into the session to `rpc.event` / push helpers so all con
```
handshake, system, containers, images, networks, volumes,
stacks, deploy, terminal, logs, docker-cli, swarm, plugins,
peers, vault, binary-stream, suggestions, tunnels
peers, vault, registry, binary-stream, suggestions, tunnels
```
On session close: kill terminals, stop log follows, end exec streams, clear `session.state`.
@@ -89,7 +89,7 @@ On session close: kill terminals, stop log follows, end exec streams, clear `ses
## Docker access
`server/services/docker.js` exports a shared **dockerode** client (default socket).
`server/services/docker.js` exports a shared **dockerode** client (default socket), plus timed raw stop/kill/delete helpers used for reliable force-remove.
Operational requirement: process user must access the socket (installer uses user `peardock` + group `docker`).
@@ -113,6 +113,14 @@ Process memory, RPC counters, latency percentiles, feature flags. Exposed via `g
Persisted jobs (prune, etc.) restored at boot; admin upsert/delete via RPC.
### Image updates (`services/image-updates.js`)
Compares local image `RepoDigest` values to remote registry manifest digests (with vault credentials for private hosts). Cached ~5 minutes. Wired as `checkImageUpdates` in `handlers/containers.js`. Works on Bare (no Node-only registry APIs).
### Registry client (`services/registry-client.js`)
Registry HTTP API V2: catalog, tags, manifests, delete; used by `handlers/registry.js`.
### Holesail tunnels (`services/holesail-tunnels.js`)
- Feature flag `ENABLE_HOLESAIL`
@@ -151,23 +159,28 @@ flowchart LR
| Handler | Typical Engine surface |
|---------|------------------------|
| containers | ContainerLifecycle + exec/attach |
| images | Image pull/build/load/save |
| containers | Container lifecycle + exec/attach; graceful stop-then-remove; image update checks |
| images | Image pull/push/build/load/save (optional vault `credentialId`) |
| networks | Network API |
| volumes | Volume API + browse |
| stacks | Compose project ops + gitops |
| deploy | Opinionated container deploy |
| stacks | Compose project ops + gitops; remove drops project networks |
| deploy | Opinionated container deploy (`alwaysPull`) |
| terminal | Multiplexed interactive shells |
| logs | Log follow |
| logs | Log follow (safe re-subscribe) |
| docker-cli | Allow-listed CLI |
| system | info/df/prune/schedules/browse |
| swarm | Swarmkit APIs |
| plugins | Plugin APIs |
| peers | ACL administration |
| vault | Credential CRUD + use |
| vault | Credential CRUD + test + session |
| registry | Remote registry browser (V2 catalog/tags/manifest/delete) |
| tunnels | Holesail |
| suggestions | Deploy UX helpers |
### Compose manager (`utils/composeManager.js`)
Deploys compose projects and, on stack remove, removes project containers then **project-scoped networks** (compose `down` parity; volumes retained).
---
## Rate limiting