Here’s the thing: I had 47,000 photos scattered across drives, phone backups, and cloud services. Google Photos was convenient until I realized I was paying for storage I didn’t need and letting their AI train on my family photos. So I built PhotoPrism on my homelab, and three months later I genuinely can’t imagine going back.
PhotoPrism is a self-hosted photo management system with local AI that does what Google Photos does โ face recognition, object tagging, location mapping, color analysis โ except it all runs on your hardware. No subscriptions. No cloud vendor lock-in. No wondering where your private moments actually live.
Why This Isn’t Just Another Photo App
Most self-hosted photo tools are basically fancy file browsers. PhotoPrism is different because it actually understands your photos using AI that runs entirely on your machine. Upload a batch of 500 vacation photos and come back in 20 minutes โ they’re automatically tagged, faces are recognized, locations are mapped, and they’re browsable by people, places, or things.
The face recognition alone is worth the setup time. I can search “Sarah” and get every photo my kid appears in across six years of photos. No training Google’s models. No feeding your biometric data into a corporation. It’s just… your computer doing smart things with your own data.
And it supports RAW files. If you’re shooting with a real camera, this matters. JPEG-only tools are for people who haven’t invested in decent glass yet.
The Install (Stupidly Easy with Docker)
If you’re running Docker on your homelab, PhotoPrism takes maybe 10 minutes. Here’s my prod-ready Compose file:
version: '3.8'
services:
photoprism:
image: photoprism/photoprism:latest
container_name: photoprism
ports:
- "2342:2342"
environment:
PHOTOPRISM_ADMIN_PASSWORD: "your-secure-password"
PHOTOPRISM_DB_DRIVER: "mysql"
PHOTOPRISM_DB_DSN: "photoprism:password@tcp(mariadb:3306)/photoprism?charset=utf8mb4,utf8&parseTime=true"
PHOTOPRISM_ORIGINALS_LIMIT: "5000"
PHOTOPRISM_WORKERS: "4"
PHOTOPRISM_DETECT_NSFW: "false"
PHOTOPRISM_UPLOAD_NSFW: "true"
PHOTOPRISM_DARKTABLE_PRESETS: "false"
volumes:
- "./photoprism/storage:/photoprism/storage"
- "/mnt/nas/photos:/photoprism/originals:rw"
depends_on:
- mariadb
restart: unless-stopped
mariadb:
image: mariadb:11
container_name: photoprism-db
environment:
MARIADB_ROOT_PASSWORD: "root-password"
MARIADB_DATABASE: "photoprism"
MARIADB_USER: "photoprism"
MARIADB_PASSWORD: "password"
volumes:
- "./photoprism/database:/var/lib/mysql"
restart: unless-stopped
Mount your photos directory to /photoprism/originals and you’re done. On first boot it’ll index everything and start crunching AI models. With a Ryzen 5 I’m processing about 10-15 photos per second. If you have GPU acceleration (NVIDIA with CUDA support), you can double that.
Real talk: The initial indexing will hammer your CPU. I let mine run overnight on my first 30GB import. Planning indexing during off-peak hours isn’t romantic but it’s smart.
Making It Actually Usable in Your Homelab
Bare localhost:2342 works, but you probably want this behind Traefik with a proper domain. If you’re already running Traefik on your lab (and if you’re not, start here), throw this label block in your Compose:
labels:
- "traefik.enable=true"
- "traefik.http.routers.photoprism.rule=Host(`photos.yourdomain.local`)"
- "traefik.http.routers.photoprism.entrypoints=websecure"
- "traefik.http.routers.photoprism.tls=true"
- "traefik.http.services.photoprism.loadbalancer.server.port=2342"
Now access it from anywhere on your network via HTTPS with a real cert. You can even expose it externally with Cloudflare Tunnel if you want mobile access (which honestly, you do โ checking photos from the couch is the small joy we deserve).
I integrated it with Home Assistant via a custom iframe card. My family can now pull up the photo feed from our living room dashboard. Sounds gimmicky until you realize you never need to fiddle with your phone to show vacation highlights.
Performance Tweaks That Actually Matter
PhotoPrism’s config is smart but has some levers worth pulling.
GPU acceleration: If you have an NVIDIA card, enable CUDA in your Compose:
environment:
PHOTOPRISM_TENSORFLOW_OFF: "false"
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
This makes face recognition screaming fast. I went from 10 hours on CPU to 40 minutes on a GTX 1080.
Storage: Keep originals on fast storage if possible. SSD for the database (MariaDB), HDD for photo archives is fine since reads are sequential. Don’t put PhotoPrism’s cache on network storage โ it’ll thrash your network.
Workers: Set PHOTOPRISM_WORKERS to 75% of your CPU cores. My 6-core Ryzen uses 4 workers. More doesn’t help; it just thrashes.
One command worth knowing: if indexing gets stuck, a full rescan is just docker exec photoprism photoprism index -f. Learned that the hard way after a storage reshuffle.
The Real-World Payoff
After three months running this, my photo life has fundamentally changed. I’m not thinking about “where should this live” anymore. I point PhotoPrism at my NAS and it just… figures it out.
Search “beach” and get 400 photos. Search “Jack” and get every photo of my son. Browse by color, by camera model, by the month. Create smart albums with search queries that update automatically.
And the privacy angle isn’t abstract โ it’s tangible. I have five years of my family’s life in this system. That’s not going to a third party. That’s not training a model. That’s mine.
The money math is pretty simple: Google One is $100/year for 2TB. I’m a storage hoarder, so I’d be paying $200+ annually. PhotoPrism cost me one afternoon and runs free forever on hardware I already owned. That’s a 12-month payback, and it just gets better from there.
If you’ve got a homelab and a pile of photos you actually care about, this is non-negotiable. Set it up this weekend.
Explore PhotoPrism in our AI Homelab Toolkit.
Recommended Hardware & Hosting
Build your homelab with hardware tested and used by our team.
Affiliate links โ we may earn a small commission at no extra cost to you.