Operator guide

Production install, multi-operator ACL, feature flags, logging, compose, and backup.

Recommended: one-line installer

On a Linux host with Docker already installed:

curl -fsSL https://install.peardock.boats | bash -s -- --server --yes

This installs the Bare server binary, creates user peardock, adds it to the docker group, writes a systemd unit, and can enable the service immediately.

sudo systemctl status peardock
sudo journalctl -u peardock -f

Check /opt/peardock/.env for your keys

After the first successful start, identity is written to the env file (mode 600). Always check this file for both values:

sudo grep -E '^(SERVER_PUBLIC_KEY|SERVER_SEED)=' /opt/peardock/.env
# or: sudo cat /opt/peardock/.env
VariableWhoClient paste
SERVER_PUBLIC_KEYSafe to shareAlone → viewer
SERVER_SEEDAdmins only — never share with operatorsWith public key → admin

Full flags and client install: Download & install.

Paths (installer defaults)

PathRole
/opt/peardock/peardock-serverServer binary
/opt/peardock/.envSERVER_SEED + SERVER_PUBLIC_KEY (mode 600)
/etc/systemd/system/peardock.servicesystemd unit
journalctl -u peardockLogs

systemd unit (current)

Matches deploy/peardock.service and the unit written by install.sh:

[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

Source install alternative for ExecStart:

ExecStart=/usr/bin/node /opt/peardock/server/server.js

Docker group / socket access

Engine sockets are typically root:docker mode 660. The service must run as a user in group docker (or the socket’s group).

# 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

Symptoms of a missing group: empty container lists, start failures, “permission denied” on the socket.

Manual install from source

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

Healthcheck

node scripts/healthcheck.js
# exit 0 if Docker socket answers

Multi-operator setup

Default peer role is viewer (public key alone is read-only). Elevate with seed proof or invites.

  1. Read SERVER_PUBLIC_KEY and SERVER_SEED from /opt/peardock/.env.
  2. Connect as admin: desktop client → Add peer → public key + SERVER_SEED (seed stays on the client; never share it).
  3. Optional harden flags in the same .env (or Environment= in the unit):
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
  1. As admin: Access → Create invite → copy the full pd1.… invite string (never truncate).
  2. Operator pastes the full pd1. invite in Add peer — the client decodes public key + HMAC capability and connects with the granted role (no seed, no RocksDB/Autopass).
  3. Revoke lost devices from Access. Delete spent invites before minting a replacement if needed.
Connect withRole
Server public key onlyviewer
Public key + SERVER_SEEDadmin
peardock invite (pd1.…)Role in package (viewer / operator / admin)

Full model (handshake elevation, capability format, redeem vs reconnect, revoke): Security model.

Registry vault

Credentials encrypted at rest (AES-GCM derived from SERVER_SEED):

Feature flags

EnvEffect
ENABLE_SWARM=0Disable Swarm / services / secrets / configs RPC (on by default)
ENABLE_PLUGINS=1Plugin install/enable/remove
ENABLE_HOLESAIL=0Disable Holesail tunnels (on by default)
PEARDOCK_MAX_TUNNELSMax concurrent tunnels (default 20)
PEARDOCK_TUNNEL_HOSTSExtra allowed tunnel target hosts
PEARDOCK_UNRESTRICTED_CLI=1Broader docker CLI for admin
PEARDOCK_BROWSE_OPEN=1Legacy open host FS browse (discouraged)

Logging

EnvEffect
LOG_LEVELerror · warn · info · debug
LOG_FORMATpretty (TTY) · json (journald)
ENABLE_FILE_LOGGING=1JSON lines under LOG_DIR
NO_COLOR=1Disable ANSI in pretty mode
# Prefer journald JSON in production
# Environment=LOG_FORMAT=json
# Environment=LOG_LEVEL=info
sudo journalctl -u peardock -f

Compose stacks

deployStack accepts:

Metrics

RPC getMetrics returns process memory, RPC counters, latency percentiles, feature flags.

Updating the server

  1. Re-run the installer with --server --yes, or replace /opt/peardock/peardock-server from a newer rolling tarball.
  2. Keep /opt/peardock/.env (seed) and vault/peer files.
  3. sudo systemctl restart peardock

Certification / soak

npm run soak          # short Docker health loop
npm run soak:24h      # 24h certification

Backup

Back up atomically from the server data dir (default /opt/peardock):