feat: add update, reinstall, uninstall, logs-<svc>, shell-<svc> targets

- update: git pull + rebuild + restart
- reinstall: full wipe (config/data) + setup + start
- uninstall: stop, remove images, wipe config/data
- logs-<svc>: follow logs for any single service
- shell-<svc>: exec into any container (bash with sh fallback)
- backup: use sudo tar to read container-owned files
- help: restructured with all commands documented
- README: updated Quick Start + added Management Commands reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-22 09:38:30 -04:00
parent a1a6b65e48
commit 78310a70ba
2 changed files with 297 additions and 215 deletions
+249 -207
View File
@@ -1,207 +1,249 @@
# Personal Internet Cell - Makefile # Personal Internet Cell - Makefile
# Provides easy commands for managing the cell # Provides easy commands for managing the cell
.PHONY: help start stop restart status logs clean setup check-deps init-peers build build-api build-webui .PHONY: help start stop restart status logs clean setup check-deps init-peers \
update reinstall uninstall \
# Detect docker compose command (v2 plugin preferred, fallback to v1 standalone) build build-api build-webui \
DC := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose") start-dns start-api start-wg start-webui \
backup restore \
# Default target test test-all test-unit test-coverage test-api test-cli \
help: test-phase1 test-phase2 test-phase3 test-phase4 test-all-phases \
@echo "Personal Internet Cell - Management Commands" show-routes add-peer list-peers
@echo ""
@echo "Setup (run once on a fresh host):" # Detect docker compose command (v2 plugin preferred, fallback to v1 standalone)
@echo " setup - Create dirs, generate WireGuard keys, write configs, then: make start" DC := $(shell docker compose version >/dev/null 2>&1 && echo "docker compose" || echo "docker-compose")
@echo " Env vars: CELL_NAME=mycell CELL_DOMAIN=cell VPN_ADDRESS=10.0.0.1/24 WG_PORT=51820"
@echo " init-peers - Reset peer list to empty" # Default target
@echo "" help:
@echo "Management:" @echo "Personal Internet Cell - Management Commands"
@echo " start - Start all services (docker compose up -d)" @echo ""
@echo " stop - Stop all services" @echo "First install:"
@echo " restart - Restart all services" @echo " check-deps - Install all required system packages (python3, docker, etc.)"
@echo " status - Show container status + API health" @echo " setup - Generate keys, write configs, create data dirs"
@echo " logs - Follow logs from all services" @echo " Env vars: CELL_NAME=mycell CELL_DOMAIN=cell VPN_ADDRESS=10.0.0.1/24 WG_PORT=51820"
@echo "" @echo " init-peers - Reset peer list to empty"
@echo "Build:" @echo ""
@echo " build - Rebuild API image" @echo "Lifecycle:"
@echo " build-api - Rebuild API image (no cache)" @echo " start - Start all services"
@echo " build-webui - Rebuild Web UI image (no cache)" @echo " stop - Stop all services"
@echo "" @echo " restart - Restart all services"
@echo "Individual Services:" @echo " status - Show container status + API health"
@echo " start-dns - Start DNS service only" @echo " logs - Follow logs from all services"
@echo " start-api - Start API service only" @echo " logs-<svc> - Follow logs for one service (e.g. make logs-api)"
@echo " start-wg - Start WireGuard service only" @echo " shell-<svc> - Open shell in a container (e.g. make shell-api)"
@echo "" @echo ""
@echo "Maintenance:" @echo "Updates & reinstall:"
@echo " clean - Remove all containers and volumes" @echo " update - git pull + rebuild + restart (deploy latest code)"
@echo " backup - Backup configuration and data" @echo " reinstall - Full wipe and fresh install from current git checkout"
@echo " restore - Restore from backup" @echo " uninstall - Remove containers, images, and all data (keeps git repo)"
@echo ""
# Setup commands @echo "Build:"
check-deps: @echo " build - Rebuild API image"
@sudo sh scripts/check_deps.sh @echo " build-api - Rebuild API image (no cache)"
@echo " build-webui - Rebuild Web UI image (no cache)"
setup: check-deps @echo ""
@echo "Setting up Personal Internet Cell..." @echo "Individual services:"
@sudo chown -R $$(id -u):$$(id -g) config/ data/ 2>/dev/null || true @echo " start-dns - Start DNS only"
CELL_NAME=$(or $(CELL_NAME),mycell) \ @echo " start-api - Start API only"
CELL_DOMAIN=$(or $(CELL_DOMAIN),cell) \ @echo " start-wg - Start WireGuard only"
VPN_ADDRESS=$(or $(VPN_ADDRESS),10.0.0.1/24) \ @echo ""
WG_PORT=$(or $(WG_PORT),51820) \ @echo "Maintenance:"
WG_PRIVATE_KEY="$(WG_PRIVATE_KEY)" \ @echo " backup - Backup config + data to backups/"
WG_PUBLIC_KEY="$(WG_PUBLIC_KEY)" \ @echo " restore - List available backups"
python3 scripts/setup_cell.py @echo " clean - Remove containers and volumes (keeps config/data dirs)"
@echo ""
init-peers: @echo "Tests:"
@echo "Initializing peer configuration..." @echo " test - Run all tests"
@echo '[]' > data/api/peers.json @echo " test-coverage - Run tests with HTML coverage report"
@echo "Peer configuration initialized." @echo ""
@echo "Peers:"
# Management commands @echo " list-peers - List configured WireGuard peers"
start: @echo " show-routes - Show WireGuard routing table"
@echo "Starting Personal Internet Cell..."
PUID=$$(id -u) PGID=$$(id -g) $(DC) up -d --build # ── Dependencies & setup ──────────────────────────────────────────────────────
@echo "Services started. Check status with 'make status'"
check-deps:
stop: @sudo sh scripts/check_deps.sh
@echo "Stopping Personal Internet Cell..."
PUID=$$(id -u) PGID=$$(id -g) $(DC) down setup: check-deps
@echo "Services stopped." @echo "Setting up Personal Internet Cell..."
@sudo chown -R $$(id -u):$$(id -g) config/ data/ 2>/dev/null || true
restart: CELL_NAME=$(or $(CELL_NAME),mycell) \
@echo "Restarting Personal Internet Cell..." CELL_DOMAIN=$(or $(CELL_DOMAIN),cell) \
PUID=$$(id -u) PGID=$$(id -g) $(DC) restart VPN_ADDRESS=$(or $(VPN_ADDRESS),10.0.0.1/24) \
@echo "Services restarted." WG_PORT=$(or $(WG_PORT),51820) \
WG_PRIVATE_KEY="$(WG_PRIVATE_KEY)" \
status: WG_PUBLIC_KEY="$(WG_PUBLIC_KEY)" \
@echo "Personal Internet Cell Status:" python3 scripts/setup_cell.py
@echo "================================"
$(DC) ps init-peers:
@echo "" @echo "Initializing peer configuration..."
@echo "API Status:" @echo '[]' > data/api/peers.json
@curl -s http://localhost:3000/health || echo "API not responding" @echo "Peer configuration initialized."
logs: # ── Lifecycle ─────────────────────────────────────────────────────────────────
@echo "Showing logs from all services..."
$(DC) logs -f start:
@echo "Starting Personal Internet Cell..."
# Individual service commands PUID=$$(id -u) PGID=$$(id -g) $(DC) up -d --build
start-dns: @echo "Services started. Check status with 'make status'"
@echo "Starting DNS service..."
$(DC) up -d dns stop:
@echo "Stopping Personal Internet Cell..."
start-api: PUID=$$(id -u) PGID=$$(id -g) $(DC) down
@echo "Starting API service..." @echo "Services stopped."
$(DC) up -d api
restart:
start-wg: @echo "Restarting Personal Internet Cell..."
@echo "Starting WireGuard service..." PUID=$$(id -u) PGID=$$(id -g) $(DC) restart
$(DC) up -d wireguard @echo "Services restarted."
start-webui: status:
@echo "Starting WebUi service..." @echo "Personal Internet Cell Status:"
$(DC) up -d webui @echo "================================"
$(DC) ps
# Maintenance commands @echo ""
clean: @echo "API Status:"
@echo "Cleaning up containers and volumes..." @curl -s http://localhost:3000/health || echo "API not responding"
$(DC) down -v
docker system prune -f logs:
@echo "Cleanup complete." $(DC) logs -f
backup: logs-%:
@echo "Creating backup..." $(DC) logs -f $*
@mkdir -p backups
@tar -czf backups/cell-backup-$(shell date +%Y%m%d-%H%M%S).tar.gz \ shell-%:
config/ data/ docker-compose.yml Makefile README.md docker exec -it cell-$* /bin/bash 2>/dev/null || docker exec -it cell-$* /bin/sh
@echo "Backup created in backups/ directory."
# ── Updates & reinstall ───────────────────────────────────────────────────────
restore:
@echo "Available backups:" update:
@ls -la backups/cell-backup-*.tar.gz 2>/dev/null || echo "No backups found" @echo "Pulling latest code..."
@echo "" git pull
@echo "To restore, run: tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz" @echo "Rebuilding and restarting services..."
PUID=$$(id -u) PGID=$$(id -g) $(DC) up -d --build
# Development commands @echo "Update complete. Run 'make status' to verify."
dev:
@echo "Starting development environment..." reinstall:
$(DC) -f docker-compose.yml -f docker-compose.dev.yml up -d @echo "Reinstalling Personal Internet Cell from scratch..."
PUID=$$(id -u) PGID=$$(id -g) $(DC) down -v 2>/dev/null || true
build: @sudo rm -rf config/ data/
@echo "Building API service..." @$(MAKE) setup
$(DC) build api @$(MAKE) start
@echo "Reinstall complete."
build-api:
@echo "Rebuilding API (no cache)..." uninstall:
$(DC) build --no-cache api @echo "Uninstalling Personal Internet Cell..."
$(DC) up -d api PUID=$$(id -u) PGID=$$(id -g) $(DC) down -v --rmi all 2>/dev/null || true
@sudo rm -rf config/ data/
build-webui: @echo "Uninstall complete. Git repo and scripts remain."
@echo "Rebuilding Web UI (no cache)..."
$(DC) build --no-cache webui # ── Build ─────────────────────────────────────────────────────────────────────
$(DC) up -d webui
build:
# Testing commands @echo "Building API service..."
test: $(DC) build api
@echo "Running all unit and integration tests with pytest..."
pytest tests/ api/tests/ build-api:
@echo "Rebuilding API (no cache)..."
test-all: $(DC) build --no-cache api
@echo "Running all tests using the unified test runner..." $(DC) up -d api
python3 api/tests/run_tests.py
build-webui:
# Remove or update old test targets that reference non-existent files @echo "Rebuilding Web UI (no cache)..."
test-unit: $(DC) build --no-cache webui
@echo "Running unit tests only..." $(DC) up -d webui
pytest tests/
# ── Individual services ───────────────────────────────────────────────────────
test-coverage:
@echo "Running tests with coverage..." start-dns:
pytest tests/ api/tests/ --cov=api --cov-report=html --cov-report=term-missing -v $(DC) up -d dns
test-api: start-api:
@echo "Testing API endpoints..." $(DC) up -d api
cd api && python3 -m pytest tests/test_api_endpoints.py -v
start-wg:
test-cli: $(DC) up -d wireguard
@echo "Testing CLI tool..."
cd api && python3 -m pytest tests/test_cli_tool.py -v start-webui:
$(DC) up -d webui
test-phase1:
@echo "Testing Phase 1 (Network Foundation)..." # ── Maintenance ───────────────────────────────────────────────────────────────
cd api && python3 -m pytest tests/test_network_manager.py tests/test_phase1_endpoints.py -v
clean:
test-phase2: @echo "Removing containers and volumes..."
@echo "Testing Phase 2 (WireGuard & Peer Registry)..." $(DC) down -v
cd api && python3 -m pytest tests/test_wireguard_manager.py tests/test_phase2_endpoints.py -v docker system prune -f
@echo "Done. config/ and data/ are untouched."
test-phase3:
@echo "Testing Phase 3 (Core Digital Services)..." backup:
cd api && python3 -m pytest tests/test_phase3_managers.py tests/test_phase3_endpoints.py -v @echo "Creating backup..."
@mkdir -p backups
test-phase4: @sudo tar -czf backups/cell-backup-$(shell date +%Y%m%d-%H%M%S).tar.gz \
@echo "Testing Phase 4 (VPN Gateway & Routing)..." config/ data/ docker-compose.yml Makefile README.md
cd api && python3 -m pytest tests/test_phase4_routing.py tests/test_phase4_endpoints.py -v @sudo chown $$(id -u):$$(id -g) backups/cell-backup-*.tar.gz
@echo "Backup created in backups/."
test-all-phases:
@echo "Testing all phases..." restore:
cd api && python3 -m pytest tests/ -v @echo "Available backups:"
@ls -lh backups/cell-backup-*.tar.gz 2>/dev/null || echo "No backups found."
# Network commands @echo ""
show-routes: @echo "To restore: tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz"
@echo "Current routing table:"
@docker exec cell-wireguard wg show || echo "WireGuard not running" # ── Tests ─────────────────────────────────────────────────────────────────────
add-peer: test:
@echo "Usage: make add-peer PEER_NAME=name PEER_IP=ip PEER_KEY=public_key" @echo "Running all tests..."
@if [ -n "$(PEER_NAME)" ] && [ -n "$(PEER_IP)" ] && [ -n "$(PEER_KEY)" ]; then \ pytest tests/ api/tests/
curl -X POST http://localhost:3000/api/peers \
-H "Content-Type: application/json" \ test-all:
-d '{"name":"$(PEER_NAME)","ip":"$(PEER_IP)","public_key":"$(PEER_KEY)"}'; \ python3 api/tests/run_tests.py
else \
echo "Please provide PEER_NAME, PEER_IP, and PEER_KEY parameters"; \ test-unit:
fi pytest tests/
list-peers: test-coverage:
@echo "Configured peers:" pytest tests/ api/tests/ --cov=api --cov-report=html --cov-report=term-missing -v
@curl -s http://localhost:3000/api/peers | python3 -m json.tool || echo "API not responding"
test-api:
cd api && python3 -m pytest tests/test_api_endpoints.py -v
test-cli:
cd api && python3 -m pytest tests/test_cli_tool.py -v
test-phase1:
cd api && python3 -m pytest tests/test_network_manager.py tests/test_phase1_endpoints.py -v
test-phase2:
cd api && python3 -m pytest tests/test_wireguard_manager.py tests/test_phase2_endpoints.py -v
test-phase3:
cd api && python3 -m pytest tests/test_phase3_managers.py tests/test_phase3_endpoints.py -v
test-phase4:
cd api && python3 -m pytest tests/test_phase4_routing.py tests/test_phase4_endpoints.py -v
test-all-phases:
cd api && python3 -m pytest tests/ -v
# ── Network / peers ───────────────────────────────────────────────────────────
show-routes:
@docker exec cell-wireguard wg show 2>/dev/null || echo "WireGuard not running"
list-peers:
@curl -s http://localhost:3000/api/peers | python3 -m json.tool || echo "API not responding"
add-peer:
@if [ -n "$(PEER_NAME)" ] && [ -n "$(PEER_IP)" ] && [ -n "$(PEER_KEY)" ]; then \
curl -X POST http://localhost:3000/api/peers \
-H "Content-Type: application/json" \
-d '{"name":"$(PEER_NAME)","ip":"$(PEER_IP)","public_key":"$(PEER_KEY)"}'; \
else \
echo "Usage: make add-peer PEER_NAME=name PEER_IP=10.0.0.x PEER_KEY=<pubkey>"; \
fi
# ── Dev ───────────────────────────────────────────────────────────────────────
dev:
$(DC) -f docker-compose.yml -f docker-compose.dev.yml up -d
+48 -8
View File
@@ -61,8 +61,7 @@ The Personal Internet Cell is a **production-grade, self-hosted, decentralized d
### Prerequisites ### Prerequisites
- **Docker** with Compose plugin (`docker compose`) or standalone `docker-compose` - **Debian/Ubuntu** host (apt-based). All other dependencies are installed automatically.
- **WireGuard tools** (`wg` binary, for key generation during install)
- **2 GB+ RAM, 10 GB+ disk space** - **2 GB+ RAM, 10 GB+ disk space**
- **Open ports**: 53 (DNS), 80/443 (HTTP/S), 3000 (API), 8081 (Web UI), 51820/udp (WireGuard) - **Open ports**: 53 (DNS), 80/443 (HTTP/S), 3000 (API), 8081 (Web UI), 51820/udp (WireGuard)
@@ -72,16 +71,22 @@ The Personal Internet Cell is a **production-grade, self-hosted, decentralized d
git clone <repo-url> pic git clone <repo-url> pic
cd pic cd pic
# Default cell (name=mycell, domain=cell, VPN=10.0.0.1/24, port=51820) # Install all system dependencies (docker, python3, python3-cryptography, etc.)
make setup && make start make check-deps
# Custom cell — required when installing a second cell on a different host # Default cell (name=mycell, domain=cell, VPN=10.0.0.1/24, port=51820)
make setup
make start
# Custom cell — use when installing a second cell on a different host
CELL_NAME=pic1 VPN_ADDRESS=10.1.0.1/24 make setup && make start CELL_NAME=pic1 VPN_ADDRESS=10.1.0.1/24 make setup && make start
``` ```
`make setup` generates WireGuard keys, writes `config/wireguard/wg0.conf` and `make check-deps` installs python3, python3-cryptography, docker, docker-compose, curl, openssl, git via apt and adds the current user to the docker group.
`config/api/cell_config.json`, and creates all data directories.
`make start` brings up all 13 Docker containers. `make setup` generates WireGuard keys, writes configs, and creates all data directories.
`make start` builds and brings up all 12 Docker containers.
### 2. Access ### 2. Access
@@ -104,6 +109,41 @@ cd webui && npm install && npm run dev # React UI on :5173 (proxies API to :
--- ---
## 🛠️ Management Commands
```bash
# First install
make check-deps # install all system packages via apt
make setup # generate keys, write configs
make start # start all 12 containers
# Daily operations
make status # container status + API health
make logs # follow all logs
make logs-api # follow logs for one service (api, dns, wg, mail, caddy, ...)
make shell-api # open a shell inside a container
# Deploy latest code
make update # git pull + rebuild + restart
# Full wipe and reinstall (useful on test machine)
make reinstall # stop, wipe config/data, setup, start fresh
# Remove everything
make uninstall # stop containers, remove images and all data
# Maintenance
make backup # tar config/ + data/ into backups/
make restore # list available backups
make clean # remove containers/volumes, keep config/data
# Tests
make test # run all tests
make test-coverage # tests + HTML coverage report
```
---
## 🔗 Connecting Two Cells (PIC Mesh) ## 🔗 Connecting Two Cells (PIC Mesh)
Two PIC instances can form a mesh — full site-to-site WireGuard tunnels with Two PIC instances can form a mesh — full site-to-site WireGuard tunnels with