← Blog

Immich für deine Fotobibliothek selbst hosten

Railyard

5. Juni 2026 · 7 Min. Lesezeit

Folge dem auf deinem eigenen Server. Kostenlos starten, keine Karte nötig

Google Photos sichert deine Bibliothek kostenlos, bis es das nicht mehr tut, und in dem Moment, in dem es aufhört, kostenlos zu sein, hat es auch jedes Gesicht und jeden Ort, an dem deine Fotos aufgenommen wurden, auf Hardware indexiert, die du nicht kontrollierst. Immich ist eine Open-Source-Alternative, die denselben Job (automatisches Backup von deinem Handy, eine Zeitleiste, Gesichtserkennung, Suche nach Objekt oder Ort) als selbst gehostete App macht: ein Haupt-Image, ein Machine-Learning-Worker für die KI-Features, Redis für Background-Jobs, und Postgres mit einer Vektor-Erweiterung für die Suche. Diese Anleitung richtet das alles auf einem leeren Server ein, und zeigt dann den Ein-Klick-Weg, falls du die Container nicht selbst betreiben willst.

Am Ende ist Immich über HTTPS auf deiner eigenen Domain erreichbar, dein Handy sichert automatisch darauf, und du hast einen Backup-Plan für die zwei Dinge, die wirklich zählen: deine Fotos und die Datenbank, die sie indexiert.

Was du brauchst

  • Einen Server mit echtem Speicher übrig. Immichs Machine-Learning-Worker (Gesichtserkennung, Objektsuche) braucht echte CPU und RAM zusätzlich zur Web-App und Datenbank, ein Hetzner CX33 (4 vCPU, 8 GB RAM, 80 GB NVMe) für 8,99 €/Monat exkl. MwSt. ist also ein sichererer Startpunkt als die kleinste Stufe; ein ähnlich dimensionierter Server bei jedem anderen Anbieter funktioniert genauso.
  • Eine Domain oder Subdomain mit einem DNS-A-Record, den du auf den Server zeigen lassen kannst (diese Anleitung nutzt photos.example.com).
  • Die Immich-Mobile-App (iOS oder Android), sobald der Server läuft.
  • SSH-Zugang und etwa 20 Minuten.

Schritt 1: Den Server provisionieren und DNS darauf zeigen lassen

Lege den Server mit Ubuntu 24.04 (oder einer aktuellen Debian-basierten Distribution) an, notiere seine öffentliche IPv4-Adresse, und lege einen DNS-A-Record an:

photos.example.com.  A  203.0.113.20

Verbinde dich per SSH und aktualisiere das System:

ssh root@203.0.113.20
apt update && apt upgrade -y

Schritt 2: Docker installieren

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker --version
docker compose version

Du solltest eine Docker-Engine-Version und eine Compose-v2.x-Version ohne Fehler sehen.

Schritt 3: Die Umgebungsdatei schreiben

Immichs eigene Installationsdoku verweist auf ein docker-compose.yml-und-.env-Paar, das in seinem GitHub-Repository gepflegt wird; diese Anleitung nutzt die aktuelle Version, Immich v3.3.5. Lege ein Arbeitsverzeichnis und die .env-Datei an:

mkdir -p /opt/immich && cd /opt/immich
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
DB_PASSWORD=change-this-to-a-random-alnum-string
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
IMMICH_VERSION=v3.3.5
TZ=America/Montreal

DB_PASSWORD hat eine echte Einschränkung, die du kennen solltest, bevor du eines generierst: Immichs eigene Doku verlangt nur Buchstaben und Ziffern, keine Satzzeichen, da das Passwort direkt in einen Connection-String eingefügt wird. UPLOAD_LOCATION ist, wo jedes Foto und Video tatsächlich auf der Festplatte liegt, behandle diesen Pfad also als das eine Verzeichnis auf diesem Server, das du dir niemals leisten kannst zu verlieren.

Schritt 4: Die Docker-Compose-Datei schreiben

Das spiegelt Immichs offizielle Compose-Datei, mit Caddy davor für HTTPS hinzugefügt:

services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy-data:/data
      - caddy-config:/config

  immich-server:
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-v3.3.5}
    restart: always
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    depends_on:
      - redis
      - database

  immich-machine-learning:
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-v3.3.5}
    restart: always
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    environment:
      MACHINE_LEARNING_MODEL_REVISION: v2

  redis:
    image: docker.io/valkey/valkey:9
    restart: always
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep -q PONG || exit 1"]

  database:
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
    restart: always
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: "--data-checksums"
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    shm_size: 128mb

volumes:
  model-cache:
  caddy-data:
  caddy-config:

Das Datenbank-Image ist kein normales Postgres: Es ist Immichs eigener Build mit den eingebauten vectorchord- und pgvecto.rs-Erweiterungen, die Gesichts- und Objektsuche im großen Maßstab schnell machen. Tausche es nicht gegen ein generisches postgres-Image aus, auch wenn die Env-Variablen identisch aussehen.

Validiere, bevor du hochfährst:

docker compose config

Schritt 5: Die Caddyfile schreiben

photos.example.com {
    reverse_proxy immich-server:2283

    request_body {
        max_size 10GB
    }
}

Der request_body-Block ist hier besonders wichtig: Caddys Standard-Limit für die Anfragegröße ist für eine Webseite angenehm, aber nicht für ein 4K-Video vom Handy, ohne es zu erhöhen scheitern große Video-Uploads also auf halbem Weg mit einem verwirrenden Connection-Reset statt einer klaren Fehlermeldung.

Schritt 6: Den Stack hochfahren

docker compose up -d
docker compose ps

Du solltest caddy, immich-server, immich-machine-learning, redis und database alle als running gelistet sehen. Verfolge beim ersten Mal die Logs des Servers, um zu bestätigen, dass er seine eigenen Startup-Migrationen beendet hat:

docker compose logs -f immich-server

Öffne https://photos.example.com; du solltest auf Immichs Account-Erstellungsbildschirm über einem gültigen HTTPS-Zertifikat landen. Lege den ersten Account an, der zum Admin des Servers wird.

Schritt 7: Die Mobile-App verbinden

Installiere Immich aus dem App Store oder Play Store, öffne es und gib die URL deines Servers (https://photos.example.com) am Login-Bildschirm ein, logg dich dann mit dem Account aus Schritt 6 ein. Schalte das Hintergrund-Backup in den Einstellungen der App ein. Du solltest sehen, wie deine Kamerarolle zu uploaden beginnt, sichtbar als Fortschrittsanzeige in der App und als neue Fotos, die innerhalb von ein, zwei Minuten im Web-Dashboard auftauchen.

Schritt 8: Die Daten sichern, die wirklich zählen

Zwei Dinge können nicht regeneriert werden: die Postgres-Datenbank (der Index: Alben, Gesichter, Metadaten) und der library-Ordner (die tatsächlichen Foto- und Videodateien). Sichere beide, nach Zeitplan, irgendwohin außer auf diesen Server:

docker compose exec -T database pg_dumpall -U postgres | gzip > /opt/immich/backups/immich-db-$(date +%F).sql.gz
tar -czf /opt/immich/backups/immich-library-$(date +%F).tar.gz -C /opt/immich library

Kopiere beide Dateien per Cron-Job vom Server weg (Object Storage, eine andere Maschine). Die Datenbank allein aus einem Dump wiederherzustellen reicht, um die App wieder laufen zu lassen; den library-Ordner gleich mit wiederherzustellen ist, was die wiederhergestellte App deine Fotos wieder tatsächlich zeigen lässt.

Schritt 9: Upgrades

Erhöhe IMMICH_VERSION in .env auf den neuen Tag, dann:

docker compose pull
docker compose up -d

Immich liefert häufige Releases, und die Mobile-App und der Server sind gemeinsam versioniert: zeigt die App nach einem Upgrade eine Versions-Mismatch-Warnung, aktualisiere zuerst die App aus ihrem Store, statt den Server zu debuggen.

Die Abkürzung: mit Railyard

Alles oben, die vier Container, die Umgebungsdatei, der Reverse-Proxy, der Backup-Zeitplan, ist das, was Railyards Immich-Stack-Vorlage für dich einrichtet. Verbinde einen Server, wähle dann Immich im Vorlagenkatalog: https://app.railyard.run/deploy?stack=immich. Railyard provisioniert alle vier Dienste zusammen, verdrahtet die Datenbank- und Redis-Connection-Strings automatisch und stellt das HTTPS-Zertifikat für deine Domain aus.

Eine ehrliche Einschränkung, die du kennen solltest: der Machine-Learning-Worker ist genauso CPU- und speicherhungrig wie im manuellen Setup, dimensioniere den Server also dafür statt für die kleinste verfügbare Option, genau wie in Schritt 1. Und eine Eigenheit, die du in jedem Fall in den Logs siehst: Immichs eigenes Startup-Log gibt für einen an 0.0.0.0 gebundenen Server immer 127.0.0.1 aus, das ist die eigene Anzeige-Substitution des Frameworks, kein Zeichen für eine Fehlkonfiguration.

Sobald es läuft, decken Datenbank-Backups die Postgres-Seite nach Zeitplan ab; das library-Volume braucht trotzdem seine eigene Kopie außerhalb des Servers, genauso wie im manuellen Setup oben.

Troubleshooting

HTTPS wird nie ausgestellt. DNS zeigt noch nicht auf den Server. dig +short photos.example.com sollte die IP des Servers zurückgeben; Caddy wiederholt es selbst, sobald das stimmt.

Uploads scheitern auf halbem Weg, besonders Videos. Das ist fast immer Caddys Limit für die Anfragegröße, behandelt in Schritt 5. Bestätige, dass der request_body-Block tatsächlich in der aktiven Caddyfile steht, mit docker compose exec caddy caddy fmt --overwrite /etc/caddy/Caddyfile, gefolgt von einem Neustart.

Der Machine-Learning-Container ist langsam oder wird gekillt. Prüfe docker stats, während ein Backup läuft. Wenn immich-machine-learning bei 100% CPU festhängt oder der Container beendet wird, ist der Server für Background-Tasks wie Gesichtserkennung auf einer großen Bibliothek unterdimensioniert; ein CX33 bewältigt den normalen Gebrauch, aber der erste vollständige Scan einer sehr großen existierenden Bibliothek profitiert von mehr.

Die Mobile-App zeigt einen Versions-Mismatch. Immich pinnt die Kompatibilität zwischen App und Server recht eng. Aktualisiere, was auch immer zurückliegt, meist die App, aus ihrem Store.

Die Login-Seite lädt, aber der Admin-Account lässt sich nicht anlegen. Prüfe docker compose logs database auf eine fehlgeschlagene Migration, meist verursacht dadurch, dass DB_PASSWORD ein Zeichen außerhalb von A-Za-z0-9 enthält, das den in Schritt 3 erwähnten Connection-String zerstört hat.

FAQ

Wie viel Speicherplatz brauche ich wirklich? Was auch immer deine Foto- und Videobibliothek heute ist, plus Spielraum für Wachstum; Immich komprimiert oder re-encodiert Originale standardmäßig nicht, das library-Volume wächst also etwa im gleichen Tempo wie deine Kamerarolle.

Können mehrere Personen dieselbe Instanz nutzen? Ja. Lege zusätzliche Accounts über das Admin-Panel an; jeder hat seine eigene Bibliothek und Freigabe-Einstellungen, mit admin-kontrollierten Speicherquoten pro Nutzer, falls du das möchtest.

Braucht der Machine-Learning-Worker eine GPU? Nein, er läuft standardmäßig auf CPU, und das ist, was diese Anleitung einrichtet; Immichs eigene Dokumentation behandelt optionale Hardware-Beschleunigung (NVIDIA, Intel, AMD) für größere Bibliotheken, die mehr Setup-Komplexität gegen schnelleres Indexieren tauscht.

Was passiert, wenn ich den Server ohne Backup verliere? Alles ist weg: die Fotos und der Index, beides. Schritt 8 ist für nichts optional, das du tatsächlich vermissen würdest.

Ist das wirklich kostenlos zu betreiben? Die Software ist es, der Server nicht; ein CX33 für etwa neun Euro im Monat ist die echte laufende Kostenseite, ohne Gebühr pro Foto oder Gigabyte, wie manche Cloud-Speicherpläne das aufbauen.

Immich gibt dir das meiste von dem, was ein gehosteter Fotodienst macht, auf Hardware, die du kontrollierst, für die Kosten eines kleinen Servers statt eines Abos, das mit der Anzahl deiner Fotos skaliert. Das Setup hier ist eine Umgebungsdatei, eine Compose-Datei und ein Reverse-Proxy; von dort aus ist es dieselbe App auf deinem Handy, die genauso sichert, auf einem Server mit deinem Namen auf der Rechnung statt dem von jemand anderem.

Warum Leute sich dafür Railyard entscheiden

  • Dein eigenes Cloud-Konto. Deploye auf DigitalOcean, Hetzner, Vultr, AWS, OVHcloud oder jedem Linux-Server per SSH, direkt von deinem Anbieter abgerechnet, ohne Aufschlag.
  • Ein fester Preis pro Team. Free ist für immer kostenlos: ein Server plus ein Datenbankserver, drei Apps, keine Karte. Pro kostet 19 $ im Monat für bis zu fünf Server und unbegrenzte Apps. Team kostet 49 $ im Monat mit unbegrenzten Servern. Keine Kosten pro App, pro Deployment, pro Sitz oder pro Gigabyte.
  • Templates mit einem Klick. Deploye Open-Source-Apps, wie Datenbanken, Analytics und Dev-Tools, mit einem Klick auf deinem eigenen Server.
  • Verwaltete Datenbanken. Postgres, MySQL und Redis mit geplanten, wiederherstellungsgeprüften Backups und Point-in-Time-Recovery.
  • Push-to-Deploy. Deploye von GitHub, GitLab oder der CLI, mit automatischem HTTPS und Releases ohne Ausfallzeit.

Server-Setup überspringen

Deploye Immich aus dem Vorlagenkatalog auf Railyard, mit Datenbank und Machine-Learning-Worker bereits verdrahtet.

Kostenloser Plan, keine Kreditkarte, und 14 Tage Pro für jedes neue Team. Ein fester Preis pro Team.