Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 19.07.2026 · 10 min Lesezeit

PhotoPrism mit Docker installieren: KI-gestützte Fotoverwaltung als Google-Photos-Ersatz

PhotoPrism ist mit über 39.000 GitHub-Stars die mächtigste selbstgehostete Fotoverwaltung: KI-Gesichtserkennung (ONNX), automatisches Tagging per TensorFlow und eine vollständige Google-Photos-Alternative – datenschutzkonform auf eigenem Server per Docker Compose.

Moderne IT-Grafik zur Installation von PhotoPrism mit Docker. Sie zeigt einen lokalen Server, einen Container, ein Fotoarchiv und KI-gestützte Bilderkennung als Google-Photos-Alternative.

Wer seine Fotos nicht bei Google, Apple oder Microsoft in der Cloud wissen will, braucht eine überzeugende Alternative – und PhotoPrism ist genau das. Die selbstgehostete Fotoverwaltung analysiert deine Bibliothek automatisch per KI: TensorFlow- und ONNX-Modelle erkennen Gesichter, vergeben Labels, identifizieren Szenen und sortieren Bilder nach Ort, Datum und Inhalt. Mit über 39.000 GitHub-Stars ist PhotoPrism die meistgenutzte Open-Source-Lösung ihrer Art. Diese Anleitung zeigt dir, wie du PhotoPrism per docker compose auf einem beliebigen Linux-Host oder NAS in Betrieb nimmst – plattformneutral, ohne DSM-Klickpfade, mit MariaDB als Datenbank-Backend und vollständiger Verifikation nach jedem Schritt.

Voraussetzungen

  1. Docker Engine >= 20.10 mit dem docker compose-Plugin (v2) auf dem Host – eine Installationsanleitung findest du unter Docker und Docker Compose auf Linux installieren.
  2. Linux-Host, VM oder NAS mit Docker-Unterstützung (x86_64 oder ARM64); ARMv7 (32-Bit) erfordert das gesonderte Image photoprism/photoprism:armv7.
  3. Mindestens 4 GB RAM und 4 GB Swap – beim ersten Start lädt PhotoPrism TensorFlow-Modelle herunter, was ohne ausreichend Swap zum OOM-Kill führt.
  4. SSD-Speicher für den Storage-Ordner (Thumbnails, Index, Cache) ist dringend empfohlen; mechanische Festplatten verlängern die Indexierung erheblich.
  5. Ausreichend freier Speicherplatz: Originaldateien + ca. 10–20 % Aufschlag für Thumbnails und Sidecars.
  6. Für HTTPS und eigene Domain: einen vorgeschalteten Reverse Proxy wie Traefik oder Caddy – siehe Caddy als Reverse Proxy mit automatischem HTTPS.
  7. Optional: curl für Health-Check-Verifikation im Terminal.

Eckdaten auf einen Blick

ParameterWert
Imagephotoprism/photoprism:latest (Build 260601, amd64 + arm64)
ARMv7photoprism/photoprism:armv7
Web-UI-Port2342/tcp
DatenbankMariaDB 11 (empfohlen) oder SQLite
LizenzAGPL (Community Edition, kostenlos)
RAM-Minimum4 GB RAM + 4 GB Swap
Architekturlinux/amd64, linux/arm64 (nativ)
Volume (Container-Pfad)ZweckPflicht
/photoprism/originalsOriginaldateien (JPEG, RAW, HEIF, MP4 …)Ja
/photoprism/storageConfig, Cache, Thumbnails, SQLite-DB, SidecarsJa
/photoprism/importEingangsordner für Import via WebDAV/CronjobNein
/var/lib/mysqlMariaDB-Datenbankdateien (benanntes Volume)Ja (bei MariaDB)

Schritt 1: Projektordner anlegen

Lege einen dedizierten Ordner für den PhotoPrism-Stack an. Absolute Pfade sind hier Pflicht – relative Pfade funktionieren zwar für Tests, führen aber in Produktionssystemen zu schwer debugbaren Problemen:

sudo mkdir -p /opt/photoprism
cd /opt/photoprism

Erstelle außerdem die Host-Verzeichnisse für Originaldateien und Storage. Wichtig: Die beiden Ordner dürfen nicht ineinander verschachtelt sein – sonst indiziert PhotoPrism seine eigenen Cache-Dateien als Fotos.

sudo mkdir -p /opt/photoprism/photos
sudo mkdir -p /opt/photoprism/storage

# Container-User (UID 1000) muss schreibberechtigt sein
sudo chown -R 1000:1000 /opt/photoprism/storage

Verifizieren: ls -la /opt/photoprism/ zeigt photos/ und storage/; stat -c "%U %G" /opt/photoprism/storage gibt den Eigentümer zurück. Wenn kein Benutzer mit UID 1000 existiert, erscheint die numerische ID – das ist korrekt und reicht aus.

Schritt 2: .env-Datei mit Secrets anlegen

PhotoPrism liest Passwörter und Umgebungsvariablen aus der .env-Datei. Die Passwörter müssen vor dem ersten Start gesetzt werden – insbesondere MARIADB_PASSWORD kann nach dem ersten Start nicht mehr per Umgebungsvariable geändert werden. Der MariaDB-Container ignoriert eine spätere Änderung und PhotoPrism kann sich dann nicht mehr verbinden. Eine Änderung erfordert direkten SQL-Eingriff.

# /opt/photoprism/.env
# --- PhotoPrism ---
PHOTOPRISM_ADMIN_PASSWORD=mein-sicheres-passwort-min8
PHOTOPRISM_SITE_URL=http://192.168.1.100:2342/

# --- MariaDB ---
MARIADB_PASSWORD=db-passwort-sicher
MARIADB_ROOT_PASSWORD=root-passwort-sicher

# --- Optionale Host-Pfade (Standardwerte werden in compose.yaml gesetzt) ---
ORIGINALS_PATH=/opt/photoprism/photos
STORAGE_PATH=/opt/photoprism/storage

Schränke die Dateiberechtigungen ein, damit andere System-Benutzer die Passwörter nicht lesen können:

chmod 600 /opt/photoprism/.env

Verifizieren: ls -la /opt/photoprism/.env zeigt -rw-------. Prüfe mit grep PHOTOPRISM_ADMIN_PASSWORD /opt/photoprism/.env, dass das Passwort mindestens 8 Zeichen hat – kürzere Passwörter lehnt PhotoPrism beim Start ab.

Schritt 3: compose.yaml erstellen

Die folgende compose.yaml enthält alle wichtigen Produktions-Details: MariaDB-Healthcheck damit PhotoPrism erst startet wenn die Datenbank bereit ist, security_opt für SELinux/AppArmor-Umgebungen und benannte Volumes für die Datenbankdateien. Secrets werden ausschließlich aus der .env-Datei geladen.

# /opt/photoprism/compose.yaml
services:
  photoprism:
    image: photoprism/photoprism:latest
    container_name: photoprism
    restart: unless-stopped
    stop_grace_period: 10s
    depends_on:
      mariadb:
        condition: service_healthy
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    ports:
      - "2342:2342"
    environment:
      PHOTOPRISM_ADMIN_USER: "admin"
      PHOTOPRISM_ADMIN_PASSWORD: "${PHOTOPRISM_ADMIN_PASSWORD:-bitte-aendern}"
      PHOTOPRISM_AUTH_MODE: "password"
      PHOTOPRISM_SITE_URL: "${PHOTOPRISM_SITE_URL:-http://localhost:2342/}"
      PHOTOPRISM_ORIGINALS_LIMIT: 5000
      PHOTOPRISM_HTTP_COMPRESSION: "gzip"
      PHOTOPRISM_LOG_LEVEL: "info"
      PHOTOPRISM_READONLY: "false"
      PHOTOPRISM_EXPERIMENTAL: "false"
      PHOTOPRISM_DISABLE_CHOWN: "false"
      PHOTOPRISM_DISABLE_FACES: "false"
      PHOTOPRISM_DISABLE_CLASSIFICATION: "false"
      PHOTOPRISM_DISABLE_VECTORS: "false"
      PHOTOPRISM_DISABLE_RAW: "false"
      PHOTOPRISM_DETECT_NSFW: "false"
      PHOTOPRISM_UPLOAD_LIMIT: 500
      PHOTOPRISM_DATABASE_DRIVER: "mysql"
      PHOTOPRISM_DATABASE_SERVER: "mariadb:3306"
      PHOTOPRISM_DATABASE_NAME: "photoprism"
      PHOTOPRISM_DATABASE_USER: "photoprism"
      PHOTOPRISM_DATABASE_PASSWORD: "${MARIADB_PASSWORD:-db-passwort-aendern}"
      PHOTOPRISM_SITE_CAPTION: "KI-gestützte Fotoverwaltung"
    volumes:
      - "${ORIGINALS_PATH:-./photos}:/photoprism/originals"
      - "${STORAGE_PATH:-./storage}:/photoprism/storage"
    networks:
      - photoprism-net

  mariadb:
    image: mariadb:11
    container_name: photoprism-db
    restart: unless-stopped
    stop_grace_period: 10s
    security_opt:
      - seccomp:unconfined
      - apparmor:unconfined
    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: "${MARIADB_PASSWORD:-db-passwort-aendern}"
      MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT_PASSWORD:-root-passwort-aendern}"
    volumes:
      - photoprism_db:/var/lib/mysql
    networks:
      - photoprism-net
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 30s
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  photoprism_db:
    driver: local

networks:
  photoprism-net:
    driver: bridge

Zwei Parameter verdienen besondere Beachtung: --transaction-isolation=READ-COMMITTED ist laut PhotoPrism-Dokumentation für MariaDB zwingend erforderlich – ohne diese Einstellung kann es zu Index-Inkonsistenzen kommen. Der --innodb-buffer-pool-size-Wert von 512 MB ist für die meisten Heimserver passend; auf Systemen mit weniger als 2 GB RAM solltest du ihn auf 128–256 MB reduzieren (Faustregel: maximal 50–70 % des freien RAMs).

Verifizieren: docker compose config --quiet aus dem Verzeichnis /opt/photoprism/ ausführen. Kein Fehler bedeutet syntaktisch gültige YAML. Prüfe außerdem mit docker compose config | grep PHOTOPRISM_ADMIN_PASSWORD, dass das Passwort aus der .env-Datei korrekt substituiert wurde und nicht der Platzhalter bitte-aendern erscheint.

Schritt 4: Stack starten

Starte den Stack im Hintergrund. Docker Compose lädt zunächst beide Images herunter (photoprism/photoprism:latest ist ca. 900–950 MB je nach Architektur), initialisiert die MariaDB und wartet dank depends_on: condition: service_healthy auf den Healthcheck bevor PhotoPrism startet:

cd /opt/photoprism
docker compose up -d

Der erste Start dauert länger als gewöhnlich: PhotoPrism initialisiert TensorFlow-Modelle und legt das Datenbankschema an. Das ist kein Fehler – in den Logs erscheinen entsprechende Meldungen dazu.

# Status beider Container prüfen
docker compose ps

# Erwartete Ausgabe:
# NAME             IMAGE                          STATUS
# photoprism       photoprism/photoprism:latest   Up (healthy) oder Up X minutes
# photoprism-db    mariadb:11                     Up (healthy)
# Live-Logs verfolgen (Ctrl+C zum Beenden)
docker compose logs -f photoprism

Warte, bis in den Logs die Zeile server: listening on 0.0.0.0:2342 erscheint und kein ERROR mit Datenbankbezug zu sehen ist.

Verifizieren: curl -I http://localhost:2342/api/v1/status sollte HTTP/1.1 200 OK zurückgeben. Alternativ: docker compose ps zeigt für beide Container Up (MariaDB zusätzlich healthy). Erscheint PhotoPrism als Restarting, deutet das auf ein Datenbankverbindungsproblem hin – prüfe die Logs mit docker compose logs photoprism.

Schritt 5: Erste Einrichtung im Browser

Öffne im Browser http://<SERVER-IP>:2342/ und melde dich mit dem Benutzernamen admin und dem in der .env-Datei gesetzten Passwort an. Beim allerersten Login fragt PhotoPrism nach einer Bestätigung der Datenschutzhinweise.

Nach dem Login empfiehlt sich folgende Reihenfolge:

  1. Einstellungen prüfen: Unter Settings > General die Instanz-URL kontrollieren – sie muss mit dem Wert in PHOTOPRISM_SITE_URL übereinstimmen, sonst funktionieren geteilte Links nicht. Beachte dabei den abschließenden Schrägstrich.
  2. Erste Indexierung starten: Navigiere zu Library > Index und klicke Start. PhotoPrism durchsucht den originals-Ordner, erstellt Thumbnails und führt die KI-Analyse durch. Alternativ per CLI:
docker compose exec photoprism photoprism index --cleanup

Die Dauer der Indexierung hängt stark von der Bibliotheksgröße und der CPU-Leistung ab. Auf einem modernen Multi-Core-System rechne mit ca. 1–3 Sekunden pro Foto für vollständige KI-Analyse (Gesichtserkennung + Tagging).

  1. Google-Takeout importieren: Google-Takeout-Archive (ZIP entpackt) ins photos-Verzeichnis legen oder via Library > Import aus dem Import-Ordner einlesen. PhotoPrism liest die Google-JSON-Metadaten automatisch aus.

Verifizieren: Nach erfolgreichem Login und gestarteter Indexierung zeigt Library > Index den Fortschritt. Unter Browse erscheinen die ersten Fotos mit Thumbnails. Nach abgeschlossener KI-Analyse sind unter Labels automatische Tags und unter People erkannte Gesichter sichtbar.

Schritt 6: Updates und Backup

PhotoPrism-Updates bestehen aus einem Image-Pull und einem Container-Neustart. Dank MARIADB_AUTO_UPGRADE=1 werden Datenbankmigrationen automatisch durchgeführt:

cd /opt/photoprism
docker compose pull
docker compose up -d

Für ein Datenbank-Backup nutze mysqldump direkt aus dem Container:

docker compose exec mariadb mysqldump \
  -u root -p"${MARIADB_ROOT_PASSWORD}" photoprism \
  > /opt/photoprism/backup-$(date +%Y%m%d).sql

Den Storage-Ordner (/opt/photoprism/storage/) solltest du ebenfalls regelmäßig sichern – er enthält Konfiguration, Sidecars und den Thumbnail-Cache. Eine bewährte Strategie dafür beschreibt die Anleitung 3-2-1-Backup-Strategie praktisch umsetzen. Weitere Details zum Automatisieren von MariaDB-Backups findest du unter MySQL & PostgreSQL Backup automatisieren mit cron.

Verifizieren: Nach docker compose pull zeigt docker compose images den aktuellen Image-Digest. Nach up -d bestätigt docker compose ps wieder beide Container als Up. Prüfe die Logs auf Migrationsmeldungen: docker compose logs photoprism | grep -i migrat.

Troubleshooting / Typische Fehler

  1. permission denied oder read-only file system: Der Storage-Ordner ist vom Container-User (UID 1000) nicht beschreibbar. Lösung: sudo chown -R 1000:1000 /opt/photoprism/storage auf dem Host ausführen.
  2. PhotoPrism startet, verbindet sich aber nicht mit der Datenbank (no route to host): MariaDB ist noch nicht bereit. Das depends_on: condition: service_healthy in der compose.yaml verhindert das in der Regel – prüfe, ob der MariaDB-Healthcheck nach mehreren Minuten noch immer fehlschlägt: docker inspect photoprism-db | grep Health.
  3. Passwort-Änderung in .env hat keine Wirkung (MariaDB): Nach dem ersten Start ignoriert MariaDB Passwortänderungen per Umgebungsvariable. Das Passwort muss direkt per SQL geändert werden: docker compose exec mariadb mariadb -u root -p, dann ALTER USER 'photoprism'@'%' IDENTIFIED BY 'neues-passwort';
  4. Container wird mit killed beendet (OOM-Kill): Zu wenig RAM oder Swap. Mindestens 4 GB Swap auf dem Host konfigurieren; keine harten Memory-Limits in Docker setzen solange PhotoPrism TensorFlow-Modelle lädt.
  5. Geteilte Links funktionieren nicht / WebDAV schlägt fehl: PHOTOPRISM_SITE_URL stimmt nicht mit der tatsächlichen Zugriffsadresse überein. Wichtig: abschließenden Schrägstrich nicht vergessen (http://mein-server:2342/).
  6. MariaDB startet nicht (Buffer-Pool-Fehler): Der Wert von --innodb-buffer-pool-size ist größer als der verfügbare RAM. Wert auf 128M oder 256M reduzieren; Faustregel: maximal 50–70 % des freien RAMs.
  7. Thumbnails nach Neustart verschwunden: Storage-Verzeichnis wurde nicht persistent gemountet. Immer einen Host-Pfad oder ein benanntes Volume für /photoprism/storage verwenden.
  8. SELinux/AppArmor blockiert Volume-Zugriff (RHEL/Fedora/Ubuntu): Die security_opt-Einträge in der compose.yaml sind bereits gesetzt. Alternativ Volume-Mounts mit dem SELinux-Label :z oder :Z versehen.

Häufige Fragen

Wie starte ich die KI-Indexierung manuell?

Über die Web-UI unter Library > Index > Start oder per CLI: docker compose exec photoprism photoprism index --cleanup. Die Option --cleanup entfernt dabei verwaiste Index-Einträge für gelöschte Dateien. Gesichtserkennung (ONNX) und Auto-Tagging (TensorFlow) laufen automatisch während der Indexierung – du musst sie nicht separat anstoßen.

Brauche ich eine GPU für die KI-Funktionen?

Nein. Gesichtserkennung und Auto-Tagging laufen vollständig auf der CPU. Eine GPU beschleunigt optional die Videotranskodierung, ist aber nicht erforderlich. Auf einem modernen Quad-Core-System ist die Indexierung performant genug für Privatbibliotheken. Auf einem Raspberry Pi 4/5 (ARM64 nutzt das reguläre :latest-Image) dauert das erste Indexieren einer großen Bibliothek deutlich länger – plane entsprechend.

Kann ich meine Google-Photos-Bibliothek importieren?

Ja. Google-Takeout-Archiv herunterladen, das ZIP entpacken und den Inhalt in den konfigurierten originals-Ordner oder den import-Ordner legen. PhotoPrism liest die Google-JSON-Metadaten (Aufnahmedatum, GPS-Koordinaten, Beschreibung) automatisch aus. Der Import über Library > Import verschiebt Dateien in eine datumsorientierte Ordnerstruktur innerhalb von originals.

Was ist der Unterschied zwischen Community Edition und Membership?

Die Community Edition (kostenlos, AGPL) enthält alle KI-Funktionen – Gesichtserkennung, Auto-Tagging, Szenen- und Objekterkennung, NSFW-Erkennung – und ist vollständig selbst hostbar. Kostenpflichtige Memberships schalten OpenStreetMap-Kartenfunktionen (Foto-Karte mit GPS-Ansicht), erweiterte Benutzerrollen (mehrere Nutzer mit verschiedenen Zugriffsrechten) und kommerziellen Support frei. Für Einzelnutzer und kleine Teams reicht die Community Edition in aller Regel vollständig aus.

Wie funktioniert die Gesichtserkennung?

PhotoPrism erkennt Gesichter beim Indexieren automatisch mit einem ONNX-Modell (seit 2025 vollständig auf ONNX umgestellt, mit deutlich besseren Ergebnissen als zuvor). Erkannte Gesichter werden nach Ähnlichkeit geclustert und unter People angezeigt. Du kannst Cluster mit Namen versehen; PhotoPrism lernt daraus und verbessert die Zuordnung. Die Empfindlichkeit steuerst du über PHOTOPRISM_FACE_SIZE (minimale Gesichtsgröße in Pixeln) und PHOTOPRISM_FACE_SCORE (Qualitätsschwellenwert 1–100).

Wie sichere ich PhotoPrism regelmäßig?

Zwei Komponenten müssen gesichert werden: die MariaDB-Datenbank (per mysqldump wie in Schritt 6 gezeigt) und der storage-Ordner mit Konfiguration, Sidecars und Thumbnail-Cache. Die Originaldateien sicherst du unabhängig davon wie jede andere Mediensammlung. Automatische Datenbank-Backups aktiviert PHOTOPRISM_BACKUP_DATABASE=true im Environment.

Fazit

PhotoPrism ist die überzeugendste datenschutzkonforme Alternative zu Google Photos: KI-Gesichtserkennung auf ONNX-Basis, automatisches Tagging mit TensorFlow, Unterstützung für RAW, HEIF und Videodateien – alles auf eigenem Server, ohne Abonnement und ohne Cloud-Zwang. Der Stack aus compose.yaml und .env ist in 25 Minuten betriebsbereit; das MariaDB-Backend mit Healthcheck-Integration sorgt für Stabilität im Dauerbetrieb. Die Community Edition reicht für Privatpersonen und kleine Teams vollständig aus. Wer eine weitere schlanke Foto-Alternative sucht, findet in Immich mit Docker eine interessante Ergänzung. Für den Produktionsbetrieb empfiehlt sich ein vorgeschalteter Reverse Proxy mit HTTPS – Traefik als Docker-Reverse-Proxy ist dafür eine bewährte Wahl.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren – die Self-Hosting-Grundlage
  2. Immich mit Docker: die selbstgehostete Google-Photos-Alternative
  3. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS
  4. Caddy als Reverse Proxy: Anfänger-Anleitung mit automatischem HTTPS
  5. MySQL & PostgreSQL Backup automatisieren mit cron
  6. 3-2-1-Backup-Strategie praktisch umsetzen
  7. Ollama und Open WebUI mit Docker: lokales KI-Sprachmodell

Offizielle Quellen: PhotoPrism Docker Compose Setup · Konfigurationsoptionen · Troubleshooting Guide · GitHub Repository