Email, calendar, and files are now optional store services, not always-on builtins. Updated README, QUICKSTART, Wiki, and service-developer-guide to reflect: dynamic nav, optional service install flow, correct egress identifiers (wireguard_ext/default vs wireguard/cell_internet), removed builtin/store distinction from manifest reference, 7 core containers. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.1 KiB
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
The installer handles all software dependencies (git, docker, make, etc.) automatically.
Option A — One-line installer (recommended)
curl -fsSL https://install.pic.ngo | sudo bash
Always review the script before running it:
curl -fsSL https://install.pic.ngo | less
The installer:
- Detects your OS and installs Docker, git, make via the system package manager
- Creates a
picsystem user and adds it to thedockergroup - Clones the repository to
/opt/pic - Runs
make install(generates keys and config, writes a systemd unit) - Runs
make start-coreto bring up the core containers - Waits for the API to respond, then prints the wizard URL
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.
git clone https://git.pic.ngo/roof/pic.git pic
cd pic
sudo make install
make start-core
Then open http://<host-ip>:8081 in a browser.
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.ngosubdomain with Let's Encrypt via DNS-01 (recommended for internet-facing cells)cloudflare— Let's Encrypt via Cloudflare DNS-01 (bring your own domain)duckdns— Let's Encrypt via DuckDNS DNS-01http01— Let's Encrypt via HTTP-01 (no wildcard; cell must be reachable on port 80)lan— internal CA, 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.
- Click Add Peer.
- Enter a peer name (e.g.
laptop). - The API generates a key pair and assigns the next available VPN IP automatically.
- Click the QR code icon to display the peer configuration as a QR code.
- 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:
- Go to Services in the sidebar.
- Find the service card (Email, Calendar, Files, or any other listed service).
- Click Install. PIC fetches the manifest, starts the container, and wires up DNS and Caddy routes automatically.
- 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:
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
# 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
make backup # archives config/ and data/ into backups/cell-backup-<timestamp>.tar.gz
make restore # list available backups
To restore manually:
tar -xzf backups/cell-backup-YYYYMMDD-HHMMSS.tar.gz
make start
Updating PIC
make update # git pull + rebuild + restart
Uninstalling
make uninstall # stops containers; prompts to also delete config/ and data/
Troubleshooting
Containers not starting
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:
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 load the kernel module
sudo modprobe wireguard
On minimal installs you may need wireguard-tools and the kernel headers for the running kernel.
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:
make reset-admin-password
This generates a new admin password and prints it.
Forgot the admin password
make show-admin-password # print current password
make reset-admin-password # generate a new random password