Quick start, operator, security, FAQ, download, home, and learn pages now point operators at /opt/peardock/.env for public key and seed, and document viewer / admin / pd1. invite roles.
581 lines
27 KiB
HTML
581 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||
<title>How PearDock Works · P2P Docker control</title>
|
||
<meta name="description" content="Learn how PearDock manages Docker over peer-to-peer HyperDHT. No open ports, no VPN, no public Docker API. Identity, hole punching, control plane, Holesail tunnels, and security." />
|
||
<meta name="keywords" content="PearDock P2P, HyperDHT, hole punching, Holesail, Docker control plane" />
|
||
<meta name="author" content="HoneyPeer, LLC" />
|
||
<meta name="robots" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
|
||
<meta name="googlebot" content="index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1" />
|
||
<meta name="theme-color" content="#2dd4bf" />
|
||
<meta name="color-scheme" content="dark light" />
|
||
<meta name="application-name" content="PearDock" />
|
||
<meta name="apple-mobile-web-app-title" content="PearDock" />
|
||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||
<meta name="mobile-web-app-capable" content="yes" />
|
||
<meta name="msapplication-TileColor" content="#2dd4bf" />
|
||
<meta name="msapplication-config" content="/assets/favicons/browserconfig.xml" />
|
||
<meta name="format-detection" content="telephone=no" />
|
||
<link rel="canonical" href="https://peardock.boats/learn/" />
|
||
<link rel="alternate" hreflang="en" href="https://peardock.boats/learn/" />
|
||
<link rel="alternate" hreflang="x-default" href="https://peardock.boats/learn/" />
|
||
|
||
<!-- Open Graph -->
|
||
<meta property="og:type" content="article" />
|
||
<meta property="og:site_name" content="PearDock" />
|
||
<meta property="og:locale" content="en_US" />
|
||
<meta property="og:url" content="https://peardock.boats/learn/" />
|
||
<meta property="og:title" content="How PearDock Works · P2P Docker control" />
|
||
<meta property="og:description" content="Learn how PearDock manages Docker over peer-to-peer HyperDHT. No open ports, no VPN, no public Docker API. Identity, hole punching, control plane, Holesail tunnels, and security." />
|
||
<meta property="og:image" content="https://peardock.boats/assets/brand/og-image.png" />
|
||
<meta property="og:image:secure_url" content="https://peardock.boats/assets/brand/og-image.png" />
|
||
<meta property="og:image:type" content="image/png" />
|
||
<meta property="og:image:width" content="1200" />
|
||
<meta property="og:image:height" content="630" />
|
||
<meta property="og:image:alt" content="PearDock: decentralized Docker management on HyperDHT" />
|
||
|
||
<!-- Twitter / X -->
|
||
<meta name="twitter:card" content="summary_large_image" />
|
||
<meta name="twitter:title" content="How PearDock Works · P2P Docker control" />
|
||
<meta name="twitter:description" content="Learn how PearDock manages Docker over peer-to-peer HyperDHT. No open ports, no VPN, no public Docker API. Identity, hole punching, control plane, Holesail tunnels, and security." />
|
||
<meta name="twitter:image" content="https://peardock.boats/assets/brand/twitter-card.png" />
|
||
<meta name="twitter:image:alt" content="PearDock: decentralized Docker management" />
|
||
|
||
<!-- Icons & PWA -->
|
||
<link rel="icon" href="/assets/favicons/favicon.ico" sizes="any" />
|
||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png" />
|
||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png" />
|
||
<link rel="icon" type="image/png" sizes="48x48" href="/assets/favicons/favicon-48x48.png" />
|
||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicons/apple-touch-icon.png" />
|
||
<link rel="manifest" href="/assets/favicons/site.webmanifest" />
|
||
<link rel="mask-icon" href="/assets/logo/peardock-wordmark.svg" color="#2dd4bf" />
|
||
|
||
<!-- Article -->
|
||
<meta property="article:section" content="Learn" />
|
||
<meta property="article:author" content="HoneyPeer, LLC" />
|
||
<meta property="article:publisher" content="HoneyPeer, LLC" />
|
||
|
||
<script type="application/ld+json">
|
||
{
|
||
"@context": "https://schema.org",
|
||
"@type": "WebPage",
|
||
"name": "How PearDock Works \u00b7 P2P Docker control",
|
||
"description": "Learn how PearDock manages Docker over peer-to-peer HyperDHT. No open ports, no VPN, no public Docker API. Identity, hole punching, control plane, Holesail tunnels, and security.",
|
||
"url": "https://peardock.boats/learn/",
|
||
"isPartOf": {
|
||
"@type": "WebSite",
|
||
"name": "PearDock",
|
||
"url": "https://peardock.boats"
|
||
},
|
||
"publisher": {
|
||
"@type": "Organization",
|
||
"name": "HoneyPeer, LLC",
|
||
"url": "https://peardock.boats"
|
||
},
|
||
"inLanguage": "en-US",
|
||
"primaryImageOfPage": {
|
||
"@type": "ImageObject",
|
||
"url": "https://peardock.boats/assets/brand/og-image.png",
|
||
"width": 1200,
|
||
"height": 630
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
||
<link rel="stylesheet" href="/src/styles/global.css" />
|
||
<link rel="stylesheet" href="/src/styles/docs.css" />
|
||
<link rel="stylesheet" href="/src/styles/learn.css" />
|
||
</head>
|
||
<body>
|
||
<div class="bg-mesh" aria-hidden="true"></div>
|
||
<div data-nav data-prefix="../"></div>
|
||
|
||
<header class="learn-hero">
|
||
<div class="learn-hero-inner">
|
||
<div class="badge mb-4">learn · how it works</div>
|
||
<h1>Peer-to-peer Docker control</h1>
|
||
<p class="lead">
|
||
PearDock is decentralized Docker management on the Holepunch stack.
|
||
<strong>You never need to open ports, expose Docker, or worry about remote access again.</strong>
|
||
You only need keys, peers, and the Engine you already run.
|
||
</p>
|
||
<div class="learn-key">
|
||
<div>
|
||
<strong>Key concept</strong>
|
||
Your laptop and a remote Docker host talk directly over an encrypted P2P stream.
|
||
No inbound firewall rules. No public <code>dockerd</code>. No always-on VPN.
|
||
Discovery and NAT traversal use HyperDHT. Docker commands ride protomux-rpc on that stream.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div class="container learn-page">
|
||
<ul class="learn-toc">
|
||
<li><a href="#why">Why P2P?</a></li>
|
||
<li><a href="#problem">Old model</a></li>
|
||
<li><a href="#identity">Identity</a></li>
|
||
<li><a href="#connect">Connecting</a></li>
|
||
<li><a href="#nat">NAT & hole punching</a></li>
|
||
<li><a href="#control">Control plane</a></li>
|
||
<li><a href="#data">Data plane</a></li>
|
||
<li><a href="#security">Security</a></li>
|
||
<li><a href="#fleet">Fleet</a></li>
|
||
<li><a href="#flow">End-to-end</a></li>
|
||
<li><a href="#glossary">Glossary</a></li>
|
||
</ul>
|
||
|
||
<!-- WHY -->
|
||
<section class="learn-section" id="why">
|
||
<h2>Why peer-to-peer for Docker?</h2>
|
||
<p class="learn-lead">
|
||
Docker Engine is powerful locally. Remotely, people usually open a TLS API port, maintain a VPN, or enroll hosts in a hosted panel.
|
||
PearDock takes another path: treat the host as a peer you reach with a public key.
|
||
<strong>No open ports, no exposed Engine, no remote-access checklist that never ends.</strong>
|
||
</p>
|
||
<p>
|
||
You can manage a home lab behind CGNAT, a VPS without punching firewall holes, or a fleet of edge machines.
|
||
Peers need to complete HyperDHT hole punching (or a relay fallback), and you need the right key material.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- PROBLEM -->
|
||
<section class="learn-section" id="problem">
|
||
<h2>The traditional remote-Docker model</h2>
|
||
<p class="learn-lead">Most “remote Docker” setups trade convenience for a large attack surface or a permanent middleman.</p>
|
||
|
||
<div class="learn-compare">
|
||
<div class="learn-card learn-card--old">
|
||
<h4>✕ Centralized / exposed</h4>
|
||
<ul>
|
||
<li>Expose <code>dockerd</code> TCP + TLS to the internet</li>
|
||
<li>Always-on VPN just to run <code>docker ps</code></li>
|
||
<li>Hosted panel with your hosts enrolled forever</li>
|
||
<li>Single vendor outage = no ops UI</li>
|
||
</ul>
|
||
</div>
|
||
<div class="learn-card learn-card--new">
|
||
<h4>✓ PearDock peer model</h4>
|
||
<ul>
|
||
<li>Never open inbound ports for Docker or the control UI</li>
|
||
<li>Clients dial the <strong>public key</strong> over HyperDHT</li>
|
||
<li>Noise-encrypted RPC end to end. No VPN required.</li>
|
||
<li>You keep Docker and state on your machines</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<pre class="mermaid">
|
||
flowchart LR
|
||
subgraph Traditional["Traditional"]
|
||
A1[Laptop] --> VPN[VPN / open :2376 / SaaS]
|
||
VPN --> D1[dockerd]
|
||
end
|
||
subgraph PearDock["PearDock"]
|
||
A2[Desktop client] -- "HyperDHT + Noise + protomux-rpc" --> S2[peardock-server]
|
||
S2 --> D2[dockerd]
|
||
end
|
||
</pre>
|
||
</section>
|
||
|
||
<!-- IDENTITY -->
|
||
<section class="learn-section" id="identity">
|
||
<h2>Identity: seeds and public keys</h2>
|
||
<p class="learn-lead">
|
||
PearDock v2 identity is a HyperDHT keypair derived from a secret seed.
|
||
It is not a shared “topic string” like some older swarm designs.
|
||
</p>
|
||
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>Material</th><th>Who has it</th><th>Purpose</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>SERVER_SEED</code></td>
|
||
<td>Server only (secret)</td>
|
||
<td>32-byte seed; generates the listening keypair. Never share.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>SERVER_PUBLIC_KEY</code></td>
|
||
<td>Operators / clients</td>
|
||
<td>64 hex chars. Paste into the client to dial this host.</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Client keys</td>
|
||
<td>Each desktop install</td>
|
||
<td>Peer identity for ACL, invites, and reconnect cache.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<p>
|
||
On first start the server writes <code>SERVER_SEED</code> and <code>SERVER_PUBLIC_KEY</code> to
|
||
<code>/opt/peardock/.env</code> (mode 600) and prints the public key in the journal.
|
||
<strong>Check the <code>.env</code> file</strong> for both values before connecting.
|
||
Rotating the seed changes the public key. All clients must re-add the peer.
|
||
Back up that file like any other root secret.
|
||
</p>
|
||
|
||
<div class="callout warn">
|
||
<div class="callout-icon">!</div>
|
||
<div class="callout-body">
|
||
<strong>Not the same as a Holesail <code>hs://</code> URL.</strong>
|
||
The server public key is for PearDock <em>control</em> RPC.
|
||
Tunnel capabilities are separate secrets created per published port.
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- CONNECT -->
|
||
<section class="learn-section" id="connect">
|
||
<h2>How a client finds and connects to a server</h2>
|
||
<p class="learn-lead">
|
||
Under the hood this is classic Holepunch connectivity: announce, look up, hole-punch (or relay), then encrypt.
|
||
PearDock’s application layer starts only after that secure stream exists.
|
||
</p>
|
||
|
||
<div class="learn-peers">
|
||
<div class="learn-peer">
|
||
<h4>Client</h4>
|
||
<p>Desktop app holds public key + optional invite</p>
|
||
</div>
|
||
<div class="learn-arrow"><span>⇄</span>lookup</div>
|
||
<div class="learn-peer learn-peer--hub">
|
||
<h4>HyperDHT</h4>
|
||
<p>Distributed peer discovery & signaling</p>
|
||
</div>
|
||
<div class="learn-arrow"><span>⇄</span>announce</div>
|
||
<div class="learn-peer">
|
||
<h4>Server</h4>
|
||
<p>Listens on keypair next to Docker</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="learn-steps">
|
||
<div class="learn-step">
|
||
<h4>Announce</h4>
|
||
<p>The server registers its presence on HyperDHT under its cryptographic identity so dialers can find a path.</p>
|
||
</div>
|
||
<div class="learn-step">
|
||
<h4>Lookup & punch</h4>
|
||
<p>The client queries the DHT, then both sides attempt coordinated UDP probes so NAT mappings open (“hole punching”).</p>
|
||
</div>
|
||
<div class="learn-step">
|
||
<h4>Encrypt & RPC</h4>
|
||
<p>A Noise-encrypted stream carries protomux-rpc methods and server→client pushes (stats, logs, events).</p>
|
||
</div>
|
||
</div>
|
||
|
||
<pre class="mermaid">
|
||
sequenceDiagram
|
||
participant C as Client
|
||
participant DHT as HyperDHT
|
||
participant S as peardock-server
|
||
participant D as dockerd
|
||
S->>DHT: announce identity
|
||
C->>DHT: lookup public key
|
||
DHT-->>C: candidate endpoints
|
||
C->>S: hole punch / connect
|
||
C->>S: Noise handshake
|
||
C->>S: protomux-rpc handshake
|
||
S-->>C: role · protocol version
|
||
C->>S: listContainers / deploy / …
|
||
S->>D: dockerode
|
||
D-->>S: result
|
||
S-->>C: response + optional pushes
|
||
</pre>
|
||
</section>
|
||
|
||
<!-- NAT -->
|
||
<section class="learn-section" id="nat">
|
||
<h2>NAT traversal & hole punching</h2>
|
||
<p class="learn-lead">
|
||
Most devices sit behind Network Address Translation. Routers map private IPs to public ports and block unsolicited inbound traffic.
|
||
That is why “just open Docker on the internet” is a bad default, and why P2P needs help to dial home.
|
||
</p>
|
||
|
||
<h3>What hole punching does</h3>
|
||
<ol>
|
||
<li><strong>Both peers learn public endpoints</strong> via DHT-assisted signaling (not a single app-specific rendezvous you host).</li>
|
||
<li><strong>Simultaneous outbound probes</strong> create temporary NAT mappings toward each other.</li>
|
||
<li><strong>Direct path preferred</strong> when mappings cooperate (common on home NAT).</li>
|
||
<li><strong>Relay fallback</strong> may apply when both sides are hard symmetric NAT. Traffic stays encrypted. Relays do not get plaintext Docker commands.</li>
|
||
</ol>
|
||
|
||
<div class="learn-compare">
|
||
<div class="learn-card">
|
||
<h4>Easier NAT</h4>
|
||
<p>Open / consistent mappings → hole punching usually succeeds quickly. Typical home routers often work well.</p>
|
||
</div>
|
||
<div class="learn-card">
|
||
<h4>Harder NAT / CGNAT</h4>
|
||
<p>Symmetric NAT or carrier-grade NAT can block direct paths. The stack may need more probes or a relay. Still no need to expose dockerd publicly.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<p>
|
||
PearDock benefits from the same Holepunch/libudx generation of tools that power Hyperswarm and Holesail.
|
||
You don’t configure port forwards for the control channel. You share a key.
|
||
That is the whole remote-access story: no open ports, no exposed Engine, no perpetual VPN.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- CONTROL PLANE -->
|
||
<section class="learn-section" id="control">
|
||
<h2>Control plane: protomux-rpc over HyperDHT</h2>
|
||
<p class="learn-lead">
|
||
Once the encrypted stream is up, PearDock speaks a structured RPC protocol, not ad-hoc JSON lines.
|
||
That is how the UI stays rich: typed methods, roles, and live pushes.
|
||
</p>
|
||
|
||
<div class="learn-stack">
|
||
<div class="learn-layer">
|
||
<div class="learn-layer-name">UI</div>
|
||
<p>Desktop client (Electron / Pear) for containers, stacks, Swarm, tunnels, terminals, and jobs.</p>
|
||
</div>
|
||
<div class="learn-layer">
|
||
<div class="learn-layer-name">protomux-rpc</div>
|
||
<p>Request/response methods + push channels. <code>PROTOCOL_VERSION</code> negotiated on connect.</p>
|
||
</div>
|
||
<div class="learn-layer">
|
||
<div class="learn-layer-name">HyperDHT</div>
|
||
<p>Peer discovery, hole punch coordination, Noise transport under the app protocol.</p>
|
||
</div>
|
||
<div class="learn-layer">
|
||
<div class="learn-layer-name">handlers</div>
|
||
<p>Server modules for containers, images, volumes, networks, stacks, Swarm, vault, tunnels…</p>
|
||
</div>
|
||
<div class="learn-layer">
|
||
<div class="learn-layer-name">dockerode</div>
|
||
<p>Talks to local <code>dockerd</code> (usually the unix socket; server user in the <code>docker</code> group).</p>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>Client → server (examples)</h3>
|
||
<ul>
|
||
<li><code>handshake</code>, <code>ping</code>: session setup and liveness</li>
|
||
<li><code>listContainers</code>, <code>startContainer</code>, <code>stopContainer</code>, <code>recreateContainer</code></li>
|
||
<li><code>deployContainer</code>, <code>deployStack</code>, <code>syncStackFromGit</code></li>
|
||
<li><code>getContainerLogs</code>, <code>startTerminal</code>, <code>containerStats</code></li>
|
||
<li><code>systemPrune</code>, Swarm methods, vault, schedules, tunnels</li>
|
||
</ul>
|
||
|
||
<h3>Server → client pushes</h3>
|
||
<ul>
|
||
<li><code>push:containers</code>, <code>push:allStats</code>: live fleet view without spam polling</li>
|
||
<li><code>push:logs</code>, <code>push:terminalOutput</code>: streaming operator surfaces</li>
|
||
<li><code>push:dockerEvent</code> and pull/build progress: keep the UI honest when the Engine changes</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Method ↔ role maps live in the shared protocol. Viewers can observe; operators mutate day-to-day;
|
||
admins get destructive and policy-level actions. See
|
||
<a href="/docs/api">RPC & API</a> and <a href="/docs/security">Security</a>.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- DATA PLANE -->
|
||
<section class="learn-section" id="data">
|
||
<h2>Data plane: Holesail tunnels (optional traffic path)</h2>
|
||
<p class="learn-lead">
|
||
Managing Docker is not the same as reaching a published web app or TCP service.
|
||
PearDock keeps a second plane for that: Holesail L4 tunnels.
|
||
Still <strong>no open host ports</strong>. Share an <code>hs://</code> key instead of a firewall rule.
|
||
</p>
|
||
|
||
<pre class="mermaid">
|
||
flowchart LR
|
||
subgraph Control["Control plane"]
|
||
UI[Client RPC]
|
||
SRV[Server handlers]
|
||
UI --> SRV
|
||
SRV --> DK[Docker Engine]
|
||
end
|
||
subgraph Data["Data plane"]
|
||
HC[Holesail client]
|
||
HS[HolesailServer]
|
||
HC -- "hs:// capability" --> HS
|
||
HS --> Port["host:published-port"]
|
||
end
|
||
Control -.->|"orthogonal"| Data
|
||
</pre>
|
||
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>Plane</th><th>Technology</th><th>Carries</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Control</strong></td>
|
||
<td>HyperDHT + protomux-rpc</td>
|
||
<td>Docker ops, ACL, logs stream control, deploy, stats</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Data / tunnels</strong></td>
|
||
<td>Holesail</td>
|
||
<td>Raw TCP/UDP bytes to a published host port via <code>hs://</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<p>
|
||
<strong>Why not use only Holesail?</strong>
|
||
Holesail moves bytes between sockets. It is not an RPC framework, role system, or audit log.
|
||
PearDock needs structured methods and live UI channels, so control stays on protomux-rpc.
|
||
</p>
|
||
<p>
|
||
Tunnels are <strong>on by default</strong> (<code>ENABLE_HOLESAIL=0</code> to disable).
|
||
Treat every <code>hs://</code> URL as a capability secret. Details:
|
||
<a href="/docs/holesail">Holesail guide</a>.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- SECURITY -->
|
||
<section class="learn-section" id="security">
|
||
<h2>Security model (operator mental model)</h2>
|
||
<p class="learn-lead">P2P does not mean “open to the world.” It means “reachable by those who hold the right cryptographic handles.”</p>
|
||
|
||
<ul>
|
||
<li><strong>Transport encryption:</strong> Noise on the HyperDHT stream, not cleartext Docker API on :2375.</li>
|
||
<li><strong>Roles:</strong> viewer (default for public key alone), operator, and admin gate methods server-side.</li>
|
||
<li><strong>Keys in <code>.env</code>:</strong> after install, check <code>/opt/peardock/.env</code> for <code>SERVER_PUBLIC_KEY</code> and <code>SERVER_SEED</code>.</li>
|
||
<li><strong>Peer policy:</strong> optional allowlists, <code>pd1.</code> invites (no seed sharing), and revoke for multi-operator fleets.</li>
|
||
<li><strong>Rate limits and audit:</strong> blunt force protection and accountability for privileged calls.</li>
|
||
<li><strong>Registry vault:</strong> credentials encrypted at rest (AES-GCM keyed from server material).</li>
|
||
<li><strong>Tunnel SSRF guard:</strong> default allowlist for tunnel targets (loopback and published binds).</li>
|
||
<li><strong>Browse roots:</strong> host filesystem browse is default-deny and constrained.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
You still must secure Docker itself: who is in the <code>docker</code> group, what images you run, and how secrets enter containers.
|
||
PearDock is a control surface. It inherits the power of the Engine socket it uses.
|
||
</p>
|
||
<p>Deep dive: <a href="/docs/security">Threat model & hardening</a> · <a href="/legal/security">Vulnerability reporting</a></p>
|
||
</section>
|
||
|
||
<!-- FLEET -->
|
||
<section class="learn-section" id="fleet">
|
||
<h2>Multi-peer fleet UX</h2>
|
||
<p class="learn-lead">
|
||
One desktop client can keep many servers. Each peer is a separate HyperDHT identity with its own role and health.
|
||
</p>
|
||
<ul>
|
||
<li>Disk-backed peer cache under the client config directory</li>
|
||
<li>Auto-reconnect (retry cadence when a peer drops)</li>
|
||
<li>Environment tags (prod / staging / lab) for mental models</li>
|
||
<li>Job tray and notifications scoped to operator workflows</li>
|
||
</ul>
|
||
<p>
|
||
There is no “log into PearDock cloud.” There is only: which public keys did you add, and which of those peers are online.
|
||
</p>
|
||
</section>
|
||
|
||
<!-- END TO END -->
|
||
<section class="learn-section" id="flow">
|
||
<h2>End-to-end: first session</h2>
|
||
<p class="learn-lead">From zero to a live containers list. This is the path most operators take.</p>
|
||
|
||
<pre class="mermaid">
|
||
flowchart TB
|
||
A[Install peardock-server on Docker host] --> B["Read keys from /opt/peardock/.env"]
|
||
B --> C[Install desktop client]
|
||
C --> D[Add peer · key / seed / pd1 invite]
|
||
D --> E[Handshake · role · protocol version]
|
||
E --> F[listContainers · stats pushes · manage]
|
||
F --> G{Need app traffic?}
|
||
G -->|Yes| H[Create Holesail tunnel · share hs://]
|
||
G -->|No| I[Stay on control plane only]
|
||
</pre>
|
||
|
||
<ol>
|
||
<li>Install the server (one-liner or binary) on a machine with Docker.</li>
|
||
<li>Read <code>SERVER_PUBLIC_KEY</code> and (for admin) <code>SERVER_SEED</code> from <code>/opt/peardock/.env</code>.</li>
|
||
<li>Install the client; Add peer with key / key+seed / full <code>pd1.</code> invite; wait for health.</li>
|
||
<li>Operate: deploy, logs, terminal, stacks, Swarm, prune, schedules…</li>
|
||
<li>Optionally tunnel a published port with Holesail for users outside the control path.</li>
|
||
</ol>
|
||
|
||
<p>
|
||
Install: <a href="/download">Download & install</a> ·
|
||
Guide: <a href="/docs/quickstart">Quick start</a> ·
|
||
Binaries: <a href="/releases">Releases</a>
|
||
</p>
|
||
</section>
|
||
|
||
<!-- GLOSSARY -->
|
||
<section class="learn-section" id="glossary">
|
||
<h2>Glossary</h2>
|
||
<div class="learn-glossary">
|
||
<details>
|
||
<summary>HyperDHT</summary>
|
||
<p>Distributed hash table used for peer announcements, lookups, and hole-punch coordination. Peers find each other by cryptographic identity without PearDock hosting a central directory of your fleet.</p>
|
||
</details>
|
||
<details>
|
||
<summary>Noise / Secret Stream</summary>
|
||
<p>Encrypted, mutually authenticated transport under HyperDHT connections. Application data (RPC) is not sent in the clear across the peer path.</p>
|
||
</details>
|
||
<details>
|
||
<summary>protomux-rpc</summary>
|
||
<p>RPC framework PearDock uses for named methods and server-initiated push channels over a multiplexed stream.</p>
|
||
</details>
|
||
<details>
|
||
<summary>Hole punching</summary>
|
||
<p>Technique where two NATed peers send coordinated outbound packets so temporary firewall mappings allow a direct path. If both sides are hostile NAT, encrypted relays may assist.</p>
|
||
</details>
|
||
<details>
|
||
<summary>NAT / CGNAT</summary>
|
||
<p>Network Address Translation (and carrier-grade NAT) share public IPs and block unsolicited inbound connections. That is why “open port 2376” is painful and unsafe as a default.</p>
|
||
</details>
|
||
<details>
|
||
<summary>Public key vs SERVER_SEED</summary>
|
||
<p>Both are written to <code>/opt/peardock/.env</code> on first start. The public key is what clients dial (viewer if used alone). The seed is secret server identity — paste it with the public key for admin only. Sharing the seed is equivalent to handing over admin.</p>
|
||
</details>
|
||
<details>
|
||
<summary>pd1. invite</summary>
|
||
<p>Self-contained peardock share string from Access → Create invite. Embeds public key + HMAC capability so operators connect without receiving <code>SERVER_SEED</code>. Paste the full string in Add peer (never truncate).</p>
|
||
</details>
|
||
<details>
|
||
<summary>Holesail / hs://</summary>
|
||
<p>Peer-to-peer L4 reverse proxy. An <code>hs://</code> URL is a capability to reach a specific tunnel endpoint. It is separate from PearDock’s Docker control key.</p>
|
||
</details>
|
||
<details>
|
||
<summary>dockerode</summary>
|
||
<p>Node.js Docker client used by the PearDock server to talk to the local Docker Engine API (typically via the unix socket).</p>
|
||
</details>
|
||
<details>
|
||
<summary>Role (viewer / operator / admin)</summary>
|
||
<p>Server-enforced permission tier for RPC methods. UI may hide actions, but the server is the authority.</p>
|
||
</details>
|
||
<details>
|
||
<summary>Rolling release</summary>
|
||
<p>Continuously updated binary channel used by the installer and <a href="/releases">releases</a> page. Recommended for current peardock-server and peardock-client builds.</p>
|
||
</details>
|
||
</div>
|
||
</section>
|
||
|
||
<div class="learn-cta">
|
||
<h2>Ready to try it?</h2>
|
||
<p>Install a server next to Docker, paste the public key into the client, and operate without a central control plane.</p>
|
||
<div class="learn-cta-actions">
|
||
<a class="btn btn-primary" href="/download">Install PearDock</a>
|
||
<a class="btn btn-secondary" href="/docs/architecture">Architecture docs</a>
|
||
<a class="btn btn-ghost" href="/docs/">All documentation</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div data-footer data-prefix="../"></div>
|
||
<script type="module" src="/src/js/site.js"></script>
|
||
</body>
|
||
</html>
|