๐ŸŽฏ New! Master certifications with Performance-Based Questions (PBQ) โ€” realistic hands-on practice for CompTIA & Cisco exams!

PhotoPrism Complete Self-Hosting Guide: From Installation to Advanced Configuration

Published on January 12, 2026


Introduction

PhotoPrism is a powerful, AI-powered, open-source photo and video management application designed as a privacy-focused alternative to Google Photos and Apple iCloud. It offers automatic facial recognition, location tagging, intelligent search capabilities, and a beautiful web interfaceโ€”all while keeping your precious memories completely under your control on your own hardware.

This comprehensive guide covers every aspect of PhotoPrism deployment, from basic installation to advanced configurations including GPU acceleration, reverse proxy setup, MariaDB optimization, and enterprise-grade backup strategies.

Who Is This Guide For?

  • Beginners wanting to set up their first self-hosted photo management system
  • Intermediate users looking to optimize their existing PhotoPrism installation
  • Advanced users seeking GPU acceleration, reverse proxy integration, or multi-user configurations
  • NAS users (Synology, QNAP, Unraid) wanting to leverage existing hardware
  • Raspberry Pi enthusiasts looking for a lightweight photo solution

What Makes PhotoPrism Special?

FeatureDescription
AI-Powered SearchFind photos using natural language queries and scene recognition
Facial RecognitionAutomatic face detection, clustering, and grouping
Location TaggingPrivacy-preserving geocoding with six high-resolution world maps
Timeline ViewGoogle Photos-like experience with intuitive navigation
Multi-PlatformWeb UI, Progressive Web App (PWA), WebDAV sync
RAW SupportNative support for RAW image formats from major camera brands
Video TranscodingHardware-accelerated video conversion with FFmpeg
Albums & SharingVirtual albums with secure link sharing

โš ๏ธ Important Note: PhotoPrism is under active development. Always maintain redundant backups of your original photos. Never rely solely on any single photo management solution.


Part 1: Understanding PhotoPrism Architecture

Before diving into installation, understanding PhotoPrismโ€™s architecture helps with troubleshooting and optimization.

Core Components

PhotoPrism can run as a single container or with a separate database container:

+-------------------------------------------------------------------+
|                        PHOTOPRISM STACK                           |
+-------------------------------------------------------------------+
|                                                                   |
|   +--------------------+       +--------------------+             |
|   |    PhotoPrism      |       |      MariaDB       |             |
|   |   (Web UI + API)   |<----->|  (Index Database)  |             |
|   |    Port 2342       |       |   (Recommended)    |             |
|   +----------+---------+       +--------------------+             |
|              |                                                    |
|              |   Alternatives:                                    |
|              |   - SQLite (built-in, simpler)                     |
|              |   - MySQL (compatible)                             |
|              |                                                    |
|   +--------------------------------------------------+            |
|   |               STORAGE VOLUMES                    |            |
|   |  /photoprism/originals - Your actual photos      |            |
|   |  /photoprism/storage - Cache, thumbnails, DB     |            |
|   |  /photoprism/import - Staging for imports        |            |
|   +--------------------------------------------------+            |
|                                                                   |
+-------------------------------------------------------------------+
ComponentPurposeNotes
photoprismWeb interface, API, indexing, AI processingMain container
mariadbStores photo metadata, user data, settingsRecommended for large libraries
SQLiteBuilt-in database optionSimpler, but can have concurrency issues

Critical Data Locations

Understanding where PhotoPrism stores data is essential for backups:

LocationContainsBackup Priority
/photoprism/originalsOriginal photo and video filesCRITICAL
/photoprism/storageConfiguration, cache, thumbnails, sidecar files, SQLite DBCRITICAL
/photoprism/importFiles waiting to be importedImportant
MariaDB data volumeDatabase files (if using MariaDB)CRITICAL

Part 2: System Requirements

Hardware Requirements

PhotoPrism is designed to be efficient, but AI features benefit from adequate resources:

ComponentMinimumRecommendedLarge Libraries (100K+ photos)
RAM3 GB4-8 GB8+ GB
CPU2 cores4 cores6+ cores (modern AMD/Intel)
Swap Space4 GB4-8 GB8+ GB
OS Storage10 GB50 GB SSD100 GB+ NVMe
Media StorageVariableSSD for cacheSSD for DB + HDD for media
GPUNot requiredIntel QuickSyncNVIDIA for AI acceleration

Architecture Support

PhotoPrism provides multi-architecture Docker images:

ArchitectureSupport LevelNotes
AMD64 (x86_64)โœ… FullStandard Intel/AMD processors
ARM64โœ… FullRaspberry Pi 4/5, Apple Silicon, ARM servers
ARMv7โš ๏ธ LimitedOlder 32-bit ARM devices

Operating System Compatibility

OSSupport LevelNotes
Linux (Ubuntu/Debian)โœ… BestRecommended for production
Linux (Other distros)โœ… GoodDocker works on most distros
Windows 10/11 (WSL2)โœ… GoodDocker Desktop required
macOS 11+โœ… GoodDocker Desktop for Mac
Raspberry Pi OS (64-bit)โœ… GoodPi 4 or 5 with 4GB+ RAM recommended
Synology DSM 7.2+โœ… GoodContainer Manager supported
QNAP QTS/QuTSโœ… GoodContainer Station supported
Podman (RHEL/Fedora)โœ… GoodAlternative to Docker

Storage Recommendations

For optimal performance, consider this storage strategy:

/-- NVMe SSD (Fast, Local)
|   +-- /var/lib/mysql (MariaDB Database) --- CRITICAL: Use local SSD!
|   +-- /photoprism/storage (Cache, thumbnails)
|   +-- System files
|
+-- HDD Array or NAS
    +-- /photoprism/originals (Original photos/videos)

โš ๏ธ Critical Warning: Never store database files on USB flash drives, SD cards, or network shares. These storage types may cause database corruption and data loss.


Part 3: Docker Installation

Docker is required to run PhotoPrism. Choose the installation method appropriate for your operating system.

This is the preferred setup for PhotoPrism.

Step 1: Update Your System

# Update package lists and upgrade existing packages
sudo apt update
sudo apt upgrade -y

What this does: Ensures your system has the latest security patches and package information before installing new software.

Step 2: Remove Old Docker Versions

# Remove potentially conflicting packages
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
  sudo apt-get remove -y $pkg 2>/dev/null
done

What this does: Removes outdated Docker packages from the default repositories that might conflict with the official Docker installation.

Step 3: Add Dockerโ€™s Official Repository

# Install prerequisites
sudo apt-get install -y ca-certificates curl gnupg

# Create directory for keyrings
sudo install -m 0755 -d /etc/apt/keyrings

# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | 
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add Docker repository to apt sources
echo 
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg]   https://download.docker.com/linux/ubuntu   $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | 
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

What this does: Adds Dockerโ€™s official package repository with GPG verification, ensuring you get authentic, up-to-date Docker packages.

๐Ÿ’ก For Debian: Replace ubuntu with debian in the repository URL above.

Step 4: Install Docker Engine

# Update package index with new repository
sudo apt-get update

# Install Docker Engine and plugins
sudo apt-get install -y 
  docker-ce 
  docker-ce-cli 
  containerd.io 
  docker-buildx-plugin 
  docker-compose-plugin

Package breakdown:

  • docker-ce: Docker Community Edition (the engine)
  • docker-ce-cli: Command-line interface
  • containerd.io: Container runtime
  • docker-buildx-plugin: Enhanced build capabilities
  • docker-compose-plugin: Docker Compose V2 (uses docker compose instead of docker-compose)
# Add current user to docker group
sudo usermod -aG docker $USER

# Apply group changes (or log out and back in)
newgrp docker

What this does: Allows running Docker commands without sudo. You must log out and log back in for changes to take effect permanently.

Step 6: Verify Installation

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker with hello-world
docker run hello-world

Expected output:

Docker version 27.x.x, build xxxxxxx
Docker Compose version v2.x.x
Hello from Docker! ...

Step 7: Configure Swap Space (Critical)

PhotoPrism requires adequate swap space to prevent crashes during memory-intensive operations:

# Check current swap
sudo swapon --show

# If no swap exists, create 4GB swap file
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Make swap permanent
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

What this does: Creates a 4GB swap file that persists across reboots. This prevents PhotoPrism from crashing when processing large RAW files or high-resolution panoramas.


Option B: Windows (Docker Desktop + WSL2)

Docker Desktop with WSL2 provides a seamless experience for running PhotoPrism on Windows.

Prerequisites

  • Windows 10 version 2004 or later, or Windows 11
  • Hardware virtualization enabled in BIOS (check Task Manager โ†’ Performance โ†’ CPU โ†’ Virtualization: Enabled)
  • At least 8 GB RAM (to allocate 4 GB to Docker)

Step 1: Enable WSL2 Features

Open PowerShell as Administrator:

# Enable WSL feature
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

# Enable Virtual Machine Platform
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

# Restart your computer
Restart-Computer

What this does: Enables the Windows Subsystem for Linux 2 and Virtual Machine Platform features required for Docker Desktop.

Step 2: Update WSL2 Kernel

After restart, download and install the WSL2 kernel update:

  1. Download from: https://aka.ms/wsl2kernel
  2. Run the wsl_update_x64.msi installer
  3. Click Next and complete installation

Step 3: Set WSL2 as Default

Open PowerShell:

# Set WSL 2 as default version
wsl --set-default-version 2

# Install Ubuntu distribution (optional, but useful)
wsl --install -d Ubuntu

Step 4: Install Docker Desktop

  1. Download Docker Desktop from docker.com
  2. Run the installer
  3. Critical: Ensure โ€œUse WSL 2 instead of Hyper-Vโ€ is checked during installation
  4. Complete installation and restart if prompted

Step 5: Configure Docker Desktop

  1. Open Docker Desktop from the Start menu
  2. Navigate to Settings (gear icon)
  3. General Tab:
    • โœ… Ensure โ€œUse the WSL 2 based engineโ€ is checked
  4. Resources โ†’ WSL Integration:
    • Toggle ON your WSL distributions (e.g., Ubuntu)
  5. Resources โ†’ Advanced (if using Hyper-V):
    • Allocate at least 4 GB memory
    • Allocate at least 2 CPUs
  6. Click Apply & Restart

Step 6: Verify Installation

Open PowerShell or Windows Terminal:

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker
docker run hello-world

Option C: macOS (Docker Desktop)

Step 1: Install Docker Desktop

  1. Download Docker Desktop from docker.com
    • Apple Silicon (M1/M2/M3/M4): Download the โ€œApple Chipโ€ version
    • Intel Macs: Download the โ€œIntel Chipโ€ version
  2. Open the downloaded .dmg file
  3. Drag Docker.app to the Applications folder
  4. Launch Docker from the Applications folder
  5. Accept the license agreement and authorize with your system password

Step 2: Configure Resources

  1. Click the Docker icon in the menu bar
  2. Select Preferences (or Settings)
  3. Navigate to Resources:
    • Memory: Allocate at least 4 GB (8 GB recommended)
    • CPUs: Allocate at least 2 cores
    • Disk image size: Increase if needed
  4. Click Apply & Restart

Step 3: Verify Installation

Open Terminal:

# Check Docker version
docker --version

# Check Docker Compose version
docker compose version

# Test Docker
docker run hello-world

Option D: Raspberry Pi (Docker)

PhotoPrism works well on Raspberry Pi 4 or 5 with at least 4GB RAM.

Prerequisites

  • Raspberry Pi 4 or 5 with 4GB+ RAM
  • 64-bit Raspberry Pi OS (required)
  • External SSD recommended (USB 3.0)
  • 4GB+ swap space configured

Step 1: Verify 64-bit OS

# Check if running 64-bit
uname -m

Expected output: aarch64 (if you see armv7l, you need to reinstall with 64-bit OS)

If not 64-bit, add to /boot/config.txt:

arm_64bit=1

And reboot.

Step 2: Update System

sudo apt update
sudo apt upgrade -y

Step 3: Install Docker

# Install Docker using the convenience script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Add user to docker group
sudo usermod -aG docker $USER
newgrp docker

Step 4: Configure Swap (Critical for Pi)

# Disable default swap
sudo dphys-swapfile swapoff

# Edit swap configuration
sudo nano /etc/dphys-swapfile

Change CONF_SWAPSIZE to at least 4096:

CONF_SWAPSIZE=4096

Re-enable swap:

sudo dphys-swapfile setup
sudo dphys-swapfile swapon

Step 5: Verify Installation

docker --version
docker compose version

Option E: Synology NAS (Container Manager)

Prerequisites

  • Synology DSM 7.2 or later
  • Container Manager package installed (from Package Center)
  • At least 4GB RAM (8GB recommended)

Step 1: Install Container Manager

  1. Open Package Center
  2. Search for Container Manager
  3. Click Install
  4. Wait for installation to complete

Step 2: Create Folder Structure

Using File Station, create the following structure:

/docker/photoprism/
โ”œโ”€โ”€ storage/
โ”œโ”€โ”€ originals/
โ”œโ”€โ”€ database/
โ””โ”€โ”€ compose.yaml (file, created later)

To create folders:

  1. Open File Station
  2. Navigate to the docker shared folder (create if it doesnโ€™t exist)
  3. Right-click โ†’ Create folder โ†’ Name: photoprism
  4. Inside photoprism, create: storage, originals, database

Step 3: Create Docker Compose via SSH

  1. Enable SSH: Control Panel โ†’ Terminal & SNMP โ†’ โœ… Enable SSH service
  2. Connect via SSH (using Terminal, PuTTY, or similar):
ssh your_username@your_nas_ip
  1. Navigate to the directory:
cd /volume1/docker/photoprism
  1. Download the compose file:
wget https://dl.photoprism.app/docker/compose.yaml
  1. Create and edit .env file for environment variables (see Configuration section below)

Step 4: Alternative - Use Container Manager GUI

  1. Open Container Manager โ†’ Project
  2. Click Create
  3. Set project name: photoprism
  4. Set path: /volume1/docker/photoprism
  5. Paste or upload your compose.yaml configuration
  6. Click Next โ†’ Done to build and start

Option F: QNAP NAS (Container Station)

Step 1: Install Container Station

  1. Open App Center
  2. Search for Container Station
  3. Click Install

Step 2: Create Folder Structure

Using File Station, create:

/Container/photoprism/
โ”œโ”€โ”€ storage/
โ”œโ”€โ”€ originals/
โ””โ”€โ”€ database/

Step 3: Create Compose Application

  1. Open Container Station โ†’ Applications
  2. Click Create
  3. Choose Create Application
  4. Paste your compose.yaml configuration
  5. Configure paths to match QNAPโ€™s volume structure
  6. Click Create

Part 4: PhotoPrism Configuration

Step 1: Create Project Directory

Linux/macOS:

# Create and navigate to PhotoPrism directory
mkdir -p ~/photoprism
cd ~/photoprism

Windows (PowerShell):

# Create directory
New-Item -ItemType Directory -Path "$env:USERPROFILEphotoprism" -Force
cd "$env:USERPROFILEphotoprism"

Step 2: Download Configuration Files

Linux/macOS:

# Download compose.yaml for Linux
wget https://dl.photoprism.app/docker/compose.yaml

# Or for Raspberry Pi (ARM64)
wget https://dl.photoprism.app/docker/arm64/compose.yaml

Windows:

# Download compose.yaml for Windows
curl.exe -o compose.yaml https://dl.photoprism.app/docker/windows/compose.yaml

macOS:

# Download compose.yaml for macOS
curl -o compose.yaml https://dl.photoprism.app/docker/macos/compose.yaml

Step 3: Understand the compose.yaml Structure

The default compose.yaml includes PhotoPrism and MariaDB services. Here is an explained version:

services:
  # ============================================
  # PHOTOPRISM SERVICE - Main application
  # ============================================
  photoprism:
    # Use the latest stable release
    image: photoprism/photoprism:latest
    
    # Restart automatically unless manually stopped
    restart: unless-stopped
    
    # Don't run before the database is ready
    depends_on:
      - mariadb
    
    # Security: Run as root for hardware access (can customize UID/GID)
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    
    # Map port 2342 on host to container
    ports:
      - "2342:2342"
    
    # Environment variables for configuration
    environment:
      # ------------------------------------------
      # CRITICAL: Change this password!
      # ------------------------------------------
      PHOTOPRISM_ADMIN_PASSWORD: "YourSecurePassword123"
      
      # Admin username (default is "admin")
      PHOTOPRISM_ADMIN_USER: "admin"
      
      # ------------------------------------------
      # Site Configuration
      # ------------------------------------------
      # Your public URL (for share links)
      PHOTOPRISM_SITE_URL: "http://localhost:2342/"
      
      # Site branding
      PHOTOPRISM_SITE_TITLE: "PhotoPrism"
      PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App"
      PHOTOPRISM_SITE_DESCRIPTION: "My Photo Collection"
      PHOTOPRISM_SITE_AUTHOR: "Your Name"
      
      # ------------------------------------------
      # Storage & Database
      # ------------------------------------------
      PHOTOPRISM_ORIGINALS_LIMIT: 5000
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"
      
      # Database connection (MariaDB)
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "photoprism"
      PHOTOPRISM_DATABASE_PASSWORD: "YourDatabasePassword"
      
      # ------------------------------------------
      # Feature Flags
      # ------------------------------------------
      PHOTOPRISM_DISABLE_TLS: "false"
      PHOTOPRISM_DEFAULT_TLS: "true"
      PHOTOPRISM_DISABLE_WEBDAV: "false"
      PHOTOPRISM_DISABLE_SETTINGS: "false"
      PHOTOPRISM_DISABLE_TENSORFLOW: "false"
      PHOTOPRISM_DISABLE_FACES: "false"
      PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
      PHOTOPRISM_DISABLE_VECTORS: "false"
      PHOTOPRISM_DISABLE_RAW: "false"
      PHOTOPRISM_RAW_PRESETS: "false"
      
      # ------------------------------------------
      # Video Processing
      # ------------------------------------------
      PHOTOPRISM_FFMPEG_ENCODER: "software"
      PHOTOPRISM_FFMPEG_BITRATE: "32"
      
      # ------------------------------------------
      # Detection Settings
      # ------------------------------------------
      PHOTOPRISM_DETECT_NSFW: "false"
      PHOTOPRISM_UPLOAD_NSFW: "true"
    
    # ------------------------------------------
    # Volume Mounts - CUSTOMIZE THESE PATHS
    # ------------------------------------------
    volumes:
      # Your original photos (REQUIRED)
      # Format: "/path/on/host:/photoprism/originals"
      - "~/Pictures:/photoprism/originals"
      
      # Optional import folder
      # - "/path/to/import:/photoprism/import"
      
      # PhotoPrism storage (cache, thumbnails, etc.) (REQUIRED)
      # Use local SSD for best performance
      - "./storage:/photoprism/storage"
    
    # Working directory inside container
    working_dir: "/photoprism"
  
  # ============================================
  # MARIADB SERVICE - Database
  # ============================================
  mariadb:
    image: mariadb:11
    restart: unless-stopped
    
    # Security hardening
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    
    # Command to set character encoding
    command: >
      --innodb-buffer-pool-size=512M
      --transaction-isolation=READ-COMMITTED
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --max-connections=512
      --innodb-rollback-on-timeout=OFF
      --innodb-lock-wait-timeout=120
    
    environment:
      MARIADB_AUTO_UPGRADE: "1"
      MARIADB_INITDB_SKIP_TZINFO: "1"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "YourDatabasePassword"
      MARIADB_ROOT_PASSWORD: "YourRootPassword"
    
    volumes:
      # Database files - MUST be local SSD!
      - "./database:/var/lib/mysql"

Step 4: Configure Environment Variables

The key environment variables you should customize:

Security Settings (CRITICAL)

VariableDescriptionExample
PHOTOPRISM_ADMIN_USERAdmin usernameadmin
PHOTOPRISM_ADMIN_PASSWORDAdmin password (min 8 chars)YourSecurePassword123
PHOTOPRISM_AUTH_MODEAuthentication modepassword (default) or public

โš ๏ธ Critical: Always change PHOTOPRISM_ADMIN_PASSWORD before first startup. Never use the default insecure value on accessible servers!

๐Ÿ’ก Note: If your password contains a $ sign, escape it with $$. For example: pa$$word becomes pa$$$$word in the YAML file.

Site Settings

VariableDescriptionExample
PHOTOPRISM_SITE_URLPublic URL (for share links)https://photos.yourdomain.com/
PHOTOPRISM_SITE_TITLEBrowser tab titleMy Photos
PHOTOPRISM_SITE_CAPTIONSubtitleAI-Powered Photos
PHOTOPRISM_SITE_AUTHOROwner nameYour Name

Database Settings

VariableDescriptionDefault
PHOTOPRISM_DATABASE_DRIVERDatabase typemysql (use sqlite for simpler setup)
PHOTOPRISM_DATABASE_SERVERDatabase host:portmariadb:3306
PHOTOPRISM_DATABASE_NAMEDatabase namephotoprism
PHOTOPRISM_DATABASE_USERDatabase userphotoprism
PHOTOPRISM_DATABASE_PASSWORDDatabase password(set a strong password)

Feature Flags

VariableDescriptionDefault
PHOTOPRISM_DISABLE_WEBDAVDisable WebDAV file syncfalse
PHOTOPRISM_DISABLE_SETTINGSHide settings in UIfalse
PHOTOPRISM_DISABLE_TENSORFLOWDisable AI/ML featuresfalse
PHOTOPRISM_DISABLE_FACESDisable facial recognitionfalse
PHOTOPRISM_DISABLE_CLASSIFICATIONDisable image classificationfalse
PHOTOPRISM_DISABLE_RAWDisable RAW processingfalse
PHOTOPRISM_READONLYRead-only mode (no uploads)false

Video Transcoding

VariableDescriptionOptions
PHOTOPRISM_FFMPEG_ENCODERVideo encodersoftware, intel, nvidia, raspberry
PHOTOPRISM_FFMPEG_BITRATETarget bitrate (Mbps)32 (default)
PHOTOPRISM_FFMPEG_SIZEMax resolution3840 (4K), 1920 (1080p)

Step 5: Configure Volume Paths

Volume mounts connect host directories to the container. Format: host_path:container_path

Linux Example:

volumes:
  # Originals on a large HDD
  - "/mnt/photos:/photoprism/originals"
  
  # Import folder on USB drive
  - "/mnt/usb/import:/photoprism/import"
  
  # Storage on fast SSD
  - "/var/lib/photoprism:/photoprism/storage"

Windows Example:

volumes:
  # Use forward slashes and Windows drive letter
  - "D:/Photos:/photoprism/originals"
  - "C:/PhotoPrism/storage:/photoprism/storage"

โš ๏ธ Windows Path Format: Always use forward slashes / instead of backslashes \.

macOS Example:

volumes:
  - "~/Pictures:/photoprism/originals"
  - "~/Library/PhotoPrism/storage:/photoprism/storage"

Synology NAS Example:

volumes:
  - "/volume1/photo:/photoprism/originals"
  - "/volume1/docker/photoprism/storage:/photoprism/storage"

Step 6: Create Required Directories

Linux/macOS:

# Create directories
mkdir -p storage database

# If using non-relative paths
sudo mkdir -p /var/lib/photoprism/storage
sudo mkdir -p /mnt/photos
sudo chown -R $USER:$USER /var/lib/photoprism

Windows (PowerShell):

New-Item -ItemType Directory -Path ".storage" -Force
New-Item -ItemType Directory -Path ".database" -Force

Part 5: Starting PhotoPrism

Step 1: Navigate to Project Directory

cd ~/photoprism

Step 2: Start the Containers

# Pull images and start containers in detached mode
docker compose up -d

Command breakdown:

  • docker compose: Docker Compose V2 command
  • up: Download images (if needed) and start containers
  • -d: Detached mode (runs in background)

๐Ÿ’ก Note: If your Docker version doesnโ€™t support docker compose (with a space), use docker-compose (with a hyphen) instead.

Step 3: Monitor Startup

# Watch container logs in real-time
docker compose logs -f

# Or watch specific service
docker compose logs -f photoprism

The first startup may take 2-5 minutes as:

  • Database initializes
  • TensorFlow models load
  • Initial caching occurs

Look for this message indicating success:

INFO server: listening on 0.0.0.0:2342 (tls=false)

Press Ctrl+C to exit log view.

Step 4: Verify Containers Are Running

docker compose ps

Expected output:

NAME                IMAGE                       STATUS          PORTS
photoprism          photoprism/photoprism:latest   Up (healthy)   0.0.0.0:2342->2342/tcp
mariadb             mariadb:11                  Up (healthy)   3306/tcp

Step 5: Access Web Interface

  1. Open your web browser
  2. Navigate to: http://YOUR_SERVER_IP:2342
    • Or http://localhost:2342 if running locally
  3. Log in with:
    • Username: admin (or your configured PHOTOPRISM_ADMIN_USER)
    • Password: Your configured PHOTOPRISM_ADMIN_PASSWORD

Step 6: Index Your Photo Library

  1. Navigate to Library โ†’ Index in the web interface
  2. Click Start to begin indexing your photos
  3. For a complete rescan: Check โ€œComplete Rescanโ€ option

๐Ÿ’ก Tip: Initial indexing may take hours for large libraries. Run it overnight for best results.


Part 6: Useful Docker Commands

Container Management

# Start containers
docker compose up -d

# Stop containers
docker compose stop

# Stop and remove containers
docker compose down

# Restart containers
docker compose restart

# View running containers
docker compose ps

# View logs
docker compose logs

# View logs for specific service
docker compose logs photoprism

# Follow logs in real-time
docker compose logs -f

Executing Commands Inside Container

# Open shell inside PhotoPrism container
docker compose exec photoprism bash

# Run PhotoPrism CLI commands
docker compose exec photoprism photoprism help

# Reset admin password
docker compose exec photoprism photoprism passwd admin

# Force reindex
docker compose exec photoprism photoprism index -f

# Create database backup
docker compose exec photoprism photoprism backup -i -f

# Restore database
docker compose exec photoprism photoprism restore -i -f

Update PhotoPrism

# Pull latest images
docker compose pull

# Recreate containers with new images
docker compose up -d

# Or combined command
docker compose up -d --pull always

๐Ÿ’ก After major updates: Perform a complete rescan of your library via Library โ†’ Index โ†’ Complete Rescan.


Part 7: Reverse Proxy Setup (HTTPS)

For security and remote access, run PhotoPrism behind a reverse proxy with HTTPS.

Important Requirements

  • PhotoPrism must be served at the root path of a domain (not a sub-path like /photos)
  • Required headers: Host, X-Real-IP, X-Forwarded-Proto, X-Forwarded-For
  • WebSocket support required for live updates
  • Large upload support and adequate timeouts

Update PhotoPrism Configuration for Proxy

Add/modify these environment variables in your compose.yaml:

environment:
  # Your public URL (MUST match proxy domain)
  PHOTOPRISM_SITE_URL: "https://photos.yourdomain.com/"
  
  # Disable internal TLS (let proxy handle it)
  PHOTOPRISM_DISABLE_TLS: "true"

Option A: Nginx Reverse Proxy

Step 1: Install Nginx and Certbot

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx

Step 2: Create Nginx Configuration

Create /etc/nginx/sites-available/photoprism:

# Redirect HTTP to HTTPS
server {
    listen 80;
    listen [::]:80;
    server_name photos.yourdomain.com;
    
    location / {
        return 301 https://$host$request_uri;
    }
}

# HTTPS Server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name photos.yourdomain.com;

    # SSL Configuration (filled by certbot)
    ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Allow large uploads (50GB)
    client_max_body_size 50000M;
    
    # Optimize upload buffering
    client_body_buffer_size 512k;
    proxy_request_buffering off;

    # Timeouts for long-running operations
    proxy_read_timeout 600s;
    proxy_send_timeout 600s;
    send_timeout 600s;

    location / {
        proxy_pass http://127.0.0.1:2342;
        
        # Required headers
        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;
        
        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Buffering
        proxy_buffering off;
    }
}

Step 3: Enable the Site

# Create symlink to enable site
sudo ln -s /etc/nginx/sites-available/photoprism /etc/nginx/sites-enabled/

# Remove default site (optional)
sudo rm /etc/nginx/sites-enabled/default

# Test configuration
sudo nginx -t

# If test passes, reload Nginx
sudo systemctl reload nginx

Step 4: Obtain SSL Certificate

# Get certificate (choose your domain)
sudo certbot --nginx -d photos.yourdomain.com

Follow the prompts to complete certificate issuance.


Option B: Traefik Reverse Proxy

Traefik integrates cleanly with Docker and provides automatic Letโ€™s Encrypt certificates.

Step 1: Create Traefik Configuration

Create traefik.yaml in your PhotoPrism directory:

log:
  level: INFO

global:
  sendAnonymousUsage: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    transport:
      respondingTimeouts:
        readTimeout: "3h"
        writeTimeout: "0s"

providers:
  docker:
    exposedByDefault: false
    watch: true

api:
  insecure: false
  dashboard: false
  debug: false

certificatesResolvers:
  myresolver:
    acme:
      email: your-email@example.com
      storage: /data/certs.json
      httpChallenge:
        entryPoint: web

Step 2: Update compose.yaml

services:
  traefik:
    image: traefik:v3.6
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "./traefik.yaml:/etc/traefik/traefik.yaml"
      - "./traefik/data:/data"
      - "/var/run/docker.sock:/var/run/docker.sock"

  photoprism:
    image: photoprism/photoprism:latest
    restart: unless-stopped
    depends_on:
      - mariadb
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.photoprism.rule=Host(`photos.yourdomain.com`)"
      - "traefik.http.routers.photoprism.entrypoints=websecure"
      - "traefik.http.routers.photoprism.tls=true"
      - "traefik.http.routers.photoprism.tls.certresolver=myresolver"
      - "traefik.http.services.photoprism.loadbalancer.server.port=2342"
    environment:
      PHOTOPRISM_SITE_URL: "https://photos.yourdomain.com/"
      PHOTOPRISM_DISABLE_TLS: "true"
      # ... other environment variables
    volumes:
      - "./originals:/photoprism/originals"
      - "./storage:/photoprism/storage"

  mariadb:
    # ... MariaDB configuration

Option C: Caddy Reverse Proxy

Caddy provides automatic HTTPS with minimal configuration.

Caddyfile Configuration

Create Caddyfile:

photos.yourdomain.com {
    reverse_proxy localhost:2342
}

Thatโ€™s it! Caddy automatically obtains and renews SSL certificates.


Part 8: GPU Acceleration

PhotoPrism supports GPU acceleration for video transcoding and (experimentally) AI/ML features.

Step 1: Verify Intel GPU

# Check for Intel GPU
ls -la /dev/dri/

You should see devices like card0, renderD128.

Step 2: Update compose.yaml

services:
  photoprism:
    # ... existing configuration
    devices:
      - "/dev/dri:/dev/dri"
    environment:
      PHOTOPRISM_FFMPEG_ENCODER: "intel"
      # ... other variables

Step 3: Restart

docker compose down
docker compose up -d

NVIDIA GPU Acceleration

Step 1: Install NVIDIA Container Toolkit

# Add NVIDIA repository
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | 
  sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | 
  sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | 
  sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# Install toolkit
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# Configure Docker
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Step 2: Update compose.yaml

services:
  photoprism:
    # ... existing configuration
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    environment:
      PHOTOPRISM_FFMPEG_ENCODER: "nvidia"
      NVIDIA_VISIBLE_DEVICES: "all"
      NVIDIA_DRIVER_CAPABILITIES: "compute,video,utility"
      # For GPU-accelerated TensorFlow (optional)
      PHOTOPRISM_INIT: "gpu tensorflow"

Raspberry Pi Hardware Encoding

services:
  photoprism:
    devices:
      - "/dev/video10:/dev/video10"
      - "/dev/video11:/dev/video11"
      - "/dev/video12:/dev/video12"
    environment:
      PHOTOPRISM_FFMPEG_ENCODER: "raspberry"

Part 9: Backup and Restore

What to Back Up

ComponentLocationPriority
Original photos/photoprism/originals volumeCRITICAL
PhotoPrism storage/photoprism/storage volumeCRITICAL
MariaDB database/var/lib/mysql volumeCRITICAL
compose.yamlYour project directoryImportant

Creating Database Backup

# Create database backup
docker compose exec photoprism photoprism backup -i -f

# Backup is saved to storage/backup/mysql/

Alternatively, using MariaDB directly:

docker compose exec mariadb mysqldump -u photoprism -p photoprism > photoprism_backup.sql

Automated Backups

PhotoPrism can create automatic daily backups. Configure in compose.yaml:

environment:
  PHOTOPRISM_BACKUP_DATABASE: "true"
  PHOTOPRISM_BACKUP_SCHEDULE: "0 3 * * *"  # Daily at 3 AM
  PHOTOPRISM_BACKUP_RETAIN: "3"             # Keep 3 backups

Restoring from Backup

Method 1: Using PhotoPrism CLI

# Restore the most recent backup
docker compose exec photoprism photoprism restore -i -f

# Restore specific backup file
docker compose exec photoprism photoprism restore -i /photoprism/storage/backup/mysql/2026-01-12.sql

Method 2: Restore to MariaDB directly

# Stop PhotoPrism first
docker compose stop photoprism

# Restore
docker compose exec -T mariadb mysql -u photoprism -p photoprism < photoprism_backup.sql

# Start PhotoPrism
docker compose start photoprism

Full System Backup Strategy

#!/bin/bash
# backup_photoprism.sh

BACKUP_DIR="/backup/photoprism/$(date +%Y-%m-%d)"
mkdir -p "$BACKUP_DIR"

# 1. Create database dump
docker compose exec -T photoprism photoprism backup -i -f

# 2. Copy storage folder
rsync -av /path/to/photoprism/storage/ "$BACKUP_DIR/storage/"

# 3. Copy originals (optional if backed up elsewhere)
rsync -av /path/to/photoprism/originals/ "$BACKUP_DIR/originals/"

# 4. Copy configuration
cp /path/to/photoprism/compose.yaml "$BACKUP_DIR/"

echo "Backup completed to $BACKUP_DIR"

Part 10: Database Migration

Migrating from SQLite to MariaDB

For large libraries, MariaDB provides better performance and concurrency.

Step 1: Install Migration Tool

sudo pip3 install sqlite3-to-mysql

Step 2: Stop PhotoPrism

docker compose stop photoprism

Step 3: Add MariaDB to compose.yaml

If not already present, add the MariaDB service (see Part 4).

Step 4: Start MariaDB

docker compose up -d mariadb

Step 5: Migrate Data

sqlite3mysql 
  -f storage/index.db 
  -d photoprism 
  -u photoprism 
  -p YourDatabasePassword 
  -h localhost 
  -P 3306

Step 6: Update compose.yaml

Change database settings:

environment:
  PHOTOPRISM_DATABASE_DRIVER: "mysql"
  PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
  PHOTOPRISM_DATABASE_NAME: "photoprism"
  PHOTOPRISM_DATABASE_USER: "photoprism"
  PHOTOPRISM_DATABASE_PASSWORD: "YourDatabasePassword"

Step 7: Start PhotoPrism

docker compose up -d

Part 11: Mobile Access with WebDAV

PhotoPrism supports WebDAV for file synchronization.

Enabling WebDAV

Ensure this variable is not set to true:

environment:
  PHOTOPRISM_DISABLE_WEBDAV: "false"

WebDAV URL

Access your photos via WebDAV at:

https://photos.yourdomain.com/originals/

Connecting from Mobile Apps

iOS Files App:

  1. Open Files app
  2. Tap โ€ฆ (more) โ†’ Connect to Server
  3. Enter: https://photos.yourdomain.com/originals/
  4. Enter your PhotoPrism credentials

Android with Solid Explorer:

  1. Open Solid Explorer
  2. Tap + โ†’ New connection โ†’ WebDAV
  3. Enter server URL and credentials

Part 12: Troubleshooting

Common Issues and Solutions

Issue: Cannot Login to PhotoPrism

Symptoms: Login page appears but credentials donโ€™t work

Solutions:

  1. Check password special characters: Escape $ signs with $$ in YAML
  2. Reset password via CLI:
    docker compose exec photoprism photoprism passwd admin
  3. Check for locked account: Too many failed attempts temporarily block login
  4. Reset authentication:
    docker compose exec photoprism photoprism auth reset --yes

Issue: App Not Loading / Blank Page

Solutions:

  1. Check if server is running:
    docker compose ps
    docker compose logs photoprism
  2. Verify browser compatibility (use Chrome, Firefox, Safari)
  3. Clear browser cache
  4. Check for ad-blocker interference
  5. Verify port binding: netstat -tlnp | grep 2342

Issue: Container Keeps Restarting

Symptoms: Container status shows repeated restarts

Solutions:

  1. Check logs:
    docker compose logs photoprism
  2. Common causes:
    • Insufficient memory โ†’ Add swap space (4GB+)
    • Disk full โ†’ Free disk space
    • Permission issues โ†’ Check folder permissions
    • Database connection failure โ†’ Check MariaDB is healthy

Issue: Photos Not Appearing After Import

Solutions:

  1. Trigger manual index:
    • Web UI: Library โ†’ Index โ†’ Start
    • CLI: docker compose exec photoprism photoprism index
  2. Complete rescan:
    docker compose exec photoprism photoprism index -f
  3. Check file permissions:
    ls -la /path/to/originals

Issue: Slow Performance

Solutions:

  1. Use SSD for database: Move MariaDB data to SSD
  2. Reduce workers (if memory limited):
    environment:
      PHOTOPRISM_WORKERS: "2"
  3. Switch to MariaDB (if using SQLite)
  4. Add more swap space
  5. Disable unused features:
    environment:
      PHOTOPRISM_DISABLE_FACES: "true"
      PHOTOPRISM_DISABLE_CLASSIFICATION: "true"

Issue: Video Playback Not Working

Solutions:

  1. Check FFmpeg logs:
    docker compose logs photoprism | grep -i ffmpeg
  2. Allow transcoding time: Large videos need processing
  3. Check browser codec support: Use Chrome/Firefox
  4. Increase bitrate limit:
    environment:
      PHOTOPRISM_FFMPEG_BITRATE: "64"

Viewing Logs

# View all logs
docker compose logs

# Follow logs in real-time
docker compose logs -f

# View specific service logs
docker compose logs photoprism
docker compose logs mariadb

# View last 100 lines
docker compose logs --tail=100 photoprism

Health Checks

# Check container health
docker compose ps

# Detailed container inspection
docker inspect photoprism | grep -A 20 "Health"

# Check database connection
docker compose exec mariadb mysql -u photoprism -p -e "SELECT 1"

Part 13: Advanced Configuration

Running PhotoPrism as Non-Root User

For improved security:

services:
  photoprism:
    user: "1000:1000"  # UID:GID of your user
    environment:
      PHOTOPRISM_UID: "1000"
      PHOTOPRISM_GID: "1000"

Ensure volumes have correct permissions:

sudo chown -R 1000:1000 /path/to/originals /path/to/storage

Using Read-Only Mode

To prevent file modifications:

environment:
  PHOTOPRISM_READONLY: "true"
volumes:
  - "/path/to/originals:/photoprism/originals:ro"

Multiple Libraries

Mount additional directories as subfolders:

volumes:
  - "/mnt/photos:/photoprism/originals"
  - "/mnt/videos:/photoprism/originals/videos"
  - "/mnt/archive:/photoprism/originals/archive"

Custom Thumbnail Settings

environment:
  PHOTOPRISM_THUMB_SIZE: "2048"      # Max thumbnail size
  PHOTOPRISM_THUMB_LIBRARY: "vips"   # vips or imaging
  PHOTOPRISM_JPEG_QUALITY: "90"      # Output quality

Disabling AI Features (Low-Power Devices)

For systems with limited resources:

environment:
  PHOTOPRISM_DISABLE_TENSORFLOW: "true"
  PHOTOPRISM_DISABLE_FACES: "true"
  PHOTOPRISM_DISABLE_CLASSIFICATION: "true"

Part 14: Updating PhotoPrism

Standard Update Process

# Navigate to PhotoPrism directory
cd ~/photoprism

# Pull latest images
docker compose pull

# Recreate containers with new images
docker compose up -d

# View logs to verify startup
docker compose logs -f

Alternative: Combined Command

docker compose up -d --pull always

After Major Updates

  1. Create database backup before updating
  2. Complete rescan recommended:
    • Web UI: Library โ†’ Index โ†’ Complete Rescan
    • Or CLI: docker compose exec photoprism photoprism index -f
  3. Review release notes for breaking changes

Automatic Updates with Watchtower (Optional)

Add Watchtower to your compose.yaml:

services:
  watchtower:
    image: containrrr/watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      WATCHTOWER_CLEANUP: "true"
      WATCHTOWER_SCHEDULE: "0 0 4 * * *"  # Daily at 4 AM

โš ๏ธ Warning: Automatic updates may interrupt indexing operations. Manual updates give you more control.


Part 15: Security Best Practices

Essential Security Measures

  1. Use Strong Passwords

    • Minimum 12 characters
    • Mix of letters, numbers, symbols
    • Donโ€™t use default values
  2. Enable HTTPS

    • Always use reverse proxy with SSL/TLS
    • Never expose PhotoPrism directly on public internet without encryption
  3. Firewall Configuration

    • Only expose necessary ports (80, 443)
    • Block port 2342 from public access if using reverse proxy
  4. Keep Updated

    • Regularly update PhotoPrism
    • Update Docker and host OS
    • Monitor security advisories
  5. Limit Login Attempts PhotoPrism automatically rate-limits failed login attempts

Using Tailscale/VPN for Remote Access

Instead of exposing to public internet:

  1. Install Tailscale on server and clients
  2. Access PhotoPrism via Tailscale IP (e.g., http://100.x.x.x:2342)
  3. No port forwarding needed

Part 16: Useful Resources

Official Resources

Community

Configuration Reference


Conclusion

Congratulations! You now have a comprehensive understanding of how to deploy and manage PhotoPrism. This AI-powered photo management solution gives you complete control over your precious memories while providing features comparable to commercial cloud services.

Key Takeaways

  • Docker Compose is the recommended installation method
  • MariaDB provides better performance than SQLite for large libraries
  • Reverse proxy with HTTPS is essential for security
  • Regular backups protect against data loss
  • GPU acceleration dramatically speeds up video transcoding
  • Keep PhotoPrism updated for security and new features

Next Steps

  1. โœ… Complete initial photo library indexing
  2. โœ… Set up mobile app for automatic backup
  3. โœ… Configure reverse proxy for remote access
  4. โœ… Establish backup routine
  5. โœ… Explore PhotoPrismโ€™s AI features (face recognition, search)

This guide was researched and compiled using official PhotoPrism documentation, community resources, and verified installation procedures. Last updated: January 2026.

Comments

Sign in to join the discussion!

Your comments help others in the community.