No description
  • Rust 71.5%
  • TypeScript 22.1%
  • CSS 3.2%
  • Shell 1.3%
  • Dockerfile 0.9%
  • Other 1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Satya Benson 975a1b7a72 Add MIT license
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-05 15:26:27 -04:00
crates Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
deploy Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
docs Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
scripts Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
web Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
.env.example Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
.gitignore Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
Cargo.lock Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
Cargo.toml Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
LICENSE Add MIT license 2026-10-05 15:26:27 -04:00
Makefile Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00
README.md Initial commit: photos.benson.earth 2026-10-01 12:33:42 -04:00

photos.benson.earth

Self-hosted family photo library: web gallery, auto-uploaders, local-first ML. Design and roadmap: docs/ARCHITECTURE.md.

Layout

Path What
crates/core Shared Rust: hashing, media sniffing, EXIF/ffprobe metadata, tus metadata, API types
crates/db Postgres pool, migrations (crates/db/migrations), SKIP LOCKED job queue
crates/server API: Authelia header auth, device tokens, tus uploads, timeline, file serving, SPA
crates/worker-media Claims derive jobs: thumbnail, preview, dimensions, thumbhash
crates/cli photos uploader: pair, upload
web React + Vite SPA
deploy Compose stack, Dockerfile, WireGuard / Authelia / Caddy examples

Development (macOS or Linux, no Docker)

Needs Rust, Node + pnpm, and: brew install postgresql@17 pgvector vips ffmpeg (Debian: postgresql-17 postgresql-17-pgvector libvips-tools ffmpeg).

cp .env.example .env
make server     # starts the dev Postgres in .dev/pg (port 54329), migrates, API on :8080
make worker     # second terminal
make web        # third terminal → http://127.0.0.1:5173

.env sets PHOTOS_DEV_USER, which replaces Authelia with a fixed admin user; the server refuses to start with it on a non-loopback address.

Upload something:

cargo build -p photos-cli
export PHOTOS_CONFIG=.dev/cli-config.toml          # keep dev pairing out of ~/.config
target/debug/photos pair --server http://127.0.0.1:8080 --code <code from the Devices page>
target/debug/photos upload ~/some/folder

make test runs the Rust tests and the web typecheck; make check runs clippy and rustfmt. scripts/dev-db.sh psql opens the dev database, scripts/dev-db.sh reset wipes it (also delete .dev/data).

Configuration (server and worker)

Variable Meaning
PHOTOS_DATABASE_URL Postgres with pgvector available
PHOTOS_DATA_DIR Holds originals/, derived/, incoming/
PHOTOS_LISTEN Default 127.0.0.1:8080
PHOTOS_TRUSTED_PROXIES CIDRs whose Remote-User / Remote-Groups headers are believed (the VPS's WireGuard address)
PHOTOS_ADMIN_GROUP Authelia group that sees the Admin page (default photos-admin)
PHOTOS_WEB_DIR Built SPA to serve at /
PHOTOS_MAX_UPLOAD_BYTES Default 4 GiB
PHOTOS_MEDIA_CONCURRENCY Worker parallelism (default: half the cores)
PHOTOS_DEV_USER Development only, see above