I frame no hypothesis.
I. Newton , Mathematical Principles of Natural Philosophy - 1687 A.D.
PhotoPrism is an AI-powered photos app for the decentralized web. It leverages modern technologies to automatically tag and search pictures without getting in your way. You can run it at home, on a private server, or in the cloud. While the proposed installation method is via Docker, this guide uses MariaDB as the database and Nginx as the web server.
This guide is specifically tailored for the Gentoo GNU/Linux distribution, but the steps should be similar for other distributions.
Ensure you have installed ImageMagick
, ffmpeg
, MariaDB, and Nginx.
PhotoPrism requires several libraries and tools for a smooth experience, especially for handling photo and video formats. You need to install these libraries manually. Add the following USE flags to your /etc/portage/make.conf
file:
jpeg tiff avif heic png webp ffmpeg imagemagick
Next, install the required packages:
emerge -av www-servers/nginx dev-db/mariadb media-libs/libheif media-libs/libavif media-video/ffmpeg media-gfx/imagemagick
NOTE: PhotoPrism can integrate with tools like DarkTable for professional photographers.
The microserver features four 2TB disk drives in a storage array and a 250GB SSD drive for the operating system. The storage layer runs in ZFS mirror (RAID1) mode, providing 4TB of usable space on a system that can tolerate one HDD failure1 without data loss.
NOTE: I recommend using RAID5 instead of RAID1. RAID5 offers more space, better performance, and nearly the same level of reliability.
Filesystem configuration is out of the scope of this document.
Setting up MySQL
is also out of the scope of this guide. You can follow the official documentation for assistance. Once the database is set up, create a new database and user for PhotoPrism:
CREATE DATABASE photoprism;
CREATE USER 'photoprism'@'localhost' IDENTIFIED BY 'password123';
GRANT ALL PRIVILEGES ON photoprism.* TO 'photoprism'@'localhost';
FLUSH PRIVILEGES;
For SSL certificates and DNS, I am using AWS Route53, but this is a personal preference, so I’ll skip the setup here. Connections over VPN are secure, so SSL setup isn’t mandatory.
NOTE: To set up Let’s Encrypt with AWS Route53 DNS verification, I recommend using the acme-sh package (
app-crypt/acme-sh
in Gentoo) instead ofcertbot
.
Here is my Nginx configuration for PhotoPrism. Adjust it according to your needs:
# /etc/nginx/nginx.conf
user nginx nginx;
worker_processes 2;
error_log /var/log/nginx/error_log info;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
log_format main
'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
client_header_timeout 10m;
client_body_timeout 30m;
client_max_body_size 0;
create_full_put_path on;
client_body_temp_path /tmp/;
send_timeout 10m;
connection_pool_size 256;
client_header_buffer_size 4k;
large_client_header_buffers 4 2k;
request_pool_size 4k;
gzip on;
output_buffers 1 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75 20;
ignore_invalid_headers on;
index index.html;
include /etc/nginx/conf.d/*.conf;
}
server {
listen 443 ssl;
server_name photoprism.example.com;
ssl_certificate /etc/acme-sh/example.com_ecc/fullchain.cer;
ssl_certificate_key /etc/acme-sh/example.com_ecc/example.com.key;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 30m;
client_max_body_size 15G;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:2342;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
While the PhotoPrism developers recommend Traefik as a reverse proxy, I am using Nginx because I am more familiar with it.
TensorFlow is required for face recognition, a highly desired feature for family photo libraries. Photoprism comes with tensorflow libraries, installed under /opt/photoprism/tensorflow
.
There is no Portage package for PhotoPrism. It is distributed as a Go binary, which you can download from the GitHub repository.
First, create the photoprism
user and group:
groupadd photoprism
useradd -r -g photoprism -d /opt/photoprism -s /sbin/nologin photoprism
mkdir -p /opt/photoprism
id photoprism # Verify setup
Download and extract the latest version to the /opt/photoprism
directory:
cd /tmp && curl -LO https://github.com/photoprism/photoprism/releases/download/240915-e1280b2fb/photoprism_240915-e1280b2fb-linux-amd64.tar.gz
tar zxf -C /opt/photoprism photoprism_240915-e1280b2fb-linux-amd64.tar.gz
chown photoprism:photoprism -R /opt/photoprism
You can run the binary directly, but I recommend creating an OpenRC service.
Create the init configuration in /etc/conf.d/photoprism
:
# /etc/conf.d/photoprism
# Global photoprism options
group="photoprism"
user="photoprism"
# Photoprism configuration
pidfile="/var/run/photoprism.pid"
log="/var/log/photoprism/photoprism.log"
photoprism_defaults="/etc/photoprism/defaults.yml"
And the init script at /etc/init.d/photoprism
:
#!/sbin/openrc-run
name="photoprism"
description="Manage pictures automatically"
command="/opt/photoprism/bin/photoprism"
pidfile=${pidfile:-"/run/${RC_SVCNAME}.pid"}
output_log="${log}"
error_log="${log}"
user=${user:-root}
group=${group:-root}
command_user="${user}:${group}"
command_args="--defaults-yaml ${photoprism_defaults} --pid-filename ${pidfile} --log-filename ${log} start"
command_background="true"
depend() {
need net
use logger
}
start_pre() {
checkpath -q -d -m 0755 -o ${user}:${group} /var/log/photoprism
}
Create the necessary directories:
mkdir -p /storage/photoprism/{originals,import}
chown photoprism:photoprism -R /storage/photoprism
mkdir /etc/photoprism
The library will live under /storage/photoprism/originals
, and files added to /storage/photoprism/import
will be automatically imported.
NOTE: Following best practices, the library is stored on the HDD, while thumbnails are stored on the SSD.
Create the defaults.yml
configuration file in /etc/photoprism
:
ConfigPath: "/etc/photoprism"
StoragePath: "/opt/photoprism/storage"
OriginalsPath: "/storage/photoprism/originals"
AssetsPath: "/opt/photoprism/assets"
ImportPath: "/storage/photoprism/import"
HttpPort: 2342
...
Then set up the options.yml
file, which includes MySQL configuration:
AdminPassword: <password>
AdminUser: admin
AutoImport: 60
DatabaseDriver: mysql
...
Ensure the correct permissions:
chown photoprism:photoprism -R /etc/storage
Explore PhotoPrism to understand its logic. With this setup, adding files to the /import
directory will trigger an import workflow after about 60 seconds.
Use /var/log/photoprism/photoprism.log
for debugging startup issues. Photoprism can be finicky about permissions, so carefully review your setup.
Under circumstances the system could support simultaneously two HDDs failures, assuming they don’t belong to the same source-mirror pair. ↩