How to Install and Set Up PhotoPrism on Your Home Server

Why PhotoPrism Deserves a Spot on Your Home Server

PhotoPrism is a self-hosted, AI-powered photo management application that transforms how you organize, search, and share your image library. Unlike commercial solutions like Google Photos, PhotoPrism runs entirely on your hardware, giving you complete privacy and control. It automatically tags people, places, and objects using machine learning, supports RAW files, and offers a polished web interface. Before diving into installation, confirm your server meets the minimum requirements: a 64-bit Linux or Windows system, 4GB of RAM (8GB recommended), a dual-core processor, and Docker support. Storage depends on your library size, but allocate at least 50GB for the database and thumbnails.

Step 1: Prepare Your Server Environment

Begin with a clean Ubuntu Server 22.04 LTS installation or any Debian-based distribution. Update your package list and upgrade existing packages:

sudo apt update && sudo apt upgrade -y

Install essential tools: curl, git, and ufw if not already present:

sudo apt install curl git ufw -y

Configure the firewall to allow SSH (port 22), HTTP (port 80), and HTTPS (port 443) if you plan to expose PhotoPrism externally. For a local-only setup, ensure port 2342 (default PhotoPrism port) is open:

sudo ufw allow 22/tcp
sudo ufw allow 2342/tcp
sudo ufw enable

Step 2: Install Docker and Docker Compose

PhotoPrism officially recommends Docker for deployment, as it simplifies dependencies and updates. Install Docker using the official repository:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

Add your user to the Docker group to avoid running commands with sudo:

sudo usermod -aG docker $USER
newgrp docker

Install Docker Compose plugin:

sudo apt install docker-compose-plugin -y

Verify installations with docker --version and docker compose version.

Step 3: Set Up the PhotoPrism Directory Structure

Create a dedicated directory for PhotoPrism with organized subfolders:

mkdir -p ~/photoprism/{storage,originals,config}
cd ~/photoprism
  • storage: Contains database files, cache, thumbnails, and logs.
  • originals: Place your actual photo and video files here, or use bind mounts to external drives.
  • config: Holds the docker-compose.yml file and environment variables.

If your photos reside on an external drive or NAS, mount it to /mnt/photos and modify the originals path later.

Step 4: Create the Docker Compose File

Use a text editor to create docker-compose.yml inside the config directory:

nano ~/photoprism/config/docker-compose.yml

Paste the following configuration, which includes MariaDB for database reliability and PhotoPrism itself:

version: '3.5'

services:
  photoprism-db:
    image: mariadb:11
    restart: unless-stopped
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512
    environment:
      MYSQL_ROOT_PASSWORD: change_me_root_password
      MYSQL_DATABASE: photoprism
      MYSQL_USER: photoprism
      MYSQL_PASSWORD: change_me_db_password
    volumes:
      - "/home/your_username/photoprism/storage/database:/var/lib/mysql"
    security_opt:
      - seccomp:unconfined

  photoprism-app:
    image: photoprism/photoprism:latest
    restart: unless-stopped
    depends_on:
      - photoprism-db
    environment:
      PHOTOPRISM_ADMIN_PASSWORD: "your_admin_password"
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "photoprism-db:3306"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "photoprism"
      PHOTOPRISM_DATABASE_PASSWORD: "change_me_db_password"
      PHOTOPRISM_SITE_URL: "http://localhost:2342"
      PHOTOPRISM_DISABLE_WEBDAV: "false"
      PHOTOPRISM_DISABLE_SETTINGS: "false"
      PHOTOPRISM_DISABLE_EXIFTOOL: "false"
      PHOTOPRISM_DISABLE_FFMPEG: "false"
      PHOTOPRISM_RAW_PRESETS: "false"
      PHOTOPRISM_THUMBNAIL_SIZE: "2048"
      PHOTOPRISM_THUMBNAIL_UNCACHED: "true"
      PHOTOPRISM_UPLOAD_NSFW: "true"
      PHOTOPRISM_DETECT_NSFW: "false"
      PHOTOPRISM_EXPERIMENTAL: "false"
      PHOTOPRISM_READONLY: "false"
    volumes:
      - "/home/your_username/photoprism/originals:/photoprism/originals"
      - "/home/your_username/photoprism/storage:/photoprism/storage"
    ports:
      - "2342:2342"

Replace your_username with your actual Linux username, and change all passwords to strong, unique values. The PHOTOPRISM_SITE_URL should match your server’s IP or domain.

Step 5: Launch the Containers

Navigate to the config directory and start the stack:

cd ~/photoprism/config
docker compose up -d

The -d flag runs containers in detached mode. Monitor the startup logs:

docker compose logs -f

Wait for both services to initialize. This may take several minutes on first run as MariaDB creates the database schema and PhotoPrism generates initial thumbnails. Once you see PhotoPrism ready in the logs, proceed.

Step 6: Access the Web Interface

Open your web browser and navigate to http://your-server-ip:2342. Log in using admin as the username and the password you set in PHOTOPRISM_ADMIN_PASSWORD. The interface displays an empty library. Navigate to Settings > General to customize language, theme, and thumbnail sizes. Under Library > Import, you can drag and drop photos directly, or use the filesystem mount.

Step 7: Configure External Photo Libraries

If your photos reside on an external drive, modify the volumes in docker-compose.yml to bind mount the actual path. For example, if photos are on /mnt/nas/photos, update the photoprism-app volume:

volumes:
  - "/mnt/nas/photos:/photoprism/originals"
  - "/home/your_username/photoprism/storage:/photoprism/storage"

Recreate the containers:

docker compose down
docker compose up -d

PhotoPrism will now scan the mounted directory. To trigger an immediate index, go to Library > Index and click Start.

Step 8: Enable Automatic Indexing and Background Workers

PhotoPrism continuously watches for file changes if the filesystem supports inotify. For improved performance, especially with large libraries, add these environment variables:

PHOTOPRISM_WATCHER_DISABLE: "false"
PHOTOPRISM_WORKERS: "4"

Set WORKERS to match your CPU core count. Restart containers to apply.

Step 9: Optimize Performance for Large Libraries

For libraries exceeding 50,000 photos, adjust MariaDB settings. Create a custom config file at ~/photoprism/storage/database/my.cnf:

[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
max_allowed_packet = 256M

Mount this file in the database service:

volumes:
  - "/home/your_username/photoprism/storage/database/my.cnf:/etc/mysql/conf.d/my.cnf"

Recreate the database container and rebuild the index.

Step 10: Secure the Installation with SSL (Optional but Recommended)

For remote access, secure PhotoPrism with HTTPS. Install Certbot and generate a Let’s Encrypt certificate for your domain, then use a reverse proxy like Nginx or Traefik. Example Nginx configuration:

server {
    listen 443 ssl;
    server_name photos.yourdomain.com;
    ssl_certificate /etc/letsencrypt/live/photos.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/photos.yourdomain.com/privkey.pem;
    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;
    }
}

Update PHOTOPRISM_SITE_URL to https://photos.yourdomain.com and restart the app container.

Step 11: Automate Backups of the Database and Storage

Create a backup script at ~/photoprism/backup.sh:

#!/bin/bash
docker exec photoprism-db mysqldump -u photoprism -p'change_me_db_password' photoprism > ~/photoprism/db_backup.sql
tar -czf ~/photoprism/storage_backup.tar.gz ~/photoprism/storage

Make it executable and add a cron job:

chmod +x ~/photoprism/backup.sh
crontab -e
0 3 * * 0 ~/photoprism/backup.sh

This runs backups every Sunday at 3:00 AM. Store backups off-site for disaster recovery.

Step 12: Troubleshoot Common Issues

  • Container fails to start: Run docker compose logs to check for permission errors. Ensure originals and storage directories are owned by the user with ID 1000 (sudo chown -R 1000:1000 ~/photoprism/storage).
  • Photos not appearing: Verify files are readable by Docker. Use ls -la ~/photoprism/originals to confirm permissions. Trigger a manual index from the UI.
  • Slow thumbnail generation: Increase PHOTOPRISM_WORKERS and ensure PHOTOPRISM_THUMBNAIL_UNCACHED is set to false after the first full indexing.
  • Database connection errors: Confirm the database container is healthy with docker ps. Check that MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWORD match exactly across services.

Step 13: Upgrade to the Latest Version

PhotoPrism releases updates frequently. To upgrade, pull new images and recreate containers:

docker compose pull
docker compose up -d

Review the release notes on GitHub for any breaking changes or new environment variables.

Step 14: Integrate with External Services

Enable WebDAV by setting PHOTOPRISM_DISABLE_WEBDAV: "false". This allows mounting PhotoPrism as a network drive on macOS Finder (Go > Connect to Server > http://your-server-ip:2342/photos) or Windows File Explorer. For mobile access, use a VPN or expose the service through a secure tunnel like Tailscale.

Step 15: Monitor Resource Usage

Check container resource consumption:

docker stats

PhotoPrism uses approximately 500MB–1GB RAM for indexing and AI features. If memory is limited, disable TensorFlow for face recognition by setting PHOTOPRISM_DISABLE_TENSORFLOW: "true". Monitor disk space with df -h; thumbnails and database files grow significantly. Set PHOTOPRISM_THUMBNAIL_SIZE to 1280 to reduce storage overhead.

Leave a Comment