ilia 64c1d3818a
CI / skip-ci-check (push) Successful in 43s
CI / docker-ci (push) Successful in 44s
CI / python-lint (push) Successful in 44s
CI / secret-scan (push) Successful in 51s
CI / admin-unit (push) Successful in 1m56s
CI / e2e (push) Successful in 2m54s
CI / viewer-unit (push) Successful in 3m6s
Merge pull request 'docs: humanize guides and scratch docs' (#109) from docs/humanize-wave into master
2026-08-06 09:55:25 -05:00
2025-09-15 12:16:01 -04:00
2026-07-26 15:46:28 -05:00

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.

S
Description
PunimTag web application
Readme MIT
86 MiB
Languages
TypeScript 60.7%
Python 36.1%
Shell 2.7%
CSS 0.3%
JavaScript 0.1%
Other 0.1%