Zum Inhalt

Self-Hosting Photo Management: PhotoPrism on Debian Linux (Go Backend, TensorFlow AI & MariaDB)

Executive Summary: PhotoPrism is a privacy-first, Go-powered photo management platform designed specifically for curating, indexing, and searching large existing disk archives of RAW camera photography (.CR3, .NEF, .ARW), high-resolution JPEGs, and videos. Unlike mobile-first camera-roll replacement apps, PhotoPrism excels at non-destructive indexing of your existing folder hierarchy (/originals mounted read-only), local TensorFlow image classification & facial recognition, offline GPS reverse geocoding onto interactive world maps, and WebDAV synchronization.

  • Non-Destructive Archive Indexing


    Mount your existing curated photo directories at /photoprism/originals (:ro) without letting the software rename or move your files.

  • 100% Local TensorFlow AI


    Classify landscapes, documents, pets, and faces locally on your Debian server CPU/GPU with zero cloud API data leaks.

  • EXIF & World Map Geocoding


    Extract camera EXIF/XMP metadata, lens focal lengths, and GPS coordinates onto an interactive vector world map.

  • Dedicated MariaDB 11 Backend


    Replace default SQLite locking bottlenecks on 50,000+ photo libraries with a dedicated UTF8MB4 MariaDB 11 (InnoDB) database container.


1. PhotoPrism vs. Immich: Which Should You Choose?

Both PhotoPrism and Immich are outstanding self-hosted photo platforms, but they target two distinct engineering workflows:

Workflow Dimension PhotoPrism Immich
Primary Design Goal Indexing, browsing & tagging existing curated NAS / DSLR / RAW photo archives Direct Google Photos / iCloud drop-in replacement with native iOS/Android background backup apps
File System Philosophy Respects your existing /originals folder tree untouched (Read-Only supported) Manages its own upload storage template (while also supporting External Libraries)
Mobile Upload Mechanism Standard WebDAV (PhotoSync app) or PWA Web UI Official native Immich iOS & Android apps
Database Engine MariaDB 11 (InnoDB) PostgreSQL + pgvector / VectorChord
%%{init: {'flowchart': {'wrappingWidth': 600}}}%%
flowchart TB
    ORIG["📷 DSLR / NAS Photo Archive<br/>/srv/photos/originals (:ro)"]
    PP["🖼️ PhotoPrism Engine (Go)<br/>127.0.0.1:2342<br/>(TensorFlow + Darktable RAW)"]
    SIDE["🗂️ /photoprism/storage<br/>Thumbnails & XMP Sidecars<br/>(Local NVMe SSD)"]
    DB["🗄️ MariaDB 11 (InnoDB)<br/>UTF8MB4 Metadata Index"]

    ORIG -->|"Read-Only Index"| PP
    PP <-->|"Writes Previews"| SIDE
    PP <-->|"SQL Queries"| DB

2. Production compose.yaml (PhotoPrism + MariaDB 11)

Never use SQLite for a PhotoPrism library exceeding a few thousand photos—concurrent thumbnail generation and TensorFlow indexing require MariaDB 11 tuned with innodb_buffer_pool_size:

# File: /srv/containers/photoprism/compose.yaml
services:
  photoprism:
    image: docker.io/photoprism/photoprism:latest
    container_name: photoprism
    depends_on:
      photoprism-db:
        condition: service_healthy
    restart: unless-stopped
    user: "1000:1000"
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "127.0.0.1:2342:2342/tcp"
    environment:
      PHOTOPRISM_ADMIN_USER: "nejat"
      PHOTOPRISM_ADMIN_PASSWORD: "${PP_ADMIN_PASSWORD}"
      PHOTOPRISM_AUTH_MODE: "password"
      PHOTOPRISM_SITE_URL: "https://photos.nejat-hakan.de/"
      PHOTOPRISM_SITE_TITLE: "NHDOC Photo Archive"
      # Never modify or delete files inside /photoprism/originals!
      PHOTOPRISM_READONLY: "true"
      PHOTOPRISM_ORIG_LINK: "false"
      # Database connection to MariaDB 11 container
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "photoprism-db:3306"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "photoprism"
      PHOTOPRISM_DATABASE_PASSWORD: "${PP_DB_PASSWORD}"
      # Performance & RAW conversion tuning
      PHOTOPRISM_WORKERS: "4"
      PHOTOPRISM_JPEG_QUALITY: "90"
    volumes:
      - /srv/photos/originals:/photoprism/originals:ro
      - /srv/containers/photoprism/storage:/photoprism/storage:rw

  photoprism-db:
    image: docker.io/library/mariadb:11
    container_name: photoprism-db
    restart: unless-stopped
    command:
      - --innodb-buffer-pool-size=1G
      - --transaction-isolation=READ-COMMITTED
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --max-connections=256
    environment:
      MARIADB_ROOT_PASSWORD: "${PP_DB_ROOT_PASSWORD}"
      MARIADB_DATABASE: "photoprism"
      MARIADB_USER: "photoprism"
      MARIADB_PASSWORD: "${PP_DB_PASSWORD}"
    volumes:
      - /srv/containers/photoprism/database:/var/lib/mysql:rw
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      timeout: 5s
      retries: 5

3. CLI Indexing, Face Clustering & Backup Operations

Trigger manual library re-indexing, facial recognition updates, or database backups directly via the photoprism CLI inside the container:

# File: /opt/photoprism-ops/maintenance_commands.sh
#!/usr/bin/env bash
set -euo pipefail

# 1. Index newly added photos in /photoprism/originals without re-scanning existing files
docker exec -it photoprism photoprism index

# 2. Re-cluster facial recognition embeddings and update people tags
docker exec -it photoprism photoprism faces update

# 3. Create a consistent compressed SQL dump of the PhotoPrism MariaDB index
docker exec -it photoprism photoprism backup -i -f /photoprism/storage/backups/photoprism_db.sql

Where to Go Next

Compare PhotoPrism with Immich mobile backups and BorgBackup off-site encryption:

  • Immich Mobile Photo & Video Cloud


    Explore Immich for automatic iOS/Android camera-roll backups and CLIP semantic natural-language search.

    Immich Guide

  • Encrypted Backups with BorgBackup


    Protect your irreplaceable /srv/photos/originals archive with deduplicated, encrypted off-site Borg repositories.

    BorgBackup Guide

  • Nextcloud Cloud Sync


    Synchronize documents, calendars, contacts, and mobile folders with a hardened Nextcloud stack.

    Nextcloud Guide