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.

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
- 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. - Linux-Host, VM oder NAS mit Docker-Unterstützung (x86_64 oder ARM64); ARMv7 (32-Bit) erfordert das gesonderte Image
photoprism/photoprism:armv7. - 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.
- SSD-Speicher für den Storage-Ordner (Thumbnails, Index, Cache) ist dringend empfohlen; mechanische Festplatten verlängern die Indexierung erheblich.
- Ausreichend freier Speicherplatz: Originaldateien + ca. 10–20 % Aufschlag für Thumbnails und Sidecars.
- Für HTTPS und eigene Domain: einen vorgeschalteten Reverse Proxy wie Traefik oder Caddy – siehe Caddy als Reverse Proxy mit automatischem HTTPS.
- Optional:
curlfür Health-Check-Verifikation im Terminal.
Eckdaten auf einen Blick
| Parameter | Wert |
|---|---|
| Image | photoprism/photoprism:latest (Build 260601, amd64 + arm64) |
| ARMv7 | photoprism/photoprism:armv7 |
| Web-UI-Port | 2342/tcp |
| Datenbank | MariaDB 11 (empfohlen) oder SQLite |
| Lizenz | AGPL (Community Edition, kostenlos) |
| RAM-Minimum | 4 GB RAM + 4 GB Swap |
| Architektur | linux/amd64, linux/arm64 (nativ) |
| Volume (Container-Pfad) | Zweck | Pflicht |
|---|---|---|
/photoprism/originals | Originaldateien (JPEG, RAW, HEIF, MP4 …) | Ja |
/photoprism/storage | Config, Cache, Thumbnails, SQLite-DB, Sidecars | Ja |
/photoprism/import | Eingangsordner für Import via WebDAV/Cronjob | Nein |
/var/lib/mysql | MariaDB-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/photoprismErstelle 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/storageVerifizieren: 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/storageSchränke die Dateiberechtigungen ein, damit andere System-Benutzer die Passwörter nicht lesen können:
chmod 600 /opt/photoprism/.envVerifizieren: 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: bridgeZwei 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 -dDer 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 photoprismWarte, 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:
- 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. - 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 --cleanupDie 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).
- 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 -dFü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).sqlDen 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
permission deniedoderread-only file system: Der Storage-Ordner ist vom Container-User (UID 1000) nicht beschreibbar. Lösung:sudo chown -R 1000:1000 /opt/photoprism/storageauf dem Host ausführen.- PhotoPrism startet, verbindet sich aber nicht mit der Datenbank (
no route to host): MariaDB ist noch nicht bereit. Dasdepends_on: condition: service_healthyin dercompose.yamlverhindert das in der Regel – prüfe, ob der MariaDB-Healthcheck nach mehreren Minuten noch immer fehlschlägt:docker inspect photoprism-db | grep Health. - Passwort-Änderung in
.envhat 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, dannALTER USER 'photoprism'@'%' IDENTIFIED BY 'neues-passwort'; - Container wird mit
killedbeendet (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. - Geteilte Links funktionieren nicht / WebDAV schlägt fehl:
PHOTOPRISM_SITE_URLstimmt nicht mit der tatsächlichen Zugriffsadresse überein. Wichtig: abschließenden Schrägstrich nicht vergessen (http://mein-server:2342/). - MariaDB startet nicht (Buffer-Pool-Fehler): Der Wert von
--innodb-buffer-pool-sizeist größer als der verfügbare RAM. Wert auf 128M oder 256M reduzieren; Faustregel: maximal 50–70 % des freien RAMs. - Thumbnails nach Neustart verschwunden: Storage-Verzeichnis wurde nicht persistent gemountet. Immer einen Host-Pfad oder ein benanntes Volume für
/photoprism/storageverwenden. - SELinux/AppArmor blockiert Volume-Zugriff (RHEL/Fedora/Ubuntu): Die
security_opt-Einträge in dercompose.yamlsind bereits gesetzt. Alternativ Volume-Mounts mit dem SELinux-Label:zoder:Zversehen.
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
- Docker und Docker Compose auf Linux installieren – die Self-Hosting-Grundlage
- Immich mit Docker: die selbstgehostete Google-Photos-Alternative
- Traefik als Docker-Reverse-Proxy mit automatischem HTTPS
- Caddy als Reverse Proxy: Anfänger-Anleitung mit automatischem HTTPS
- MySQL & PostgreSQL Backup automatisieren mit cron
- 3-2-1-Backup-Strategie praktisch umsetzen
- Ollama und Open WebUI mit Docker: lokales KI-Sprachmodell
Offizielle Quellen: PhotoPrism Docker Compose Setup · Konfigurationsoptionen · Troubleshooting Guide · GitHub Repository