PhotoPrism Photo Management Installation
PhotoPrism is a self-hosted AI-powered photo management application that automatically indexes, classifies, and geolocates your photo library without sending data to external services. With facial recognition, automatic scene detection, and a Google Photos-inspired interface, PhotoPrism is the leading open-source alternative for teams and individuals who want private, intelligent photo management on their own Linux server.
Prerequisites
- Ubuntu 20.04+, Debian 11+, or CentOS/Rocky 8+
- Docker and Docker Compose installed
- Minimum 2 GB RAM (4+ GB recommended for AI features)
- Sufficient storage for photos plus 10-30% overhead for thumbnails and index
- Root or sudo access
Installing PhotoPrism with Docker
# Create the PhotoPrism directory structure
sudo mkdir -p /opt/photoprism/{storage,originals,import}
# Create docker-compose.yml
sudo tee /opt/photoprism/docker-compose.yml <<'EOF'
version: '3.8'
services:
photoprism:
image: photoprism/photoprism:latest
restart: unless-stopped
ports:
- "2342:2342"
environment:
PHOTOPRISM_ADMIN_USER: "admin"
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # Change this!
PHOTOPRISM_AUTH_MODE: "password"
PHOTOPRISM_SITE_URL: "https://photos.example.com/"
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # MB per upload
PHOTOPRISM_HTTP_COMPRESSION: "gzip"
PHOTOPRISM_LOG_LEVEL: "info"
PHOTOPRISM_READONLY: "false"
PHOTOPRISM_EXPERIMENTAL: "false"
PHOTOPRISM_DISABLE_CHOWN: "false"
PHOTOPRISM_DISABLE_WEBDAV: "false"
PHOTOPRISM_DETECT_NSFW: "false"
PHOTOPRISM_UPLOAD_NSFW: "true"
PHOTOPRISM_DATABASE_DRIVER: "mysql"
PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
PHOTOPRISM_DATABASE_NAME: "photoprism"
PHOTOPRISM_DATABASE_USER: "photoprism"
PHOTOPRISM_DATABASE_PASSWORD: "insecure" # Change this!
PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos"
PHOTOPRISM_SITE_DESCRIPTION: ""
PHOTOPRISM_SITE_AUTHOR: ""
working_dir: "/photoprism"
volumes:
- /opt/photoprism/originals:/photoprism/originals
- /opt/photoprism/storage:/photoprism/storage
- /opt/photoprism/import:/photoprism/import
depends_on:
- mariadb
mariadb:
image: mariadb:11
restart: unless-stopped
security_opt:
- seccomp:unconfined
- apparmor:unconfined
command: --innodb-buffer-pool-size=512M
environment:
MARIADB_AUTO_UPGRADE: "1"
MARIADB_INITDB_SKIP_TZINFO: "1"
MARIADB_DATABASE: "photoprism"
MARIADB_USER: "photoprism"
MARIADB_PASSWORD: "insecure" # Change this!
MARIADB_ROOT_PASSWORD: "insecure" # Change this!
volumes:
- /opt/photoprism/database:/var/lib/mysql
EOF
# Start PhotoPrism
cd /opt/photoprism
sudo docker compose up -d
# Monitor startup (takes 1-2 minutes on first run)
sudo docker compose logs -f photoprism
Access PhotoPrism at http://your-server:2342. Default login: admin / insecure.
Library Indexing Configuration
Organize your originals directory:
# PhotoPrism can read from subdirectories
# Good structure:
/opt/photoprism/originals/
2023/
vacation/
family/
2024/
events/
# Set correct permissions
sudo chown -R 1000:1000 /opt/photoprism/originals/
Import photos via the import folder:
# Copy photos to the import directory
cp -r /path/to/new/photos /opt/photoprism/import/
# Then trigger import from the UI:
# Library > Import
Trigger indexing via CLI:
# Index all originals
sudo docker compose exec photoprism photoprism index --cleanup
# Index only changed files
sudo docker compose exec photoprism photoprism index
# Convert RAW files
sudo docker compose exec photoprism photoprism convert
# Generate thumbnails
sudo docker compose exec photoprism photoprism thumbs
Schedule automatic indexing:
# Add to crontab for daily scanning
echo "0 3 * * * cd /opt/photoprism && docker compose exec -T photoprism photoprism index" | \
sudo crontab -
Facial Recognition and AI Features
PhotoPrism uses TensorFlow for image classification and facial recognition:
# Enable face recognition via environment variable
# Add to docker-compose.yml environment:
# PHOTOPRISM_FACE_SIZE: 50 # Minimum face size (px)
# PHOTOPRISM_FACE_SCORE: 9 # Recognition confidence (0-100)
# PHOTOPRISM_FACE_OVERLAP: 42 # Overlap threshold
# Run face detection on existing library
sudo docker compose exec photoprism photoprism faces index
Configure AI scene detection:
# In docker-compose.yml environment section:
PHOTOPRISM_TENSORFLOW_SIZE: 150 # Resize for TF model input
PHOTOPRISM_TENSORFLOW_OFF: "false" # Set true to disable AI
# Check GPU/TensorFlow usage
sudo docker compose exec photoprism photoprism status
Geotagging and Maps
# Enable maps in docker-compose.yml:
PHOTOPRISM_MAPS_TILE_URI: "https://cdn.photoprism.app/maps/world/{z}/{x}/{y}.png"
PHOTOPRISM_MAPS_API_KEY: "" # Optional: for commercial map tiles
Geocode existing photos without GPS data:
# Photos with GPS EXIF data are automatically geotagged
# Check EXIF data on a photo
exiftool /opt/photoprism/originals/photo.jpg | grep -i gps
User Management and Sharing
# Create additional users via CLI
sudo docker compose exec photoprism photoprism users create \
--name "Jane Doe" \
--username jane \
--password "securepassword" \
--role viewer
# List all users
sudo docker compose exec photoprism photoprism users list
# Change a password
sudo docker compose exec photoprism photoprism passwd jane
# Set admin password
sudo docker compose exec photoprism photoprism passwd admin
Create a shared album link:
- Open any album in the PhotoPrism web interface
- Click the Share button (chain link icon)
- Click Create Link — generates a shareable URL
- Set optional expiry and password
Storage Configuration
# Storage directory structure (managed by PhotoPrism):
/opt/photoprism/storage/
cache/ # Thumbnail cache
sidecar/ # XMP/JSON sidecars
backup/ # Database backups
# Check storage usage
sudo du -sh /opt/photoprism/storage/cache/
sudo du -sh /opt/photoprism/originals/
# Clear thumbnail cache (regenerated on demand)
sudo docker compose exec photoprism photoprism purge
# Backup the database
sudo docker compose exec mariadb mysqldump \
-u photoprism -pinsecure photoprism > \
/backup/photoprism-$(date +%Y%m%d).sql
Reverse Proxy with Nginx
# /etc/nginx/sites-available/photoprism
server {
listen 80;
server_name photos.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name photos.example.com;
ssl_certificate /etc/letsencrypt/live/photos.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/photos.example.com/privkey.pem;
# Large uploads for photo imports
client_max_body_size 500M;
location / {
proxy_pass http://127.0.0.1:2342;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 600s;
}
}
sudo ln -s /etc/nginx/sites-available/photoprism /etc/nginx/sites-enabled/
sudo certbot --nginx -d photos.example.com
sudo systemctl reload nginx
# Update PHOTOPRISM_SITE_URL in docker-compose.yml
# Then restart
cd /opt/photoprism && sudo docker compose up -d photoprism
Troubleshooting
Indexing stuck or very slow:
# Check resource usage
sudo docker stats photoprism
# Disable AI to speed up indexing
# Set PHOTOPRISM_TENSORFLOW_OFF=true, then re-enable after indexing
# Check for errors
sudo docker compose logs photoprism | grep -i error
# Reset the index and start fresh
sudo docker compose exec photoprism photoprism reset
Photos not appearing after import:
# Verify file permissions
sudo -u 1000 ls /opt/photoprism/originals/
# Check supported formats
sudo docker compose exec photoprism photoprism --help | grep -i format
# Run a full index
sudo docker compose exec photoprism photoprism index --cleanup --force
High memory usage:
# Limit memory in docker-compose.yml
services:
photoprism:
mem_limit: 4g
memswap_limit: 4g
# Disable face detection to reduce memory
# PHOTOPRISM_DISABLE_FACES: "true"
Conclusion
PhotoPrism delivers a powerful self-hosted photo management platform with AI-powered classification, facial recognition, and geolocation that rival commercial alternatives like Google Photos — without sending your personal photos to external services. By running PhotoPrism with Docker and MariaDB on a VPS, you get a scalable, private photo library that indexes tens of thousands of photos automatically and serves them to any device through a beautiful web interface.


