Why self-host PhotoPrism on a VPS
Where Immich aims for the full cloud experience with real-time mobile backup, PhotoPrism focuses on indexing and organizing an existing photo library, often large, sitting on a file system. It analyzes your folders, sorts photos by labels (mountain, beach, car), detects faces, reads EXIF and geocodes pictures. All of this runs locally via embedded TensorFlow. Hosting it on a VPS has a twofold benefit: centralizing photo archives scattered on a disk accessible from anywhere, and getting automatic tagging without ever transmitting the images to a third-party service. PhotoPrism works with MariaDB for good performance and directly reads an originals folder that you fill via WebDAV, rsync or a mount.
The strengths of a self-hosted PhotoPrism
- Automatic tagging by local AI: search by keywords, locations and colors without a cloud.
- Indexing of existing archives placed on disk, via WebDAV, rsync or network mount.
- Detection of duplicates and similar photos to clean up a cluttered collection.
- Interactive maps based on the GPS coordinates extracted from EXIF metadata.
- Read-only mode available: PhotoPrism indexes without ever modifying your original files.
- Installable PWA interface, accessible from any browser on your network.
Hardware and software requirements
PhotoPrism recommends at least 4 GB of physical RAM, part of which will serve the TensorFlow indexing operations; below that, analysis becomes slow or fails on large libraries. 2 vCPUs are enough for personal use, but the initial indexing of a large archive benefits from additional cores. Storage must cover your originals plus about 30% for thumbnails and cache. On the software side: Docker and docker compose v2, MariaDB 10.5+ (strongly preferable to SQLite for large collections), a domain (galerie.yourcompany.com), and ideally some swap to absorb indexing spikes on modest VPSes.
Deploy PhotoPrism step by step
Prepare the VPS and volumes
Install Docker, then create two persistent folders: /opt/photoprism/originals for your photos and /opt/photoprism/storage for the cache and the index database. Separating these volumes simplifies backups.
Declare PhotoPrism and MariaDB
In docker-compose.yml, add a mariadb service with a dedicated volume and a photoprism service (image photoprism/photoprism:latest). Link them via PHOTOPRISM_DATABASE_DRIVER=mysql and point PHOTOPRISM_ORIGINALS_PATH to your photo folder.
Set the administrator and the indexing mode
Set PHOTOPRISM_ADMIN_PASSWORD and enable PHOTOPRISM_READONLY=true if you want it to index without touching the originals. Then launch the stack with docker compose up -d.
Import and run the first indexing
Copy your photos into the originals folder via rsync or WebDAV, then trigger the analysis from the interface or on the command line with docker compose exec photoprism photoprism index. This is where the AI generates labels and thumbnails.
Add a reverse proxy with SSL
Place Caddy or Traefik in front of PhotoPrism for galerie.yourcompany.com, with automatic Let's Encrypt certificate generation. Make sure to forward the headers to keep the correct https scheme in the application.
PhotoPrism or Immich: which to choose
| Criterion | PhotoPrism | Immich |
|---|---|---|
| Main objective | Index and organize an existing photo library | Full photo cloud with mobile backup |
| Mobile app | PWA, no native automatic backup | iOS/Android apps with automatic backup |
| Database | MariaDB or SQLite | PostgreSQL with vector extension |
| AI search | TensorFlow labels by content and color | Semantic search and advanced facial recognition |
| Recommended RAM | 4 GB | 6 to 8 GB |
| File model | Reads an originals folder, read-only mode available | Manages its own upload tree |
| Multi-user | Limited, geared toward a single collection | Isolated libraries per user |
| Ideal use case | Archive and search large photo folders | Replace Google Photos day to day |
Mount your originals folder read-only (:ro in the Docker volume) and enable PHOTOPRISM_READONLY=true. PhotoPrism will index and generate labels and thumbnails in the separate storage volume, without ever risking modifying or deleting an original file. This way you can safely point to a precious archive, and even synchronize that folder via rsync from another server.