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?
| Feature | Description |
|---|---|
| AI-Powered Search | Find photos using natural language queries and scene recognition |
| Facial Recognition | Automatic face detection, clustering, and grouping |
| Location Tagging | Privacy-preserving geocoding with six high-resolution world maps |
| Timeline View | Google Photos-like experience with intuitive navigation |
| Multi-Platform | Web UI, Progressive Web App (PWA), WebDAV sync |
| RAW Support | Native support for RAW image formats from major camera brands |
| Video Transcoding | Hardware-accelerated video conversion with FFmpeg |
| Albums & Sharing | Virtual 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 | |
| +--------------------------------------------------+ |
| |
+-------------------------------------------------------------------+ | Component | Purpose | Notes |
|---|---|---|
photoprism | Web interface, API, indexing, AI processing | Main container |
mariadb | Stores photo metadata, user data, settings | Recommended for large libraries |
SQLite | Built-in database option | Simpler, but can have concurrency issues |
Critical Data Locations
Understanding where PhotoPrism stores data is essential for backups:
| Location | Contains | Backup Priority |
|---|---|---|
/photoprism/originals | Original photo and video files | CRITICAL |
/photoprism/storage | Configuration, cache, thumbnails, sidecar files, SQLite DB | CRITICAL |
/photoprism/import | Files waiting to be imported | Important |
| MariaDB data volume | Database files (if using MariaDB) | CRITICAL |
Part 2: System Requirements
Hardware Requirements
PhotoPrism is designed to be efficient, but AI features benefit from adequate resources:
| Component | Minimum | Recommended | Large Libraries (100K+ photos) |
|---|---|---|---|
| RAM | 3 GB | 4-8 GB | 8+ GB |
| CPU | 2 cores | 4 cores | 6+ cores (modern AMD/Intel) |
| Swap Space | 4 GB | 4-8 GB | 8+ GB |
| OS Storage | 10 GB | 50 GB SSD | 100 GB+ NVMe |
| Media Storage | Variable | SSD for cache | SSD for DB + HDD for media |
| GPU | Not required | Intel QuickSync | NVIDIA for AI acceleration |
Architecture Support
PhotoPrism provides multi-architecture Docker images:
| Architecture | Support Level | Notes |
|---|---|---|
| AMD64 (x86_64) | โ Full | Standard Intel/AMD processors |
| ARM64 | โ Full | Raspberry Pi 4/5, Apple Silicon, ARM servers |
| ARMv7 | โ ๏ธ Limited | Older 32-bit ARM devices |
Operating System Compatibility
| OS | Support Level | Notes |
|---|---|---|
| Linux (Ubuntu/Debian) | โ Best | Recommended for production |
| Linux (Other distros) | โ Good | Docker works on most distros |
| Windows 10/11 (WSL2) | โ Good | Docker Desktop required |
| macOS 11+ | โ Good | Docker Desktop for Mac |
| Raspberry Pi OS (64-bit) | โ Good | Pi 4 or 5 with 4GB+ RAM recommended |
| Synology DSM 7.2+ | โ Good | Container Manager supported |
| QNAP QTS/QuTS | โ Good | Container Station supported |
| Podman (RHEL/Fedora) | โ Good | Alternative 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.
Option A: Linux (Ubuntu/Debian) - Recommended
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
ubuntuwithdebianin 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 interfacecontainerd.io: Container runtimedocker-buildx-plugin: Enhanced build capabilitiesdocker-compose-plugin: Docker Compose V2 (usesdocker composeinstead ofdocker-compose)
Step 5: Configure Non-Root Access (Recommended)
# 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:
- Download from: https://aka.ms/wsl2kernel
- Run the
wsl_update_x64.msiinstaller - 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
- Download Docker Desktop from docker.com
- Run the installer
- Critical: Ensure โUse WSL 2 instead of Hyper-Vโ is checked during installation
- Complete installation and restart if prompted
Step 5: Configure Docker Desktop
- Open Docker Desktop from the Start menu
- Navigate to Settings (gear icon)
- General Tab:
- โ Ensure โUse the WSL 2 based engineโ is checked
- Resources โ WSL Integration:
- Toggle ON your WSL distributions (e.g., Ubuntu)
- Resources โ Advanced (if using Hyper-V):
- Allocate at least 4 GB memory
- Allocate at least 2 CPUs
- 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
- Download Docker Desktop from docker.com
- Apple Silicon (M1/M2/M3/M4): Download the โApple Chipโ version
- Intel Macs: Download the โIntel Chipโ version
- Open the downloaded
.dmgfile - Drag Docker.app to the Applications folder
- Launch Docker from the Applications folder
- Accept the license agreement and authorize with your system password
Step 2: Configure Resources
- Click the Docker icon in the menu bar
- Select Preferences (or Settings)
- Navigate to Resources:
- Memory: Allocate at least 4 GB (8 GB recommended)
- CPUs: Allocate at least 2 cores
- Disk image size: Increase if needed
- 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
- Open Package Center
- Search for Container Manager
- Click Install
- 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:
- Open File Station
- Navigate to the docker shared folder (create if it doesnโt exist)
- Right-click โ Create folder โ Name:
photoprism - Inside
photoprism, create:storage,originals,database
Step 3: Create Docker Compose via SSH
- Enable SSH: Control Panel โ Terminal & SNMP โ โ Enable SSH service
- Connect via SSH (using Terminal, PuTTY, or similar):
ssh your_username@your_nas_ip - Navigate to the directory:
cd /volume1/docker/photoprism - Download the compose file:
wget https://dl.photoprism.app/docker/compose.yaml - Create and edit
.envfile for environment variables (see Configuration section below)
Step 4: Alternative - Use Container Manager GUI
- Open Container Manager โ Project
- Click Create
- Set project name:
photoprism - Set path:
/volume1/docker/photoprism - Paste or upload your
compose.yamlconfiguration - Click Next โ Done to build and start
Option F: QNAP NAS (Container Station)
Step 1: Install Container Station
- Open App Center
- Search for Container Station
- Click Install
Step 2: Create Folder Structure
Using File Station, create:
/Container/photoprism/
โโโ storage/
โโโ originals/
โโโ database/ Step 3: Create Compose Application
- Open Container Station โ Applications
- Click Create
- Choose Create Application
- Paste your
compose.yamlconfiguration - Configure paths to match QNAPโs volume structure
- 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)
| Variable | Description | Example |
|---|---|---|
PHOTOPRISM_ADMIN_USER | Admin username | admin |
PHOTOPRISM_ADMIN_PASSWORD | Admin password (min 8 chars) | YourSecurePassword123 |
PHOTOPRISM_AUTH_MODE | Authentication mode | password (default) or public |
โ ๏ธ Critical: Always change
PHOTOPRISM_ADMIN_PASSWORDbefore first startup. Never use the defaultinsecurevalue on accessible servers!
๐ก Note: If your password contains a
$sign, escape it with$$. For example:pa$$wordbecomespa$$$$wordin the YAML file.
Site Settings
| Variable | Description | Example |
|---|---|---|
PHOTOPRISM_SITE_URL | Public URL (for share links) | https://photos.yourdomain.com/ |
PHOTOPRISM_SITE_TITLE | Browser tab title | My Photos |
PHOTOPRISM_SITE_CAPTION | Subtitle | AI-Powered Photos |
PHOTOPRISM_SITE_AUTHOR | Owner name | Your Name |
Database Settings
| Variable | Description | Default |
|---|---|---|
PHOTOPRISM_DATABASE_DRIVER | Database type | mysql (use sqlite for simpler setup) |
PHOTOPRISM_DATABASE_SERVER | Database host:port | mariadb:3306 |
PHOTOPRISM_DATABASE_NAME | Database name | photoprism |
PHOTOPRISM_DATABASE_USER | Database user | photoprism |
PHOTOPRISM_DATABASE_PASSWORD | Database password | (set a strong password) |
Feature Flags
| Variable | Description | Default |
|---|---|---|
PHOTOPRISM_DISABLE_WEBDAV | Disable WebDAV file sync | false |
PHOTOPRISM_DISABLE_SETTINGS | Hide settings in UI | false |
PHOTOPRISM_DISABLE_TENSORFLOW | Disable AI/ML features | false |
PHOTOPRISM_DISABLE_FACES | Disable facial recognition | false |
PHOTOPRISM_DISABLE_CLASSIFICATION | Disable image classification | false |
PHOTOPRISM_DISABLE_RAW | Disable RAW processing | false |
PHOTOPRISM_READONLY | Read-only mode (no uploads) | false |
Video Transcoding
| Variable | Description | Options |
|---|---|---|
PHOTOPRISM_FFMPEG_ENCODER | Video encoder | software, intel, nvidia, raspberry |
PHOTOPRISM_FFMPEG_BITRATE | Target bitrate (Mbps) | 32 (default) |
PHOTOPRISM_FFMPEG_SIZE | Max resolution | 3840 (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 commandup: 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), usedocker-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
- Open your web browser
- Navigate to:
http://YOUR_SERVER_IP:2342- Or
http://localhost:2342if running locally
- Or
- Log in with:
- Username:
admin(or your configuredPHOTOPRISM_ADMIN_USER) - Password: Your configured
PHOTOPRISM_ADMIN_PASSWORD
- Username:
Step 6: Index Your Photo Library
- Navigate to Library โ Index in the web interface
- Click Start to begin indexing your photos
- 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.
Intel Quick Sync Video (Recommended for Intel CPUs)
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
| Component | Location | Priority |
|---|---|---|
| Original photos | /photoprism/originals volume | CRITICAL |
| PhotoPrism storage | /photoprism/storage volume | CRITICAL |
| MariaDB database | /var/lib/mysql volume | CRITICAL |
| compose.yaml | Your project directory | Important |
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:
- Open Files app
- Tap โฆ (more) โ Connect to Server
- Enter:
https://photos.yourdomain.com/originals/ - Enter your PhotoPrism credentials
Android with Solid Explorer:
- Open Solid Explorer
- Tap + โ New connection โ WebDAV
- 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:
- Check password special characters: Escape
$signs with$$in YAML - Reset password via CLI:
docker compose exec photoprism photoprism passwd admin - Check for locked account: Too many failed attempts temporarily block login
- Reset authentication:
docker compose exec photoprism photoprism auth reset --yes
Issue: App Not Loading / Blank Page
Solutions:
- Check if server is running:
docker compose ps docker compose logs photoprism - Verify browser compatibility (use Chrome, Firefox, Safari)
- Clear browser cache
- Check for ad-blocker interference
- Verify port binding:
netstat -tlnp | grep 2342
Issue: Container Keeps Restarting
Symptoms: Container status shows repeated restarts
Solutions:
- Check logs:
docker compose logs photoprism - 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:
- Trigger manual index:
- Web UI: Library โ Index โ Start
- CLI:
docker compose exec photoprism photoprism index
- Complete rescan:
docker compose exec photoprism photoprism index -f - Check file permissions:
ls -la /path/to/originals
Issue: Slow Performance
Solutions:
- Use SSD for database: Move MariaDB data to SSD
- Reduce workers (if memory limited):
environment: PHOTOPRISM_WORKERS: "2" - Switch to MariaDB (if using SQLite)
- Add more swap space
- Disable unused features:
environment: PHOTOPRISM_DISABLE_FACES: "true" PHOTOPRISM_DISABLE_CLASSIFICATION: "true"
Issue: Video Playback Not Working
Solutions:
- Check FFmpeg logs:
docker compose logs photoprism | grep -i ffmpeg - Allow transcoding time: Large videos need processing
- Check browser codec support: Use Chrome/Firefox
- 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
- Create database backup before updating
- Complete rescan recommended:
- Web UI: Library โ Index โ Complete Rescan
- Or CLI:
docker compose exec photoprism photoprism index -f
- 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
Use Strong Passwords
- Minimum 12 characters
- Mix of letters, numbers, symbols
- Donโt use default values
Enable HTTPS
- Always use reverse proxy with SSL/TLS
- Never expose PhotoPrism directly on public internet without encryption
Firewall Configuration
- Only expose necessary ports (80, 443)
- Block port 2342 from public access if using reverse proxy
Keep Updated
- Regularly update PhotoPrism
- Update Docker and host OS
- Monitor security advisories
Limit Login Attempts PhotoPrism automatically rate-limits failed login attempts
Using Tailscale/VPN for Remote Access
Instead of exposing to public internet:
- Install Tailscale on server and clients
- Access PhotoPrism via Tailscale IP (e.g.,
http://100.x.x.x:2342) - No port forwarding needed
Part 16: Useful Resources
Official Resources
- Official Website: https://photoprism.app
- Documentation: https://docs.photoprism.app
- GitHub Repository: https://github.com/photoprism/photoprism
- Docker Hub: https://hub.docker.com/r/photoprism/photoprism
Community
- GitHub Discussions: https://github.com/photoprism/photoprism/discussions
- Community Chat: https://link.photoprism.app/chat
- Reddit: r/photoprism
Configuration Reference
- All Config Options: https://docs.photoprism.app/getting-started/config-options/
- Docker Compose Examples: https://dl.photoprism.app/docker/
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
- โ Complete initial photo library indexing
- โ Set up mobile app for automatic backup
- โ Configure reverse proxy for remote access
- โ Establish backup routine
- โ 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.