298 lines
13 KiB
HTML
298 lines
13 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>Operator guide · PearDock Docs</title>
|
||
<meta name="description" content="Deploy and operate PearDock: install.sh, systemd, docker group, roles, vault, flags, logging, stacks, backup." />
|
||
<meta name="keywords" content="PearDock operator, systemd, roles, vault, production" />
|
||
<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/docs/operator" />
|
||
<link rel="alternate" hreflang="en" href="https://peardock.boats/docs/operator" />
|
||
<link rel="alternate" hreflang="x-default" href="https://peardock.boats/docs/operator" />
|
||
|
||
<!-- 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/docs/operator" />
|
||
<meta property="og:title" content="Operator guide · PearDock Docs" />
|
||
<meta property="og:description" content="Deploy and operate PearDock: install.sh, systemd, docker group, roles, vault, flags, logging, stacks, backup." />
|
||
<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="Operator guide · PearDock Docs" />
|
||
<meta name="twitter:description" content="Deploy and operate PearDock: install.sh, systemd, docker group, roles, vault, flags, logging, stacks, backup." />
|
||
<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="Documentation" />
|
||
<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",
|
||
"TechArticle"
|
||
],
|
||
"name": "Operator guide \u00b7 PearDock Docs",
|
||
"description": "Deploy and operate PearDock: install.sh, systemd, docker group, roles, vault, flags, logging, stacks, backup.",
|
||
"url": "https://peardock.boats/docs/operator",
|
||
"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
|
||
},
|
||
"headline": "Operator guide \u00b7 PearDock Docs"
|
||
}
|
||
</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" />
|
||
</head>
|
||
<body>
|
||
<div class="bg-mesh" aria-hidden="true"></div>
|
||
<div data-nav data-prefix="../"></div>
|
||
|
||
<div class="docs-layout">
|
||
<aside class="docs-sidebar" data-docs-nav data-prefix="../"></aside>
|
||
<button type="button" class="docs-sidebar-toggle" aria-label="Docs menu">☰</button>
|
||
|
||
<article class="docs-main">
|
||
<h1>Operator guide</h1>
|
||
<p class="docs-lead">Production install, multi-operator ACL, feature flags, logging, compose, and backup.</p>
|
||
|
||
<h2>Recommended: one-line installer</h2>
|
||
<p>On a Linux host with Docker already installed:</p>
|
||
<pre><code>curl -fsSL https://install.peardock.boats | bash -s -- --server --yes</code></pre>
|
||
<p>This installs the Bare server binary, creates user <code>peardock</code>, adds it to the <strong>docker</strong> group, writes a systemd unit, and can enable the service immediately.</p>
|
||
<pre><code>sudo systemctl status peardock
|
||
sudo journalctl -u peardock -f
|
||
# copy public key from logs into the desktop client</code></pre>
|
||
<p>Full flags and client install: <a href="/download">Download & install</a>.</p>
|
||
|
||
<h2>Paths (installer defaults)</h2>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>Path</th><th>Role</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>/opt/peardock/peardock-server</code></td><td>Server binary</td></tr>
|
||
<tr><td><code>/opt/peardock/.env</code></td><td>Identity / env (mode 600)</td></tr>
|
||
<tr><td><code>/etc/systemd/system/peardock.service</code></td><td>systemd unit</td></tr>
|
||
<tr><td><code>journalctl -u peardock</code></td><td>Logs</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<h2>systemd unit (current)</h2>
|
||
<p>Matches <code>deploy/peardock.service</code> and the unit written by <code>install.sh</code>:</p>
|
||
<pre><code>[Unit]
|
||
Description=peardock HyperDHT Docker control plane
|
||
Documentation=https://git.ssh.surf/snxraven/peardock
|
||
After=network-online.target
|
||
Wants=network-online.target
|
||
Wants=docker.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
WorkingDirectory=/opt/peardock
|
||
ExecStart=/opt/peardock/peardock-server
|
||
Restart=on-failure
|
||
RestartSec=5
|
||
TimeoutStartSec=30
|
||
TimeoutStopSec=30
|
||
NoNewPrivileges=true
|
||
PrivateTmp=true
|
||
User=peardock
|
||
Group=docker
|
||
SupplementaryGroups=docker
|
||
Environment=NODE_ENV=production
|
||
EnvironmentFile=-/opt/peardock/.env
|
||
ReadWritePaths=/opt/peardock
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target</code></pre>
|
||
<p>Source install alternative for <code>ExecStart</code>:</p>
|
||
<pre><code>ExecStart=/usr/bin/node /opt/peardock/server/server.js</code></pre>
|
||
|
||
<h2>Docker group / socket access</h2>
|
||
<p>
|
||
Engine sockets are typically <code>root:docker</code> mode <code>660</code>.
|
||
The service <strong>must</strong> run as a user in group <code>docker</code> (or the socket’s group).
|
||
</p>
|
||
<pre><code># Installer does this; manual recovery:
|
||
sudo usermod -aG docker peardock
|
||
# if docker group was just created, restart Docker once
|
||
sudo systemctl restart docker
|
||
sudo systemctl restart peardock</code></pre>
|
||
<p>Symptoms of a missing group: empty container lists, start failures, “permission denied” on the socket.</p>
|
||
|
||
<h2>Manual install from source</h2>
|
||
<pre><code>git clone https://git.ssh.surf/snxraven/peardock.git /opt/peardock
|
||
cd /opt/peardock
|
||
npm ci --omit=dev # Node.js ≥ 20
|
||
|
||
sudo useradd --system --home /opt/peardock --shell /usr/sbin/nologin peardock
|
||
sudo usermod -aG docker peardock
|
||
sudo cp deploy/peardock.service /etc/systemd/system/
|
||
# edit ExecStart if using node instead of Bare binary
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now peardock
|
||
sudo journalctl -u peardock -f</code></pre>
|
||
|
||
<h2>Healthcheck</h2>
|
||
<pre><code>node scripts/healthcheck.js
|
||
# exit 0 if Docker socket answers</code></pre>
|
||
|
||
<h2>Multi-operator setup</h2>
|
||
<ol>
|
||
<li>On first connect, note the client’s peer id (handshake returns <code>peerId</code>).</li>
|
||
<li>Configure <code>/opt/peardock/.env</code> (or Environment= in the unit):</li>
|
||
</ol>
|
||
<pre><code>PEARDOCK_DEFAULT_ROLE=viewer
|
||
PEARDOCK_ADMIN_KEYS=<64-hex-client-public-key>
|
||
PEARDOCK_PEER_ALLOWLIST=1
|
||
PEARDOCK_BROWSE_ROOTS=/var/lib/docker/volumes
|
||
PEARDOCK_AUDIT=1</code></pre>
|
||
<ol start="3">
|
||
<li>As admin: <strong>Access → Create invite</strong> → send token to operator.</li>
|
||
<li>Operator connects with server public key + invite token as supported.</li>
|
||
<li><strong>Revoke</strong> lost devices from Access.</li>
|
||
</ol>
|
||
|
||
<h2>Registry vault</h2>
|
||
<p>Credentials encrypted at rest (AES-GCM derived from <code>SERVER_SEED</code>):</p>
|
||
<ul>
|
||
<li>UI: <strong>Access → Registry vault</strong></li>
|
||
<li>RPC: <code>vaultStoreCredential</code>, <code>vaultUseCredential</code>, <code>listVaultCredentials</code></li>
|
||
<li>File: <code>peardock-vault.json</code> (mode 600). Override with <code>PEARDOCK_VAULT_PATH</code>.</li>
|
||
</ul>
|
||
|
||
<h2>Feature flags</h2>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>Env</th><th>Effect</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>ENABLE_SWARM=0</code></td><td>Disable Swarm / services / secrets / configs RPC (on by default)</td></tr>
|
||
<tr><td><code>ENABLE_PLUGINS=1</code></td><td>Plugin install/enable/remove</td></tr>
|
||
<tr><td><code>ENABLE_HOLESAIL=0</code></td><td>Disable Holesail tunnels (on by default)</td></tr>
|
||
<tr><td><code>PEARDOCK_MAX_TUNNELS</code></td><td>Max concurrent tunnels (default 20)</td></tr>
|
||
<tr><td><code>PEARDOCK_TUNNEL_HOSTS</code></td><td>Extra allowed tunnel target hosts</td></tr>
|
||
<tr><td><code>PEARDOCK_UNRESTRICTED_CLI=1</code></td><td>Broader docker CLI for admin</td></tr>
|
||
<tr><td><code>PEARDOCK_BROWSE_OPEN=1</code></td><td>Legacy open host FS browse (discouraged)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<h2>Logging</h2>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr><th>Env</th><th>Effect</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><code>LOG_LEVEL</code></td><td>error · warn · info · debug</td></tr>
|
||
<tr><td><code>LOG_FORMAT</code></td><td>pretty (TTY) · json (journald)</td></tr>
|
||
<tr><td><code>ENABLE_FILE_LOGGING=1</code></td><td>JSON lines under LOG_DIR</td></tr>
|
||
<tr><td><code>NO_COLOR=1</code></td><td>Disable ANSI in pretty mode</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<pre><code># Prefer journald JSON in production
|
||
# Environment=LOG_FORMAT=json
|
||
# Environment=LOG_LEVEL=info
|
||
sudo journalctl -u peardock -f</code></pre>
|
||
|
||
<h2>Compose stacks</h2>
|
||
<p><code>deployStack</code> accepts:</p>
|
||
<ul>
|
||
<li><code>composeContent</code> (required)</li>
|
||
<li><code>overrideContent</code>: second compose file</li>
|
||
<li><code>envFileContent</code>: written as <code>.env</code> for compose CLI</li>
|
||
<li><code>profiles</code>: array or comma string</li>
|
||
<li><code>build: true</code>: runs <code>docker compose up --build</code></li>
|
||
</ul>
|
||
|
||
<h2>Metrics</h2>
|
||
<p>RPC <code>getMetrics</code> returns process memory, RPC counters, latency percentiles, feature flags.</p>
|
||
|
||
<h2>Updating the server</h2>
|
||
<ol>
|
||
<li>Re-run the installer with <code>--server --yes</code>, or replace <code>/opt/peardock/peardock-server</code> from a newer rolling tarball.</li>
|
||
<li><strong>Keep</strong> <code>/opt/peardock/.env</code> (seed) and vault/peer files.</li>
|
||
<li><code>sudo systemctl restart peardock</code></li>
|
||
</ol>
|
||
|
||
<h2>Certification / soak</h2>
|
||
<pre><code>npm run soak # short Docker health loop
|
||
npm run soak:24h # 24h certification</code></pre>
|
||
|
||
<h2>Backup</h2>
|
||
<p>Back up atomically from the server data dir (default <code>/opt/peardock</code>):</p>
|
||
<ul>
|
||
<li><code>.env</code> (<code>SERVER_SEED</code>)</li>
|
||
<li><code>peardock-vault.json</code></li>
|
||
<li><code>peardock-peers.json</code></li>
|
||
<li><code>peardock-audit.log</code> (optional)</li>
|
||
</ul>
|
||
|
||
<div class="docs-pager">
|
||
<a href="/docs/architecture"><span>Previous</span><strong>← Architecture</strong></a>
|
||
<a class="next" href="/docs/holesail"><span>Next</span><strong>Holesail →</strong></a>
|
||
</div>
|
||
</article>
|
||
</div>
|
||
|
||
<div data-footer data-prefix="../"></div>
|
||
<script type="module" src="/src/js/site.js"></script>
|
||
</body>
|
||
</html>
|