Zum Inhalt springen
Serverküche
Suche

Die Suche wird geladen … (nur in der veröffentlichten Seite verfügbar).

Anwendungen Schwierigkeit: Fortgeschritten

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.

· 10 Min. Lesezeit ·Dauer: ca. 60 Minuten
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

Immich entwickelt sich rasant. Datenbank-Migrationen laufen beim Update automatisch und sind nicht rückwärtskompatibel – ein Downgrade ist danach nicht mehr sauber möglich. Pinne deshalb immer eine feste Version (hier v3.0.3) statt release oder latest, und mache vor jedem Update ein Backup. So bestimmst du, wann aktualisiert wird.

Voraussetzungen

Wie groß muss der Server sein?

Immich ist der ressourcenhungrigste Dienst der Serverküche. Offiziell werden mindestens 6 GB RAM (empfohlen 8) verlangt – vor allem der Machine-Learning-Dienst für Gesichtserkennung und Suche braucht Speicher. Der getestete VPS 1000 mit 8 GB RAM erfüllt das gerade, hat aber wenig Reserve. Für eine große Bibliothek oder mehrere Nutzer ist ein Server mit 16 GB RAM (z. B. VPS 2000) entspannter. Auf einem 4-GB-Server läuft Immich nur mit abgeschaltetem ML (siehe „Wenn es nicht funktioniert"). Und: Fotos brauchen Platz – plane genügend Festplatte ein.

Wie viel RAM deine Foto-Bibliothek samt KI-Suche wirklich braucht, rechnet dir der Server-Rechner aus.

🍳 Empfehlung Anzeige

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.

Zu netcup →

💶 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:

Terminal
dig +short photos.DEINE_DOMAIN

Es 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:

Terminal
mkdir -p ~/immich && cd ~/immich

Erstelle eine .env mit den Kernwerten (ein starkes DB-Passwort einsetzen – nur Buchstaben und Ziffern, keine Sonderzeichen, das mag Immichs DB-Init nicht):

INI
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
DB_PASSWORD=DEIN_DB_PASSWORT
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
IMMICH_VERSION=v3.0.3
  • UPLOAD_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:

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: true

Wichtig zu verstehen:

  • Nur immich-server hängt im proxy-Netz und trägt Traefik-Labels. Der ML-Dienst, Valkey und die Datenbank bleiben ausschließlich im internen default-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_healthy startet immich-server erst dann – das verhindert Migrationsfehler und den „Datenbank nicht erreichbar"-Start beim ersten Hochfahren.

Änderungen an der .env übernehmen

Wenn du später etwas in der .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):

YAML
    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:

Terminal
docker compose up -d
docker compose logs -f immich-server

Die Images sind mehrere Gigabyte groß – der erste pull braucht je nach Anbindung ein paar Minuten. Prüfe danach, dass alle vier Container laufen:

Terminal
docker compose ps

Du 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:

![Der Willkommensbildschirm von Immich mit den Optionen „Erste Schritte" und „Von Datenbank wiederherstellen"](immich-willkommen.png “Erster Aufruf: „Erste Schritte” wählen für eine frische Installation")

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:

Das Immich-Formular „Admin-Registrierung" mit Feldern für E-Mail, Passwort und Name
Admin-Registrierung – der erste Nutzer wird automatisch Administrator

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

Der Immich-Einrichtungsassistent begrüßt den neuen Administrator
Der Onboarding-Assistent nach dem ersten Login

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

Die leere Foto-Zeitleiste von Immich mit der Aufforderung, das erste Foto hochzuladen
Die Foto-Zeitleiste – hier laufen später alle Bilder ein (Server online, v3.0.3)

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

Immich wandelt Videos für die Wiedergabe im Browser um (Transcoding). Auf einem normalen VPS ohne Grafikkarte passiert das über die CPU – das ist bei vielen oder langen Videos spürbar langsamer und lastet Kerne aus. Für ein privates Handy-Backup ist das in der Regel kein Problem; wer sehr viel Video hat, sollte den Server entsprechend größer wählen.

Weitere Nutzer

Für die Familie legst du unter Administration → Benutzer weitere Konten an – jedes bekommt seine eigene, getrennte Bibliothek. Registrierung von außen ist standardmäßig aus; neue Nutzer entstehen nur über das Admin-Konto.

Deine Fotos hängen im Internet

Sobald Immich über 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:

    Terminal
    docker 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-server

    Sichere 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_VERSION erhöhen, dann docker 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