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:

  1. Open any album in the PhotoPrism web interface
  2. Click the Share button (chain link icon)
  3. Click Create Link — generates a shareable URL
  4. 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.