fix: config persistence, setup script, and install docs

- app.py: ConfigManager now uses CONFIG_DIR env var for config file path
  instead of hardcoded './config/cell_config.json' — config was being read
  from the image's working directory, making all settings writes ephemeral
  (lost on container restart)
- wireguard_manager: generate_config uses configured address/port instead of
  hardcoded 10.0.0.1 in DNAT rules and Address field
- scripts/setup_cell.py: full setup script — generates WireGuard keys (wg
  binary or Python cryptography fallback), writes wg0.conf and cell_config.json
  with correct _identity key; CELL_NAME / VPN_ADDRESS / WG_PORT env vars
- Makefile: setup target passes env vars through; build-api / build-webui targets
- README: replace install.sh references with make setup && make start

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-22 07:37:11 -04:00
parent 848f8cfc7c
commit 4ed2a6cbae
5 changed files with 307 additions and 139 deletions
+62 -25
View File
@@ -61,45 +61,82 @@ The Personal Internet Cell is a **production-grade, self-hosted, decentralized d
### Prerequisites
- **Docker & Docker Compose** (recommended)
- **Python 3.10+** (for CLI and development)
- **2GB+ RAM, 10GB+ disk space**
- **Ports**: 53, 80, 443, 3000, 51820
- **Docker** with Compose plugin (`docker compose`) or standalone `docker-compose`
- **WireGuard tools** (`wg` binary, for key generation during install)
- **2 GB+ RAM, 10 GB+ disk space**
- **Open ports**: 53 (DNS), 80/443 (HTTP/S), 3000 (API), 8081 (Web UI), 51820/udp (WireGuard)
### 1. Clone and Setup
### 1. Install
```bash
git clone https://github.com/yourusername/PersonalInternetCell.git
cd PersonalInternetCell
git clone <repo-url> pic
cd pic
# Start with Docker (Recommended)
docker-compose up --build
# Default cell (name=mycell, domain=cell, VPN=10.0.0.1/24, port=51820)
make setup && make start
# Or run locally
pip install -r api/requirements.txt
python api/app.py
# Custom cell — required when installing a second cell on a different host
CELL_NAME=pic1 VPN_ADDRESS=10.1.0.1/24 make setup && make start
```
### 2. Access Services
`make setup` generates WireGuard keys, writes `config/wireguard/wg0.conf` and
`config/api/cell_config.json`, and creates all data directories.
`make start` brings up all 13 Docker containers.
- **API**: http://localhost:3000
- **Health Check**: http://localhost:3000/health
- **Service Status**: http://localhost:3000/api/services/status
### 2. Access
### 3. Use the Enhanced CLI
| Service | URL |
|---------|-----|
| Web UI | `http://<host-ip>:8081` |
| API | `http://<host-ip>:3000` |
| Health | `http://<host-ip>:3000/health` |
On a WireGuard client: `http://mycell.cell` (or whatever your cell name is).
### 3. Local dev (no Docker)
```bash
# Show cell status
python api/enhanced_cli.py --status
pip install -r api/requirements.txt
python api/app.py # API on :3000
# Interactive mode
python api/enhanced_cli.py --interactive
cd webui && npm install && npm run dev # React UI on :5173 (proxies API to :3000)
```
# Show all services
python api/enhanced_cli.py --services
---
# Configuration wizard
python api/enhanced_cli.py --wizard network
## 🔗 Connecting Two Cells (PIC Mesh)
Two PIC instances can form a mesh — full site-to-site WireGuard tunnels with
automatic DNS forwarding so each cell's services are reachable from the other.
### Install the second cell
```bash
# On the second host (different VPN subnet; port 51820 is fine — different machine)
CELL_NAME=pic1 VPN_ADDRESS=10.1.0.1/24 make setup && make start
```
### Exchange invites (two pastes, two clicks)
1. On **Cell A** → open Web UI → **Cell Network** → copy the invite JSON.
2. On **Cell B****Cell Network** → paste into "Connect to Another Cell" → click **Connect**.
3. On **Cell B** → copy its invite JSON.
4. On **Cell A** → paste Cell B's invite → click **Connect**.
Both cells now have:
- A site-to-site WireGuard peer (AllowedIPs = remote cell's VPN subnet).
- A CoreDNS forwarding block so `*.pic1.cell` resolves across the tunnel.
The **Connected Cells** panel shows live handshake status (green = online).
### Same-LAN tip
If both cells share the same external IP (behind NAT), the auto-detected
endpoint in the invite will be the public IP. Replace it with the LAN IP
before clicking Connect so traffic stays local:
```json
{ "endpoint": "192.168.31.50:51820", ... }
```
---