Immich Self-Hosting mit Hetzner: Fotos & Videos günstig in der Cloud sichern

Get Site as Markdown

Wer seine Fotos und Videos selbst hosten möchte, ohne ein Vermögen für Cloud-Speicher auszugeben, kommt an Immich kaum vorbei. Immich ist eine quelloffene Alternative zu Google Photos – mit automatischer Gesichtserkennung, Geodaten-Anzeige, Duplikaterkennung und vielem mehr. In diesem Artikel zeige ich, wie man Immich auf einem Hetzner Cloud VPS in Kombination mit einer Hetzner Storage Box betreibt.

Warum Hetzner?

Hetzner bietet vergleichsweise niedrige Preise für Cloud-Infrastruktur in Europa. Im Gegensatz zu Hyperscalern wie AWS, Azure oder Google Cloud gibt es:

  • Feste Preise ohne versteckte Egress-Traffic-Kosten
  • DSGVO-konformes Hosting mit Rechenzentren in Deutschland und Finnland
  • Inklusiv-Traffic bei allen Cloud-Servern
  • Storage Boxes mit Samba/CIFS-, SSH- und WebDAV-Zugriff, die sich für Immich eignen

Kostenübersicht

Variante 1: Minimales Setup (ab ~9,15 €/Monat)

KomponenteProduktKosten
VPSCX22 (2 vCPU, 4 GB RAM, 40 GB SSD)5,34 €/Monat
SpeicherStorage Box BX11 (1 TB)3,81 €/Monat
Gesamt~9,15 €/Monat

Dieses Setup reicht für Einsteiger mit einer kleineren Foto-Bibliothek (bis ca. 50.000 Fotos) völlig aus.

Variante 2: Mein Setup (~21,46 €/Monat für 5 TB)

KomponenteProduktKosten
VPSCX32 (4 vCPU, 8 GB RAM, 80 GB SSD)7,13 €/Monat
SpeicherStorage Box BX21 (5 TB)12,97 €/Monat
SSD Volume20 GB für Thumbnail-Cache1,36 €/Monat
Gesamt~21,46 €/Monat

Der größere VPS lohnt sich, da Immich gerade beim Machine Learning (Gesichtserkennung, CLIP-Suche) deutlich von mehr RAM profitiert. Das separate SSD-Volume für den Thumbnail-Cache sorgt für schnelle Ladezeiten in der App.

Storage-Architektur

Der Schlüssel zum kostengünstigen Betrieb ist die Trennung von schnellem und günstigem Speicher:

┌─────────────────────────────────────────────────────┐
│                  Hetzner Cloud VPS                   │
│                                                     │
│   ┌─────────────────────────────────────────────┐   │
│   │  Lokale SSD (im VPS enthalten)              │   │
│   │  └── PostgreSQL-Datenbank                   │   │
│   └─────────────────────────────────────────────┘   │
│                                                     │
│   ┌─────────────────────────────────────────────┐   │
│   │  SSD Volume (20 GB, optional)               │   │
│   │  └── /data/thumbs (Thumbnail-Cache)         │   │
│   └─────────────────────────────────────────────┘   │
│                                                     │
│   ┌─────────────────────────────────────────────┐   │
│   │  CIFS Mount (1 Docker Volume)               │   │
│   │  └── /data/upload     (Subpath)             │   │
│   │  └── /data/library    (Subpath)             │   │
│   │  └── /data/encoded-video (Subpath)          │   │
│   │  └── /data/backups    (Subpath)             │   │
│   │  └── /data/profile    (Subpath)             │   │
│   └──────────────────┬──────────────────────────┘   │
└──────────────────────┼──────────────────────────────┘


          ┌─────────────────────────┐
          │   Hetzner Storage Box    │
          │   (1 TB / 5 TB / ...)   │
          │   via Samba/CIFS         │
          └─────────────────────────┘

Design-Entscheidungen

Warum Thumbnails auf SSD? Thumbnails werden bei jedem Öffnen der App geladen. Liegen sie auf der Storage Box (Netzwerkspeicher), ist die Ladezeit spürbar langsamer. Ein kleines 20-GB-SSD-Volume für /data/thumbs sorgt für eine reaktionsschnelle Benutzeroberfläche.

Warum Medien auf der Storage Box? Originalfotos und -videos werden seltener direkt abgerufen. Die Storage Box kostet ca. 2,59 €/TB/Monat (bei BX21) und eignet sich für die Langzeitspeicherung großer Medienbibliotheken.

Warum die Datenbank auf der lokalen SSD? PostgreSQL benötigt schnelle I/O-Operationen. Ein Betrieb auf dem Netzwerkspeicher wäre extrem langsam und ist nicht empfehlenswert.

Schritt-für-Schritt-Anleitung

1. Hetzner Cloud Server erstellen

  1. Melde dich bei der Hetzner Console an
  2. Erstelle einen neuen Cloud Server: W - Image: Ubuntu 24.04
    • Typ: CX22 (minimal) oder CX32 (empfohlen)
  3. Optional: Erstelle ein Volume (20 GB) für den Thumbnail-Cache und hänge es an den Server

2. Storage Box bestellen

  1. In der Hetzner Console eine Storage Box bestellen (BX11 für 1 TB oder BX21 für 5 TB)
  2. Samba/CIFS aktivieren: In der Storage Box-Verwaltung unter “Einstellungen” das Samba-Protokoll aktivieren
  3. Zugangsdaten notieren (Benutzername, Passwort, Server-Adresse)

Wichtig: Server und Storage Box sollten im gleichen Rechenzentrum liegen, damit der interne Traffic kostenlos bleibt und die Latenz minimal ist.

docker-compose.yml

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    volumes:
      # Medien auf der Storage Box via CIFS
      - type: volume
        source: immich_smb
        target: /data/upload
        volume:
          subpath: upload
      - type: volume
        source: immich_smb
        target: /data/encoded-video
        volume:
          subpath: encoded-video
      - type: volume
        source: immich_smb
        target: /data/library
        volume:
          subpath: library
      - type: volume
        source: immich_smb
        target: /data/backups
        volume:
          subpath: backups
      - type: volume
        source: immich_smb
        target: /data/profile
        volume:
          subpath: profile
      # Thumbnails auf schneller SSD
      - /mnt/volume-hel1-1/immich/thumbs:/data/thumbs
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - stack.env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik
      - traefik.http.routers.immich.rule=Host(`immich.example.com`)
      - traefik.http.routers.immich.entrypoints=websecure
      - traefik.http.routers.immich.tls.certresolver=myresolver
      - traefik.http.services.immich.loadbalancer.server.port=2283
    networks:
      - immich
      - traefik

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    volumes:
      - model-cache:/cache
    env_file:
      - stack.env
    restart: always
    healthcheck:
      disable: false
    networks:
      - immich

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:9
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always
    networks:
      - immich

  database:
    container_name: immich_postgres
    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}
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    shm_size: 128mb
    restart: always
    healthcheck:
      disable: false
    networks:
      - immich

volumes:
  immich_smb:
    driver: local
    driver_opts:
      type: cifs
      o: username=${SMB_USERNAME},password=${SMB_PASSWORD},vers=3.0,addr=${SMB_SERVER}
      device: //${SMB_SERVER}/${SMB_SHARE}
  model-cache:

networks:
  immich:
    internal: false
  traefik:
    external: true

So funktioniert die Storage-Box-Einbindung

Der entscheidende Teil ist das Docker Volume immich_smb. Es nutzt den local-Treiber mit CIFS-Optionen, um die Hetzner Storage Box als Netzlaufwerk einzubinden:

volumes:
  immich_smb:
    driver: local
    driver_opts:
      type: cifs
      o: username=${SMB_USERNAME},password=${SMB_PASSWORD},vers=3.0,addr=${SMB_SERVER}
      device: //${SMB_SERVER}/${SMB_SHARE}

Über subpath im Service werden die einzelnen Immich-Verzeichnisse (upload, library, encoded-video, backups, profile) als Unterordner auf der Storage Box abgebildet:

volumes:
  - type: volume
    source: immich_smb
    target: /data/upload
    volume:
      subpath: upload

Damit werden alle Medien automatisch auf der Storage Box gespeichert, während der Container selbst nur wenig lokalen Speicher benötigt.

Wichtig: Die Hetzner Storage Box erlaubt maximal 10 gleichzeitige Verbindungen. Deshalb wird hier bewusst nur ein einziges Docker Volume (immich_smb) per CIFS gemountet und die verschiedenen Verzeichnisse über subpath abgebildet. Würde man für jedes Verzeichnis ein eigenes CIFS-Volume anlegen, wären die Verbindungen schnell aufgebraucht.

5. Umgebungsvariablen konfigurieren

Erstelle die Datei stack.env:

# Immich Version (leer = latest release)
IMMICH_VERSION=release

# Datenbank
DB_PASSWORD=<sicheres-passwort-generieren>
DB_USERNAME=immich
DB_DATABASE_NAME=immich
DB_DATA_LOCATION=/opt/immich/postgres

# Storage Box Samba-Zugangsdaten
SMB_USERNAME=<dein-storagebox-user>
SMB_PASSWORD=<dein-storagebox-passwort>
SMB_SERVER=<deine-storagebox>.your-storagebox.de
SMB_SHARE=backup

Performance-Tipps

Thumbnail-Cache auf SSD

Der Thumbnail-Cache ist der wichtigste Performance-Faktor. In der docker-compose.yml wird er direkt auf das SSD-Volume gemountet:

- /mnt/volume-hel1-1/immich/thumbs:/data/thumbs

Das Hetzner Volume (SSD) hat niedrigere Latenz als die Storage Box über das Netzwerk. Das Volume kann im laufenden Betrieb über die Hetzner Cloud-Oberfläche vergrößert werden – ein Herunterfahren des Servers ist dafür nicht nötig.

Hilfreiche Debug-Befehle

Um zu prüfen, ob die gemounteten Verzeichnisse korrekt eingebunden sind, kann man direkt in den Container schauen:

# Inhalt des Library-Verzeichnisses anzeigen
docker exec immich_server ls "/data/library/"

# Upload-Verzeichnis prüfen
docker exec immich_server ls "/data/upload/"

# Thumbnail-Verzeichnis prüfen
docker exec immich_server ls "/data/thumbs/"

# Speicherplatz der gemounteten Volumes anzeigen
docker exec immich_server df -h /data/

Migration großer Foto-Sammlungen via Synology NAS

Wer große Datenmengen an Bildern migrieren möchte, kann diese über ein Synology NAS per Cloud Sync via WebDAV auf die Hetzner Storage Box synchronisieren. Da die Daten dann bereits auf der Storage Box liegen, kann Immich sie direkt über die External Library-Funktion einlesen – das spart den langsamen Upload über das Internet.

Import mit immich-go

immich-go ist eine Alternative zur offiziellen immich-CLI, die keine Node.js-Installation voraussetzt. Das Tool eignet sich besonders für den Import von Google-Photos-Takeout-Archiven und versucht dabei, Metadaten wie Alben und Zeitstempel korrekt zu übernehmen.

JPEG-Komprimierung mit jpegli

Um Speicherplatz zu sparen, lassen sich vorhandene JPEG-Bilder mit jpegli-windows-explorer-extension unter nahezu gleichbleibender Qualität verkleinern. Langfristig wäre JPEG XL das bessere Format, aber bis zur breiten Unterstützung in Browsern und Apps ist jpegli eine pragmatische Lösung.

Sicherheit: Immich mit Authelia absichern

Da Immich standardmäßig über das Internet erreichbar ist, empfehle ich zusätzlich Authelia als Authentifizierungs-Layer davor zu schalten. In Kombination mit Traefik als Reverse Proxy lässt sich das recht einfach umsetzen: Traefik leitet Anfragen an Authelia weiter, das eine zusätzliche Anmeldung (z. B. mit Zwei-Faktor-Authentifizierung) erzwingt, bevor der Zugriff auf Immich freigegeben wird. So erhält man eine zusätzliche Sicherheitsschicht vor der eigentlichen Immich-Authentifizierung.

Fazit

Mit Hetzner lässt sich Immich zu folgenden Kosten selbst betreiben:

SetupSpeicherMonatliche Kosten
Minimal1 TB~9,15 €
Empfohlen5 TB~21,46 €

Zum Vergleich: ente.io – eine empfehlenswerte, Ende-zu-Ende-verschlüsselte Foto-App – kostet 10 €/Monat für 1 TB bzw. 20 €/Monat für 2 TB. Immich bietet zwar keine E2E-Verschlüsselung, hat dafür aber andere Eigenschaften. Ich nutze ente.io weiterhin in einer kleinen Variante für den direkten, sicheren Geräte-Sync von Medien.

Im Vergleich zu kommerziellen Cloud-Fotodiensten erhältst du mit Immich + Hetzner für dieses Geld:

  • Volle Kontrolle über deine Daten (DSGVO-konform in Deutschland gehostet)
  • Keine Vendor-Lock-in – deine Fotos bleiben in Originalqualität erhalten
  • KI-Features wie Gesichtserkennung und semantische Suche
  • Unbegrenzte Nutzer – die ganze Familie kann Immich nutzen
  • Automatische Snapshots als integrierte Backup-Lösung

Der Trick liegt in der Trennung von Compute (günstiger VPS) und Storage (günstige Storage Box). Thumbnails und Datenbank laufen auf schneller SSD, während die großen Mediendateien auf dem kosteneffizienten Netzwerkspeicher liegen. So lässt sich schneller Zugriff mit günstigem Speicherplatz kombinieren.

Immich unterstützen

Bitte überlegt euch, Immich zu unterstützen: buy.immich.app. Als Softwareentwickler weiß ich, was es bedeutet, ein Projekt in diesem Umfang zu entwickeln und zu pflegen. Die Entwickler verdienen für ihren Einsatz auf jeden Fall eure Unterstützung.