Immich selbst hosten: dein privates Foto-Backup hinter Traefik
Immich mit Docker hinter Traefik aufsetzen: die selbst gehostete Alternative zu Google Fotos – mit automatischem Handy-Backup, Gesichtserkennung und HTTPS.
Inhaltsverzeichnis
Tausende Fotos und Videos vom Handy – und alle liegen bei Google oder Apple. Immich holt sie zurück auf deinen Server: ein selbst gehosteter Foto-Dienst, der Google Fotos verblüffend nahekommt, inklusive automatischem Handy-Upload, Zeitleiste, Suche und Gesichtserkennung. In diesem Rezept setzen wir Immich sauber hinter Traefik auf.
Was bauen wir?
Am Ende läuft Immich v3 hinter deinem Traefik-Proxy, erreichbar unter
https://photos.DEINE_DOMAIN mit gültigem HTTPS. Die offizielle Immich-Handy-App
sichert deine neuen Fotos und Videos dann automatisch auf deinen Server – wie die
Cloud-Sicherung von Google Fotos, nur dass die Bilder ausschließlich bei dir liegen.
Über die Web-Oberfläche durchstöberst du deine Zeitleiste, suchst per Volltext
(„Strand", „Hund") und lässt Immich Gesichter gruppieren.
Immich besteht aus vier Containern: dem Server (Web + API), einem Machine-Learning-Dienst (für Suche und Gesichtserkennung), einer PostgreSQL-Datenbank mit Vektor-Erweiterung und einem Cache (Valkey). Klingt nach viel – die offizielle Vorlage nimmt uns aber den Großteil ab, und wir hängen davon nur den Server an Traefik.
Der Reiz gegenüber Google Fotos: Die Bilder verlassen deinen Server nicht, es gibt keine Speicherplatz-Abos und keine automatische Auswertung deiner Aufnahmen durch einen Konzern. Dafür trägst du die Verantwortung für Betrieb und – ganz wichtig – für Backups: Wenn der Server stirbt und du keine Sicherung hast, sind die Fotos weg. Genau deshalb steht das Backup weiter unten nicht als Kür, sondern als Pflicht.
Immich ist schnelllebig – Version pinnen
v3.0.3) statt release oder latest,
und mache vor jedem Update ein Backup. So bestimmst du, wann aktualisiert wird.Voraussetzungen
- Ein laufender Traefik-Reverse-Proxy mit dem
proxy-Netzwerk und dem Let’s-Encrypt-Resolverle– siehe Reverse Proxy mit Traefik. - Eine Subdomain
photos.DEINE_DOMAINmit DNS-Record auf deine Server-IP – siehe Domain mit Server verbinden. - Ein Backup. Deine Fotosammlung ist unersetzlich – richte zuerst Backups mit Restic ein.
Wie groß muss der Server sein?
Wie viel RAM deine Foto-Bibliothek samt KI-Suche wirklich braucht, rechnet dir der Server-Rechner aus.
VPS 2000 G12
8 vCore · 16 GB RAM · 512 GB NVMe
ab 19,24 €/Monat
Für eine große Foto-Bibliothek mit Gesichtserkennung sind 16 GB RAM angenehm.
💶 5 € Gutschein für netcup-Neukunden:
36nc17844976032
(nur Neukunden, keine Domains)
Schritt für Schritt
Schritt 1: DNS-Record anlegen
Lege einen Eintrag photos.DEINE_DOMAIN an, der auf deine Server-IP zeigt, und prüfe ihn:
dig +short photos.DEINE_DOMAINEs muss deine Server-IP zurückkommen – sonst holt Traefik später kein Zertifikat.
Schritt 2: Ordner und .env vorbereiten
Immich wird über eine .env-Datei konfiguriert. Leg das Projekt an:
mkdir -p ~/immich && cd ~/immichErstelle eine .env mit den Kernwerten (ein starkes DB-Passwort einsetzen – nur
Buchstaben und Ziffern, keine Sonderzeichen, das mag Immichs DB-Init nicht):
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
DB_PASSWORD=DEIN_DB_PASSWORT
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
IMMICH_VERSION=v3.0.3UPLOAD_LOCATION– hier landen deine Fotos und Videos. Das ist das wichtigste Verzeichnis fürs Backup.DB_DATA_LOCATION– die PostgreSQL-Daten. Muss auf einer lokalen Platte liegen (kein Netzlaufwerk/NFS – die DB nimmt das übel).IMMICH_VERSION– die gepinnte Version.
Schritt 3: Die compose.yaml anlegen
Wir übernehmen die offizielle Immich-Vorlage und ergänzen nur die Traefik-Labels am
immich-server. Erstelle compose.yaml:
name: immich
services:
immich-server:
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION}
volumes:
- ${UPLOAD_LOCATION}:/data
- /etc/localtime:/etc/localtime:ro
env_file: .env
environment:
DB_HOSTNAME: database
REDIS_HOSTNAME: redis
depends_on:
redis:
condition: service_started
database:
condition: service_healthy
labels:
- "traefik.enable=true"
- "traefik.http.routers.immich.rule=Host(`photos.DEINE_DOMAIN`)"
- "traefik.http.routers.immich.entrypoints=websecure"
- "traefik.http.routers.immich.tls.certresolver=le"
- "traefik.http.services.immich.loadbalancer.server.port=2283"
networks: [default, proxy]
restart: unless-stopped
immich-machine-learning:
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION}
volumes:
- model-cache:/cache
networks: [default]
restart: unless-stopped
redis:
image: docker.io/valkey/valkey:9
networks: [default]
restart: unless-stopped
database:
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE_NAME}"]
interval: 10s
timeout: 5s
retries: 5
networks: [default]
restart: unless-stopped
volumes:
model-cache:
networks:
default:
proxy:
external: trueWichtig zu verstehen:
- Nur
immich-serverhängt improxy-Netz und trägt Traefik-Labels. Der ML-Dienst, Valkey und die Datenbank bleiben ausschließlich im internendefault-Netz – von außen nicht erreichbar. loadbalancer.server.port=2283– Immich lauscht im Container auf Port 2283.- Die Datenbank ist bewusst das vorgebaute Immich-Postgres-Image mit der
Vektor-Erweiterung VectorChord (für die Bildsuche). Nimm nicht einfach ein
Standard-
postgres– die Erweiterung fehlt dann. - Valkey ist der Redis-Nachfolger; der Service heißt in der Immich-Vorlage aus
Kompatibilitätsgründen weiterhin
redis. - Der Healthcheck an der Datenbank meldet, wann Postgres wirklich bereit ist. Über
depends_on: … condition: service_healthystartetimmich-servererst dann – das verhindert Migrationsfehler und den „Datenbank nicht erreichbar"-Start beim ersten Hochfahren.
Änderungen an der .env übernehmen
.env änderst, reicht ein docker compose restart nicht –
Docker liest die Umgebungsvariablen nur beim Neuerstellen der Container. Nutze dann
docker compose up -d; Compose erkennt die Änderung und baut die betroffenen Container neu.Schritt 4: Große Uploads erlauben (Traefik-Timeout)
Das ist der Stolperstein bei Immich hinter Traefik: Standardmäßig bricht Traefik
Verbindungen nach 60 Sekunden ab (readTimeout). Beim Hochladen großer Videos vom
Handy führt das zu abgebrochenen Uploads (Fehler 502/499). Erhöhe den Timeout am
websecure-Entrypoint in deiner Traefik-Konfiguration (der traefik-Service aus dem
Traefik-Tutorial):
command:
# ... deine bestehenden Zeilen ...
- "--entrypoints.websecure.transport.respondingTimeouts.readTimeout=600s"Starte Traefik danach neu (docker compose up -d im Traefik-Ordner). Anders als nginx hat
Traefik kein festes Größenlimit für Uploads – nur dieser Timeout muss hoch.
Schritt 5: Starten und den Erst-Setup durchlaufen
Zieh die Images (mehrere GB – das dauert) und starte:
docker compose up -d
docker compose logs -f immich-serverDie Images sind mehrere Gigabyte groß – der erste pull braucht je nach Anbindung ein
paar Minuten. Prüfe danach, dass alle vier Container laufen:
docker compose psDu solltest immich-server, immich-machine-learning, redis und database mit Status
running (die Datenbank healthy) sehen. Warte, bis im Log
Immich Server is listening on http://[::1]:2283 [v3.0.3] erscheint.
Ruf dann https://photos.DEINE_DOMAIN auf. Traefik holt beim ersten Zugriff das
Let’s-Encrypt-Zertifikat (einen Moment Geduld). Beim allerersten Start begrüßt dich Immich mit
„Willkommen bei Immich" und der Wahl, ob du neu startest oder eine Sicherung
wiederherstellst:

Klick auf Erste Schritte (Wiederherstellen brauchst du nur, wenn du ein Backup einspielst). Danach legst du das Administrator-Konto an – als erster Nutzer wirst du automatisch Admin:

Nach dem ersten Login führt dich ein kurzer Einrichtungs-Assistent durch Theme, Sprache und Datenschutz-Grundeinstellungen:

Danach landest du auf deiner (noch leeren) Zeitleiste – das Herzstück von Immich:

Schritt 6: Die Handy-App verbinden
Der eigentliche Nutzen kommt von der App. Installiere Immich aus dem App Store bzw.
Play Store (oder F-Droid). Beim Start fragt sie nach der Server-Adresse – trag
https://photos.DEINE_DOMAIN ein und melde dich mit deinem Konto an. Aktiviere dann in den
App-Einstellungen die Sicherung und wähle die Alben, die hochgeladen werden sollen.
Ab jetzt sichert dein Handy neue Fotos automatisch auf deinen Server – im Hintergrund und über WLAN. Der erste Durchlauf einer großen Mediathek dauert; danach kommen nur noch neue Aufnahmen dazu.
Nach dem Upload arbeitet Immich im Hintergrund weiter: Es erzeugt Vorschaubilder, liest die Aufnahme-Metadaten (Datum, Ort) aus und lässt den ML-Dienst Gesichter erkennen und die Bilder für die intelligente Suche indexieren. Diese Jobs laufen einige Zeit nach dem ersten großen Import – Gesichter und Suchtreffer tauchen also erst nach und nach auf. Den Fortschritt siehst du unter Administration → Auftragswarteschlangen. In der Seitenleiste findest du dann die typischen Foto-Funktionen: Erkunden (nach Personen und Orten), die Karte mit Geo-Verortung, Alben zum Teilen und die Rückblicke („Vor einem Jahr").
Videos & Transcoding auf dem VPS
Weitere Nutzer
Deine Fotos hängen im Internet
photos.DEINE_DOMAIN erreichbar ist, steht die Anmeldeseite offen im
Netz. Vergib deshalb ein langes, einmaliges Passwort für das Admin- und alle
Nutzerkonten und aktiviere die Zwei-Faktor-Authentifizierung in den Kontoeinstellungen.
Wer ganz sichergehen will, macht Immich nur über ein VPN erreichbar – für den automatischen
Handy-Upload ist die direkte HTTPS-Erreichbarkeit aber meist der praktischere Weg.Wenn es nicht funktioniert
Symptom: Uploads großer Videos brechen nach etwa einer Minute ab (Fehler 502 oder 499).
Ursache & Lösung: Traefiks readTimeout (Standard 60 s) greift. Setz ihn wie in
Schritt 4 auf 600s (oder höher) und starte Traefik neu. Das ist mit Abstand der
häufigste Immich-hinter-Proxy-Fehler.
Symptom: Der immich-machine-learning-Container stürzt ab bzw. beendet sich mit
„exit 137", Suche und Gesichtserkennung funktionieren nicht.
Ursache & Lösung: Zu wenig RAM – der Container wurde vom System beendet (Out of
Memory). Gib dem Server mehr Speicher, oder deaktiviere ML, indem du den Service
immich-machine-learning aus der compose.yaml entfernst. Immich läuft dann ohne
Gesichtserkennung und intelligente Suche, aber Upload und Zeitleiste funktionieren normal.
Symptom: Nach einem Update starten die Container nicht mehr oder melden Migrationsfehler.
Ursache & Lösung: Server, Machine-Learning und Datenbank müssen auf derselben
Version laufen. Setz in der .env die neue IMMICH_VERSION und aktualisiere alle
Container gemeinsam (docker compose pull && docker compose up -d). Ein Downgrade nach
einer Migration ist nicht möglich – nur ein Rücksetzen aus dem Backup.
Symptom: Immich zeigt „Wartungsmodus" / „Vorübergehend nicht verfügbar".
Ursache & Lösung: Immich v3 startet bei bestimmten Datenbank-Zuständen in einen
Wartungsmodus. Im Log (docker compose logs immich-server) steht dann eine URL mit einem
einmaligen Token (…/maintenance?token=…) – darüber meldest du dich am Wartungsmodus
an und wählst „neu starten" bzw. beendest ihn. Danach ist die normale Oberfläche wieder da.
Symptom: Container startet nicht, „permission denied" beim Datenbank- oder Upload-Verzeichnis.
Ursache & Lösung: UPLOAD_LOCATION oder DB_DATA_LOCATION haben die falschen
Zugriffsrechte oder liegen auf einem Netzlaufwerk. Lege beide auf einer lokalen Platte an
und stelle sicher, dass Docker hineinschreiben darf.
Wartung & Backups
Zwei Dinge gehören ins Backup – konsistent zusammen. Deine Fotos (
UPLOAD_LOCATION, also~/immich/library) und die Datenbank. Der DB-Dump enthält nur die Metadaten; ohne die passenden Dateien ist er wertlos, und umgekehrt. Am saubersten stoppst du Immich kurz und sicherst beides zusammen:Terminaldocker compose stop immich-server docker compose exec -T database pg_dump --clean --if-exists \ --dbname=immich --username=postgres | gzip > immich-db.sql.gz docker compose start immich-serverSichere den Dump zusammen mit dem
library-Ordner verschlüsselt und off-site mit Restic. Alternativ kann Immich unter Administration → Auftragswarteschlangen automatische DB-Dumps erzeugen – die Fotos musst du trotzdem separat sichern.Den Ernstfall einmal proben. Ein Backup, das du nie zurückgespielt hast, ist nur eine Hoffnung. Zum Wiederherstellen spielst du den DB-Dump in eine frische Immich-Instanz gleicher Version ein und legst den
library-Ordner an dieselbe Stelle – Immich bietet dafür beim ersten Start den Punkt „Von Datenbank wiederherstellen" an (der zweite Knopf aus Schritt 5). Wichtig ist die gleiche Version: Datenbank-Stand und Programm müssen zusammenpassen.Backup vor jedem Update. Weil Migrationen nicht umkehrbar sind, ist das Backup dein einziger Rückweg. Erst sichern, dann
IMMICH_VERSIONerhöhen, danndocker compose pull && docker compose up -d.Ehrlich zum Aufwand: Immich bringt oft mehrere Releases pro Monat. Du musst nicht jedem folgen – aber lies vor einem Sprung über mehrere Versionen die Release-Notes, und halte dich an die gepinnte Version, bis du bewusst aktualisierst.
Speicherplatz im Blick behalten. Fotos und Videos wachsen stetig; Immich legt zusätzlich Vorschaubilder und umgewandelte Videos an. Überwache die Plattenbelegung (z. B. mit Uptime Kuma), damit dir der Server nicht volläuft.
Feedback per E-Mail: feedback@serverkueche.de
Das könnte dir auch schmecken

Paperless-ngx selbst hosten: papierloses Büro mit OCR
Paperless-ngx mit Docker hinter Traefik aufsetzen: Dokumente per OCR durchsuchbar archivieren – mit Volltextsuche, Tags …

Nextcloud selbst hosten: deine eigene Cloud hinter Traefik
Nextcloud mit Docker hinter Traefik aufsetzen: eigene Cloud für Dateien, Kalender und Kontakte – mit MariaDB, Redis und …

Uptime Kuma installieren: Server-Monitoring hinter Traefik
Uptime Kuma hinter Traefik aufsetzen und deine Dienste überwachen: Monitore, Benachrichtigungen und eine Status-Seite – …