Table of Contents
Status: Active | Owner: @roof | Updated: 2026-06-11
Dev – Overview
This is the developer guide for contributors to PIC and for developers building services for the PIC service store.
Sections
| Page | What it covers |
|---|---|
| Dev – Architecture | Container stack, manager pattern, service bus, data model, connectivity v2 |
| Dev – Build a Store Service | Manifest schema v3, compose templates, account provisioning, backup, egress |
| Dev – API Reference | Auth model, CSRF, key endpoints, connectivity v2 API |
| Dev – Testing | Unit tests (pytest), webui (vitest), integration, e2e, CI |
| Dev – Install Internals | install.sh steps, make targets, systemd unit, PIC_DEBUG |
| Dev – Service Manifest Reference | Complete field-by-field manifest reference, compose variables, HTTP account API |
Quick start for local development
# Run on: your development machine, with Docker installed
git clone https://git.pic.ngo/roof/pic.git pic
cd pic
make start
# open http://<host-ip>:8081 — wizard appears automatically
Run the Flask API without Docker (useful for rapid iteration):
# Run on: your development machine
pip install -r api/requirements.txt
python api/app.py # listens on :3000
Run the React UI dev server (proxies /api to :3000):
# Run on: your development machine
cd webui && npm install && npm run dev # listens on :5173
After code changes:
# Run on: your development machine, from the repo root
make build-api # rebuild only the API container
make build-webui # rebuild only the webui container
make restart # restart containers without rebuild
Key conventions
- All container lifecycle goes through
maketargets. Never calldockerordocker composedirectly in development. - All API calls from the UI go through
webui/src/services/api.js. Never add a new Axios instance or rawfetchcall. - Business logic belongs in manager classes, not in Flask route handlers. Route handlers should validate input, call the manager, and return JSON.
- Config reads always go through
ConfigManager. Never opencell_config.jsondirectly. - Run
make testbefore committing. The pre-commit hook blocks commits that fail tests.
Repository layout
api/ Flask API and all service managers
webui/ React SPA (Vite + Tailwind)
tests/ pytest unit tests
tests/integration/ require a running PIC stack
tests/e2e/ Playwright UI and WireGuard tests
config/ Runtime config (mostly git-ignored)
data/ Runtime secrets and state (fully git-ignored)
scripts/ Setup and maintenance scripts
install.sh One-line installer
Makefile All operational commands
docker-compose.yml
Personal Internet Cell
New here?
Users
User – Connect to the VPN User – Use Your Services User – Troubleshooting
Admins
Admin – Overview Admin – Install and First Run Admin – Configure Domains and TLS Admin – Manage Services Admin – Configure Connectivity Admin – Manage Peers Admin – Back Up and Restore Admin – Logging and Audit Admin – Monitor and Troubleshoot
Developers
Dev – Overview Dev – Architecture Dev – Build a Store Service Dev – Service Manifest Reference Dev – API Reference Dev – Testing Dev – Install Internals
Decisions (ADRs)
ADR – 001 Store Images Are Signed and Verified by Cells ADR – 002 Named Connection Instances for Connectivity ADR – 003 All Optional Functionality Ships as Store Services
Meta
Meta – Glossary Meta – Template Runbook Meta – Template ADR
Archive
Archive – User Guide Archive – ADR 004 The Wiki Is the Single Documentation Source