# Configuration reference All knobs can be set via environment variables. The agent loads `.env` through `dotenv` on boot (`server/core/keys.js`). Copy `.env.example` to get started. ```bash cp .env.example .env ``` --- ## Agent identity | Variable | Default | Description | |----------|---------|-------------| | `SERVER_SEED` | *auto-generated* | 32-byte secret as **64 hex** chars. Root of HMAC capabilities + admin proofs. **Keep offline / mode 0600.** | | `SERVER_PUBLIC_KEY` | *derived* | 32-byte public key as **64 hex**. Clients dial this. Auto-synced to `.env` when seed loads. | | `SERVER_KEY` | — | Alias accepted for `SERVER_SEED` (legacy). Prefer `SERVER_SEED`. | Treat `SERVER_SEED` like a root password. Prefer `pd1.` invites for operators. --- ## Roles & access control | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_DEFAULT_ROLE` | `viewer` | Baseline role: `viewer` \| `operator` \| `admin` | | `PEARDATA_ADMIN_KEYS` | empty | Comma-separated peer pubs always elevated to **admin** | | `PEARDATA_ALLOWLIST` | empty | If **non-empty**, only listed peers may connect | | `PEARDATA_INSECURE_OPEN_ADMIN` | off | `1` → every peer is admin. **Dev only.** | --- ## Runtime paths & limits | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_DATA_DIR` | `./data` | Peer policy JSON + `audit.log` | | `PEARDATA_HOME` | OS home | Root for client identity + bookmarks (`~/.config/peardata/`) | | `PEARDATA_STORAGE` | — | Electron/Pear storage dir override (bookmarks prefer `Pear.config.storage`) | | `PEARDATA_RATE_LIMIT_RPM` | `120` | Per-peer RPC requests per minute | | `PEARDATA_MAX_RECONNECT` | `20` | Client manager reconnect attempts per peer | | `PEARDATA_JOURNAL` | **on** | Host `journalctl` for Logs / `queryLogs` (Linux). Set `0` to disable. Installer adds `peardata` to `systemd-journal` and sets unit `SupplementaryGroups` | ``` data/ ├── peer-policy.json ├── retention.json # Data Manager policy (after first boot / Save) ├── audit.log └── corestore/ # HyperDB warm history ``` Permissions: directory `0700`. Do **not** commit `data/` or `.env`. --- ## Metrics pipeline | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_SAMPLE_MS` | `1000` | Collector interval | | `PEARDATA_TIER0_POINTS` | `3600` | High-res ring size (~1h @ 1s); seeds Data Manager | | `PEARDATA_TIER1_POINTS` | `1440` | Downsampled ring size; seeds Data Manager | | `PEARDATA_TIER1_EVERY` | `60` | Samples per tier1 average (also HyperDB warm flush) | | `PEARDATA_WARM_RETENTION_MS` | `7776000000` (90d / **3m**) | Soft age limit for HyperDB warm points (seed; default preset **3 months**) | | `PEARDATA_WARM_MAX_BYTES` | `1073741824` (1 GiB) | Soft corestore budget; set `0` for unlimited | | `PEARDATA_WARM_MAX_POINTS` | `0` | Cap on warm points (`0` = unlimited) | | `PEARDATA_AUTO_PRUNE` | on | `0` disables scheduled prune on boot | | `PEARDATA_WARM_ALL_CHARTS` | off | `1` flushes high-cardinality instance charts (disk/net/cgroup/docker) to HyperDB; default is static catalog only | Live retention is edited in the desktop **Settings → Data** tab (admin) and persisted to `$PEARDATA_DATA_DIR/retention.json`. Env values only seed the file on first boot. UI walkthrough: [user-guide/settings.md](../user-guide/settings.md). --- ## HyperDB storage & sync | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_HYPERDB` | on | `0` / `off` disables HyperDB | | `PEARDATA_SWARM` | off | `1` enables Hyperswarm Corestore replication | | `PEARDATA_DOCKER` | off* | `1` enables Docker Engine collector (socket + per-container cpu/mem + **human names**). *Installer sets `1` when Docker is detected and adds `peardata` to the `docker` group | | `PEARDATA_DOCKER_SOCKET` | auto | Socket path for names + API (`/var/run/docker.sock`, `/run/docker.sock`, Podman). Installer writes the detected path. See [user-guide/containers.md](../user-guide/containers.md) | | `PEARDATA_CGROUPS` | on (Linux) | `0` disables cgroup v2 CPU/mem/IO charts; `1` forces on | | `PEARDATA_CGROUPS_MAX` | `32` | Max cgroup instances to chart | | `PEARDATA_SENSORS` | on (Linux) | `0` disables hwmon/thermal charts | | `PEARDATA_DISK_PARTITIONS` | off | `1` charts partition devices (higher cardinality) | | `PEARDATA_IRQ_MAX` | `24` | Max per-IRQ interrupt charts | | `PEARDATA_PROCESSES` | **on** (Linux) | Top process charts (`processes.top_*`). Set `0` to disable. Processes **tab** works whenever `/proc` is readable | | `PEARDATA_PROCESSES_TOP` | `8` | How many processes to keep in top charts (max 32) | | `PEARDATA_MYSQL` | off | MySQL/MariaDB TCP probe (+ optional stats URL) | | `PEARDATA_MYSQL_URL` | `127.0.0.1:3306` | MySQL host:port | | `PEARDATA_MYSQL_STATS_URL` | — | Optional HTTP key=value stats | | `PEARDATA_APACHE` | off | Apache `server-status?auto` | | `PEARDATA_APACHE_URL` | `http://127.0.0.1/server-status?auto` | | | `PEARDATA_MEMCACHED` | off | Memcached `stats` | | `PEARDATA_MEMCACHED_URL` | `127.0.0.1:11211` | | | `PEARDATA_MONGODB` | off | MongoDB TCP probe | | `PEARDATA_MONGODB_URL` | `127.0.0.1:27017` | | | `PEARDATA_RABBITMQ` | off | RabbitMQ management API | | `PEARDATA_RABBITMQ_URL` | `http://guest:guest@127.0.0.1:15672` | | | `PEARDATA_PROMETHEUS` | off | Generic Prometheus text scrape | | `PEARDATA_PROMETHEUS_URLS` | — | Comma-separated scrape URLs | | `PEARDATA_STATSD` | off | StatsD UDP ingest on localhost | | `PEARDATA_STATSD_PORT` | `8125` | | | `PEARDATA_SMART` | off | `smartctl` disk SMART | | `PEARDATA_NVIDIA` | off | `nvidia-smi` GPU metrics | | `PEARDATA_IPMI` | off | `ipmitool sensor` | | `PEARDATA_EBPF` | on (Linux) | Embedded eBPF-family helper / JS fallback; `0` disables | | `PEARDATA_EBPF_PATH` | — | Optional external NDJSON bridge path | | `PEARDATA_HELPER_DIR` | tmp/helpers | Where embedded helpers are extracted | | `PEARDATA_IOPING` | off | Active disk latency probe | | `PEARDATA_ZFS` | auto | ZFS ARC/pool when kstat present | | `PEARDATA_BCACHE` | auto | BCache when `/sys/fs/bcache` exists | | `PEARDATA_DMCACHE` | auto | dm-cache when device-mapper cache present; `0` disables | | `PEARDATA_FS_STATS` | on (Linux) | ext4/xfs lifetime IO stats; `0` disables | | `PEARDATA_KAFKA` | off | Kafka exporter scrape | | `PEARDATA_KAFKA_URL` | `http://127.0.0.1:9308/metrics` | | | `PEARDATA_NATS` | off | NATS `/varz` | | `PEARDATA_NATS_URL` | `http://127.0.0.1:8222` | | | `PEARDATA_UNBOUND` | off | Unbound stats | | `PEARDATA_SOCKETS` | on (Linux) | TCP/UDP socket state charts | | `PEARDATA_PARENT` | off | `1` enables parent peer fleet aggregator | | `PEARDATA_PARENT_PEERS` | empty | Comma-separated child agent public keys (64 hex) | | `PEARDATA_PARENT_PEERS_FILE` | — | Optional file with one child pubkey per line | | `PEARDATA_PARENT_SEED` | — | Optional `SERVER_SEED` of children for admin proof dial | | `PEARDATA_PARENT_POLL_MS` | `5000` | How often parent polls children | | `PEARDATA_NGINX` | off | `1` enables nginx stub_status collector | | `PEARDATA_NGINX_URL` | `http://127.0.0.1/nginx_status` | stub_status URL | | `PEARDATA_REDIS` | off | `1` enables Redis INFO collector | | `PEARDATA_REDIS_URL` | `127.0.0.1:6379` | Redis host:port or `redis://` URL | | `PEARDATA_POSTGRES` | off | `1` enables Postgres TCP probe (+ optional stats URL) | | `PEARDATA_POSTGRES_HOST` | `127.0.0.1` | Postgres host | | `PEARDATA_POSTGRES_PORT` | `5432` | Postgres port | | `PEARDATA_POSTGRES_STATS_URL` | — | Optional HTTP key=value stats sidecar | | `PEARDATA_EXPORT_DIR` | — | Write `snapshot-*.json` from export job/RPC | | `PEARDATA_PUSHGATEWAY_URL` | — | POST Prometheus text (Pushgateway-compatible) | | `PEARDATA_WEBHOOK_URL` | — | POST anomaly JSON on alert fire | | `PEARDATA_WEBHOOK_SECRET` | — | HMAC key for `X-PearData-Signature` | | `PEARDATA_WEBHOOK_SIGN` | on (if secret) | `0` disables HMAC signing | | `PEARDATA_WEBHOOK_LEGACY_SECRET` | off | `1` also send plaintext `X-PearData-Secret` | | `PEARDATA_NOTIFY_CLEARS` | off | `1` also webhook when anomaly clears | | `PEARDATA_NOTIFY_MIN_SEVERITY` | `warning` | `warning` \| `critical` | | `PEARDATA_ANOMALY_MODE` | `threshold` | `threshold` \| `zscore` \| `hybrid` | | `PEARDATA_ANOMALY_WINDOW` | `120` | Rolling samples for z-score / retrain | | `PEARDATA_ANOMALY_WARN_Z` | `2` | Warn at \|z\| ≥ this | | `PEARDATA_ANOMALY_CRIT_Z` | `3` | Critical at \|z\| ≥ this | | `PEARDATA_REST_TUNNEL` | off | `1` expose REST over HyperDHT (holesail-style) | | `PEARDATA_REST_TUNNEL_SEED` | — | 64-hex seed for stable tunnel public key | | `PEARDATA_PEARDOCK` | off | `1` enable PearDock bridge (remap remote docker charts) | | `PEARDATA_PEARDOCK_PEERS` | empty | Comma-separated dock/agent public keys | | `PEARDATA_PEARDOCK_PEERS_FILE` | — | One pubkey per line | | `PEARDATA_PEARDOCK_SEED` | — | Optional admin seed for dial | | `PEARDATA_PEARDOCK_POLL_MS` | `5000` | Bridge poll interval | Storage: `$PEARDATA_DATA_DIR/corestore` (named core `peardata-meta`). Full guide: [STORAGE-HYPERDB.md](./STORAGE-HYPERDB.md). ```bash npm run build:db # regenerate spec/ after schema edits ``` --- ## REST API (agent-style) | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_REST` | on | Set `0` / `off` to disable HTTP API | | `PEARDATA_REST_HOST` | `127.0.0.1` | Bind address (`0.0.0.0` exposes LAN — firewall!) | | `PEARDATA_REST_PORT` | `18888` | HTTP port | | `PEARDATA_REST_CORS` | `*` | `Access-Control-Allow-Origin` | See [REST-API.md](./REST-API.md). --- ## Logging | Variable | Default | Description | |----------|---------|-------------| | `LOG_LEVEL` | `info` | `debug` \| `info` \| `warn` \| `error` | | `LOG_JSON` | off | `1` → JSON lines | --- ## Healthcheck / soak / tests | Variable | Default | Description | |----------|---------|-------------| | `PEARDATA_HEALTH_KEY` | `SERVER_PUBLIC_KEY` | Key for remote ping | | `HEALTHCHECK_TIMEOUT_MS` | `8000` | Dial timeout | | `SOAK_DURATION_MS` | `60000` | Soak length | | `SOAK_INTERVAL_MS` | `500` | Soak RPC interval | | `SKIP_INTEGRATION` | off | `1` skips DHT integration test | --- ## npm scripts | Script | Purpose | |--------|---------| | `npm start` / `npm run dev` | Pear desktop | | `npm run start:server` | Agent (P2P + REST) | | `npm run start:server:bin` | `bin/peardata-server.mjs` | | `npm test` | brittle suite | | `npm run mint-invite -- [role] [ttlMs]` | Offline `pd1.` invite | | `npm run build:db` | Regenerate HyperDB `spec/` | | `npm run healthcheck` | Liveness | | `npm run soak` | Load exercise | --- ## systemd Unit: `deploy/peardata.service` WorkingDirectory: `/opt/peardata` EnvironmentFile: `/opt/peardata/.env`