docs: bring all docs current with this session's changes
Unit Tests / test (push) Successful in 12m12s

Update README, QUICKSTART, wiki, service-developer-guide, and CLAUDE.md for:
optional store services (email/calendar/files), sshuttle+proxy egress exits,
provider-aware Network Services/DNS overview, DHCP/dnsmasq removal, split-horizon
VPN DNS, container hardening (slim images, unprivileged WireGuard, webui port 8080,
pinned ntp/coredns), installer changes (host NTP, PIC_DEBUG, clean output, systemd),
and the backup overhaul (full secrets coverage + optional passphrase encryption).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 15:56:03 -04:00
parent 82a0c0e9bd
commit 8a9f4f50c6
5 changed files with 196 additions and 67 deletions
+21 -16
View File
@@ -1,6 +1,6 @@
# Personal Internet Cell (PIC)
PIC is a self-hosted digital infrastructure platform. It packages DNS, DHCP, NTP, WireGuard VPN, email, calendar/contacts (CalDAV), file storage (WebDAV), a reverse proxy, a certificate authority, and optional third-party services — all managed through a single REST API and a React web UI. No manual config file editing is required for normal operations.
PIC is a self-hosted digital infrastructure platform. It packages DNS, NTP, WireGuard VPN, a reverse proxy, a certificate authority, and optional third-party services (email, calendar/contacts, file storage, and more) — all managed through a single REST API and a React web UI. No manual config file editing is required for normal operations.
---
@@ -8,19 +8,18 @@ PIC is a self-hosted digital infrastructure platform. It packages DNS, DHCP, NTP
```
Browser
└── React SPA (cell-webui :8081)
└── React SPA (cell-webui :8081, container port 8080)
└── Flask REST API (cell-api :3000, bound to 127.0.0.1)
└── Service managers + Docker SDK
├── cell-caddy :80/:443 Caddy reverse proxy (HTTPS/TLS)
├── cell-dns :53 CoreDNS
├── cell-dhcp :67/udp dnsmasq
├── cell-ntp :123/udp chrony
├── cell-wireguard :51820/udp WireGuard VPN
└── cell-webui :8081 React UI (Nginx)
├── cell-wireguard :51820/udp WireGuard VPN (NET_ADMIN only, not privileged)
└── cell-webui :8081→8080 React UI (Nginx)
(+ per-service containers, started when a service is installed)
```
Core containers run on a Docker bridge network (`cell-network`, default subnet `172.20.0.0/16`). Static IPs per container are set in `docker-compose.yml` and can be overridden via `.env`. Installed service containers join the same network with their own compose projects managed by `ServiceComposer`.
Six core containers run on a Docker bridge network (`cell-network`, default subnet `172.20.0.0/16`). Static IPs per container are set in `docker-compose.yml` and can be overridden via `.env`. Installed service containers join the same network with their own compose projects managed by `ServiceComposer`.
The Flask API (`api/app.py`) contains REST endpoints and a background health-monitoring thread. Service managers are instantiated as singletons in `api/managers.py`. The single source of truth for runtime configuration is `config/api/cell_config.json`, managed by `ConfigManager`.
@@ -38,10 +37,11 @@ The React frontend (`webui/`) is built with Vite + Tailwind CSS. All API calls g
- **Caddy HTTPS** — automatic TLS via Let's Encrypt (DNS-01 or HTTP-01) or an internal CA, depending on domain mode.
- **DDNS (pic.ngo)** — registers a `<cell-name>.pic.ngo` subdomain. Supported providers: `pic_ngo`, `cloudflare`, `duckdns`, `noip`, `freedns`. A background thread re-publishes the public IP every 5 minutes.
- **Service store** — install/remove optional third-party services from the `pic-services` index at `git.pic.ngo`. Manifests declare container images, Caddy routes, and iptables rules.
- **Extended connectivity** — per-peer egress routing through alternate exits: WireGuard external, OpenVPN, or Tor. Configured via policy routing (fwmark + ip rule) in the WireGuard container.
- **Extended connectivity** — per-peer egress routing through alternate exits: WireGuard external, OpenVPN, Tor, sshuttle (SSH tunnel), or proxy (HTTP/SOCKS5 via redsocks). Exit nodes are optional store services. Per-service egress policy is also supported. Routing uses fwmark and `ip rule` in the WireGuard container.
- **Cell-to-cell networking** — WireGuard-based site-to-site links between PIC cells with service-level access control (calendar, files, mail, WebDAV) and a peer-sync protocol.
- **Certificate authority** — `vault_manager` issues and revokes TLS certificates for internal services.
- **Network services** — CoreDNS (`.cell` TLD), dnsmasq DHCP, chrony NTP.
- **Network services** — CoreDNS (`.cell` TLD and split-horizon DNS for the cell domain), chrony NTP.
- **Split-horizon DNS** — from outside the VPN, the cell domain resolves to the public IP. Inside the VPN, CoreDNS resolves it to the WireGuard IP so traffic stays in the tunnel. Caddy serves on both interfaces.
- **Email** _(optional, install via Service Store)_ — Postfix + Dovecot via `docker-mailserver`.
- **Calendar/contacts** _(optional, install via Service Store)_ — Radicale CalDAV/CardDAV.
- **File storage** _(optional, install via Service Store)_ — WebDAV with per-user accounts; Filegator for browser-based file management.
@@ -53,11 +53,11 @@ The React frontend (`webui/`) is built with Vite + Tailwind CSS. All API calls g
## Requirements
- Linux host with the WireGuard kernel module loaded (`modprobe wireguard` to verify)
- Linux host with the WireGuard kernel module loaded (`modprobe wireguard` to verify; required — userspace WireGuard is not supported)
- Docker Engine and Docker Compose (v2 plugin or v1 standalone)
- Python 3.10+ (for `make setup` and local development; not needed at runtime)
- 2 GB+ RAM, 10 GB+ disk
- Ports available: 53, 67/udp, 80, 443, 51820/udp (plus 25, 587, 993 when the email service is installed)
- Ports available: 53, 80, 443, 51820/udp (plus 25, 587, 993 only when the email service is installed)
---
@@ -65,10 +65,17 @@ The React frontend (`webui/`) is built with Vite + Tailwind CSS. All API calls g
See [QUICKSTART.md](QUICKSTART.md) for step-by-step instructions.
The short version:
The short version — one-line installer (recommended):
```bash
git clone gitea@192.168.31.50:roof/pic.git pic
curl -fsSL https://install.pic.ngo | sudo bash
# open http://<host-ip>:8081/setup — the setup wizard appears automatically
```
Or clone manually for development:
```bash
git clone https://git.pic.ngo/roof/pic.git pic
cd pic
make start
# open http://<host-ip>:8081 — the setup wizard appears automatically
@@ -83,13 +90,12 @@ Port assignments and container IPs are configured in `.env` in the project root.
| Variable | Default | Description |
|---|---|---|
| `CELL_NETWORK` | `172.20.0.0/16` | Docker bridge subnet |
| `CADDY_IP` through `WG_IP` | `172.20.0.2``.9` | Static IP per core container |
| `CADDY_IP` through `WG_IP` | `172.20.0.2``.11` | Static IP per core container |
| `DNS_PORT` | `53` | DNS (UDP + TCP) |
| `DHCP_PORT` | `67` | DHCP (UDP) |
| `NTP_PORT` | `123` | NTP (UDP) |
| `WG_PORT` | `51820` | WireGuard listen port (UDP) |
| `API_PORT` | `3000` | Flask API (127.0.0.1 only) |
| `WEBUI_PORT` | `8081` | React UI |
| `WEBUI_PORT` | `8081` | Host port mapped to container port 8080 |
| `FLASK_DEBUG` | _(unset)_ | Set to `1` for Flask debug mode; do not use in production |
| `PUID` / `PGID` | current user | UID/GID passed to the WireGuard container |
@@ -104,7 +110,6 @@ Cell identity (cell name, domain mode, timezone) is set through the first-run wi
- `80` / `443` — Caddy (HTTP/HTTPS reverse proxy)
- `51820/udp` — WireGuard
- `53` — DNS
- `67/udp` — DHCP
- `8081` — Web UI
- `25` / `587` / `993` — mail _(only when the email service is installed)_