8a9f4f50c6
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>
256 lines
7.8 KiB
Markdown
256 lines
7.8 KiB
Markdown
# Quick Start
|
|
|
|
This guide walks through a first-time PIC installation on a clean Linux host.
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- Linux x86-64 host — Debian, Ubuntu, Fedora, RHEL, or Alpine
|
|
- 2 GB+ RAM, 10 GB+ disk
|
|
- Always-required ports: 53, 80, 443, 51820/udp
|
|
- Email service only (when installed): 25, 587, 993
|
|
- WireGuard kernel module available on the host (`modprobe wireguard`); required — userspace WireGuard is not supported
|
|
|
|
The installer handles all software dependencies (git, docker, make, etc.) automatically.
|
|
|
|
---
|
|
|
|
## Option A — One-line installer (recommended)
|
|
|
|
```bash
|
|
curl -fsSL https://install.pic.ngo | sudo bash
|
|
```
|
|
|
|
Always review the script before running it:
|
|
|
|
```bash
|
|
curl -fsSL https://install.pic.ngo | less
|
|
```
|
|
|
|
The installer runs 7 steps and prints clean one-line progress for each. Run with `PIC_DEBUG=1` or `--debug` for full verbose output. A complete log is always written to `/var/log/pic-install.log`.
|
|
|
|
The installer:
|
|
1. Detects your OS and installs Docker, git, make via the system package manager
|
|
2. Installs and starts host NTP (chrony) — required for ACME certificate issuance and DDNS token registration
|
|
3. Creates a `pic` system user and adds it to the `docker` group
|
|
4. Clones the repository to `/opt/pic`
|
|
5. Runs `make install` — generates keys and config, writes a systemd unit. The admin password is printed once here; it does not appear again.
|
|
6. Runs `make start-core` to bring up the six core containers
|
|
7. Enables the `pic` systemd unit so the stack starts on reboot, then waits for the API health check
|
|
|
|
When it finishes, open the URL it prints:
|
|
|
|
```
|
|
http://<host-ip>:8081/setup
|
|
```
|
|
|
|
---
|
|
|
|
## Option B — Manual install
|
|
|
|
Use this if you want to control where PIC is installed, or if you are installing on a machine that already has Docker.
|
|
|
|
```bash
|
|
git clone https://git.pic.ngo/roof/pic.git pic
|
|
cd pic
|
|
sudo make install
|
|
make start-core
|
|
```
|
|
|
|
Then open `http://<host-ip>:8081/setup` in a browser.
|
|
|
|
Note: install host NTP before running `make install` if you plan to use `pic_ngo` domain mode. The installer does this automatically in Option A.
|
|
|
|
```bash
|
|
sudo apt-get install -y chrony && sudo systemctl enable --now chrony
|
|
```
|
|
|
|
---
|
|
|
|
## Complete the setup wizard
|
|
|
|
The setup wizard appears automatically on first start. All API requests redirect to `/setup` until it is finished.
|
|
|
|
The wizard asks for:
|
|
|
|
- **Cell name** — used for hostnames and DDNS subdomain. Lowercase letters, digits, hyphens, 2–31 characters. Example: `myhome`.
|
|
- **Domain mode** — how HTTPS certificates are issued:
|
|
- `pic_ngo` — automatic `<cell-name>.pic.ngo` subdomain with a wildcard Let's Encrypt cert via DNS-01 (recommended for internet-facing cells; requires accurate host clock)
|
|
- `cloudflare` — wildcard Let's Encrypt cert via Cloudflare DNS-01 (bring your own domain)
|
|
- `duckdns` — Let's Encrypt via DuckDNS DNS-01
|
|
- `http01` — Let's Encrypt via HTTP-01 (no wildcard; cell must be reachable on port 80)
|
|
- `lan` — internal CA only, no internet required (for LAN-only installs)
|
|
- **Timezone**
|
|
- **Services to install** — email, calendar, files (optional; installed in the background after setup completes; can be added later via the Services store page)
|
|
- **Admin password** — minimum 12 characters, must contain uppercase, lowercase, and a digit
|
|
|
|
Click **Complete Setup**. The wizard creates the admin account, writes cell identity to `config/api/cell_config.json`, and redirects to the login page. Any services you selected begin installing in the background.
|
|
|
|
---
|
|
|
|
## Log in
|
|
|
|
After the wizard you are redirected to `/login`.
|
|
|
|
- **Username:** `admin`
|
|
- **Password:** the password you set in the wizard
|
|
|
|
---
|
|
|
|
## Add a WireGuard peer
|
|
|
|
Go to **Peers** in the sidebar.
|
|
|
|
1. Click **Add Peer**.
|
|
2. Enter a peer name (e.g. `laptop`).
|
|
3. The API generates a key pair and assigns the next available VPN IP automatically.
|
|
4. Click the QR code icon to display the peer configuration as a QR code.
|
|
5. Scan the QR code with a WireGuard client (Android, iOS, or the WireGuard desktop app).
|
|
|
|
Once connected, `*.cell` names resolve through the cell's CoreDNS and traffic can be routed through the cell.
|
|
|
|
---
|
|
|
|
## Installing and managing services
|
|
|
|
Email, calendar, and file storage are optional services installed from the built-in service store. They are not running by default.
|
|
|
|
**To install a service:**
|
|
|
|
1. Go to **Services** in the sidebar.
|
|
2. Find the service card (Email, Calendar, Files, or any other listed service).
|
|
3. Click **Install**. PIC fetches the manifest, starts the container, and wires up DNS and Caddy routes automatically.
|
|
4. The service appears in the sidebar navigation once installation completes.
|
|
|
|
**To check service status:**
|
|
|
|
The Services page shows each installed service as "running" or "stopped". You can also check via the API:
|
|
|
|
```bash
|
|
curl -s http://<host-ip>:3000/api/services/active
|
|
```
|
|
|
|
**To uninstall a service:**
|
|
|
|
Click **Uninstall** on the service card. The container is stopped and removed. Data in `data/services/<id>/` is kept on disk unless you delete it manually.
|
|
|
|
---
|
|
|
|
## Day-to-day operations
|
|
|
|
```bash
|
|
# Check container status and API health
|
|
make status
|
|
|
|
# Follow logs from all services
|
|
make logs
|
|
|
|
# Follow logs from a single service
|
|
make logs-api
|
|
make logs-wireguard
|
|
make logs-caddy
|
|
|
|
# Open a shell inside a container
|
|
make shell-api
|
|
make shell-dns
|
|
```
|
|
|
|
---
|
|
|
|
## Backup and restore
|
|
|
|
```bash
|
|
make backup # archives config/ and data/ into backups/cell-backup-<timestamp>.tar.gz
|
|
make restore # list available backups
|
|
```
|
|
|
|
The backup archive is written mode `0600`. It contains secrets and key material — WireGuard keys, the internal CA, vault keys, admin credentials, DDNS token, cell links, and Caddy certificates. Store it securely.
|
|
|
|
Data volumes for installed store services (email mailboxes, calendar data, file storage) are captured separately via the API-driven backup (`POST /api/config/backup`), which also supports an optional passphrase for encryption at rest. The encrypted file is named `<backup_id>.tar.gz.age`.
|
|
|
|
To restore from a `make backup` archive:
|
|
|
|
```bash
|
|
tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz
|
|
make restart
|
|
```
|
|
|
|
After restore, the API re-generates the Caddyfile and Corefile from the restored config and re-applies routing rules automatically.
|
|
|
|
---
|
|
|
|
## Updating PIC
|
|
|
|
```bash
|
|
make update # git pull + rebuild + restart
|
|
```
|
|
|
|
---
|
|
|
|
## Uninstalling
|
|
|
|
```bash
|
|
make uninstall # stops containers; prompts to also delete config/ and data/
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Containers not starting
|
|
|
|
```bash
|
|
make logs
|
|
make logs-api
|
|
```
|
|
|
|
Look for errors about missing config files or port conflicts.
|
|
|
|
### Port 53 already in use
|
|
|
|
On Ubuntu and Debian, `systemd-resolved` listens on port 53. Disable it:
|
|
|
|
```bash
|
|
sudo systemctl disable --now systemd-resolved
|
|
sudo rm /etc/resolv.conf
|
|
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
|
|
```
|
|
|
|
Then run `make start` again.
|
|
|
|
### WireGuard container fails to start
|
|
|
|
The WireGuard container runs unprivileged (NET_ADMIN only, no privileged mode). It requires the host kernel's WireGuard module — either compiled in (Linux 5.6+) or loadable.
|
|
|
|
```bash
|
|
sudo modprobe wireguard
|
|
```
|
|
|
|
On minimal installs you may need `wireguard-tools` and the kernel headers for the running kernel. On kernels that lack a builtin WireGuard module, check your distro's `wireguard-dkms` or `wireguard-linux-compat` package.
|
|
|
|
### API returns 428 and redirects to /setup
|
|
|
|
The first-run wizard has not been completed. Open `http://<host-ip>:8081` and finish the wizard.
|
|
|
|
### API returns 401 / UI shows "Not authenticated"
|
|
|
|
Your session expired or you have not logged in. Go to `http://<host-ip>:8081/login`.
|
|
|
|
### API returns 503 "Authentication not configured"
|
|
|
|
The auth file exists but contains no accounts. To recover:
|
|
|
|
```bash
|
|
make reset-admin-password
|
|
```
|
|
|
|
This generates a new admin password and prints it.
|
|
|
|
### Forgot the admin password
|
|
|
|
```bash
|
|
make show-admin-password # print current password
|
|
make reset-admin-password # generate a new random password
|
|
```
|