PunimTag
Local photo library with face recognition (DeepFace / ArcFace). One monorepo holds the FastAPI backend, React admin UI, and Next.js viewer. Data stays on your machines; there is no cloud dependency for core photo or face storage.
Status: active.
Requirements
- Python 3.12+
- Node.js 18+ (20+ recommended for the viewer)
- PostgreSQL (two databases: app + auth)
- Redis (RQ background jobs)
- Python tkinter (native folder picker in admin Scan)
Quick start
git clone <repository-url>
cd punimtag
./install.sh # Ubuntu/Debian: deps, venv, DBs; elsewhere install Postgres/Redis yourself
cp .env.example .env # set DATABASE_URL, DATABASE_URL_AUTH, SECRET_KEY, ADMIN_*
After install on the viewer:
cd viewer-frontend && npx prisma generate && cd ..
Run three processes:
./run_api_with_worker.sh # API http://127.0.0.1:8000 + RQ worker
cd admin-frontend && npm run dev # http://localhost:3000
cd viewer-frontend && npm run dev # http://localhost:3001
API docs: http://127.0.0.1:8000/docs
Or use root npm scripts: npm run dev:admin, npm run dev:viewer, npm run ci:local.
Config
Root .env (see .env.example):
| Variable | Purpose |
|---|---|
DATABASE_URL |
Main app DB (photos, faces, people, tags) |
DATABASE_URL_AUTH |
Viewer auth / moderation DB |
SECRET_KEY |
JWT signing |
ADMIN_USERNAME / ADMIN_PASSWORD |
Bootstrap admin |
REDIS_URL |
RQ jobs |
PHOTO_STORAGE_DIR |
Uploaded media (default data/uploads) |
Viewer and admin each have their own .env.example under those folders.
Secrets for deployed instances belong in Infisical (/apps/punimtag), not in git.
What it does
- Detect and match faces (RetinaFace + ArcFace by default; other detectors/models configurable)
- Identify people across a library; auto-match with quality scoring
- Search by person, date, tag, folder
- Admin UI for scan/process/identify; viewer UI for browsing
- Hierarchical tags, batch jobs via Redis/RQ
- Network path browsing (UNC on Windows, mounted shares on Linux)
Layout
punimtag/
├── backend/ # FastAPI + SQLAlchemy
├── admin-frontend/ # React + Vite (port 3000)
├── viewer-frontend/ # Next.js (port 3001)
├── e2e/ # Playwright (@levkin/playkit)
├── scripts/ # Install / DB helpers
├── docs/ # Guides and reference
└── install.sh
Docs
| Doc | Purpose |
|---|---|
| docs/README.md | Doc index |
| docs/QUICK_START.md | Day-to-day run commands |
| docs/DEPLOYMENT.md | Deploy overview |
| docs/ARCHITECTURE.md | System design |
| docs/USER_GUIDE.md | Product walkthrough |
| CONTRIBUTING.md | Dev workflow |
| e2e/README.md | End-to-end tests |
Homelab deploy runbooks (hosts, Caddy, monitoring) live in the private
ansible repo, not here.
Security notes
Set strong ADMIN_* and SECRET_KEY before any shared deploy. Older commits
may still show LAN examples; treat matching real passwords as compromised and
rotate. Prefer placeholders in public docs.
Known limits
- Face pipeline is CPU-only for now; first DeepFace model download is large and slow
- Libraries over ~50k photos may need tuning
- Multi-user RBAC is the supported mode (single-user path deprecated)
License
MIT. See LICENSE.