PhotoPrism¶
AI-Powered Photo Management
PhotoPrism is an AI-powered photos app for the decentralized web. It uses the latest technologies to tag and find pictures automatically without getting in your way. Browse all your photos and videos without worrying about RAW conversion, duplicates, or video formats.
Why Choose PhotoPrism?¶
- AI-powered - automatic tagging with facial recognition
- Universal formats - RAW, HEIF/HEIC, and video support
- Smart organization - world map and timeline views
- Privacy-first - 100% private with no cloud dependencies
Install¶
Infrastructure as Code
This PhotoPrism instance is deployed using OpenTofu with custom Incus images. The infrastructure configuration manages container provisioning and persistent storage volumes.
Custom PhotoPrism Image
The PhotoPrism Incus image is built and maintained at forgejo.benoit.jp.net/Benoit/Laminar.
Infrastructure Configuration¶
The OpenTofu configuration provisions:
- Incus instance running custom PhotoPrism image
- Four persistent storage volumes:
/opt/photoprism/config- PhotoPrism configuration/opt/photoprism/storage- Database, cache, and sidecar files/opt/photoprism/originals- Original photo files/opt/photoprism/backup- Backup storage
resource "incus_storage_volume" "photoprism_opt_photoprism_config" {
name = "photoprism_opt_photoprism_config"
pool = incus_storage_pool.default.name
config = {
"initial.gid" = "1001"
"initial.uid" = "1001"
"initial.mode" = "755"
}
}
resource "incus_storage_volume" "photoprism_opt_photoprism_storage" {
name = "photoprism_opt_photoprism_storage"
pool = incus_storage_pool.default.name
config = {
"initial.gid" = "1001"
"initial.uid" = "1001"
"initial.mode" = "755"
}
}
resource "incus_storage_volume" "photoprism_opt_photoprism_originals" {
name = "photoprism_opt_photoprism_originals"
pool = incus_storage_pool.default.name
config = {
"initial.gid" = "1001"
"initial.uid" = "1001"
"initial.mode" = "755"
}
}
resource "incus_storage_volume" "photoprism_opt_photoprism_backup" {
name = "photoprism_opt_photoprism_backup"
pool = incus_storage_pool.default.name
}
resource "incus_instance" "photoprism" {
name = "photoprism"
image = "laminar.incus:photoprism-1.2507.07+250707-d28b3101e-1benoitjpnet"
device {
name = "photoprism_opt_photoprism_config"
type = "disk"
properties = {
path = "/opt/photoprism/config"
source = incus_storage_volume.photoprism_opt_photoprism_config.name
pool = incus_storage_pool.default.name
}
}
device {
name = "photoprism_opt_photoprism_storage"
type = "disk"
properties = {
path = "/opt/photoprism/storage"
source = incus_storage_volume.photoprism_opt_photoprism_storage.name
pool = incus_storage_pool.default.name
}
}
device {
name = "photoprism_opt_photoprism_originals"
type = "disk"
properties = {
path = "/opt/photoprism/originals"
source = incus_storage_volume.photoprism_opt_photoprism_originals.name
pool = incus_storage_pool.default.name
}
}
device {
name = "photoprism_opt_photoprism_backup"
type = "disk"
properties = {
path = "/opt/photoprism/backup"
source = incus_storage_volume.photoprism_opt_photoprism_backup.name
pool = incus_storage_pool.default.name
}
}
}
Deploy Infrastructure¶
After provisioning, configure PhotoPrism by editing /etc/photoprism/defaults.yml with your settings and preferences.
Upgrade¶
Incus Image Upgrade
When upgrading to a newer Incus image version, follow these steps to migrate your data.
Backup current instance data before upgrading:
Deploy to new Incus image and restore data:
Update OpenTofu configuration
Edit your OpenTofu configuration file to update the image version:
Upgrade Complete
Your PhotoPrism instance is now running on the new Incus image with all photos and AI data intact!
Related Documentation: - Infrastructure Overview - Complete self-hosting architecture - Docker Management Guide - Container orchestration tips