Kurz gesagt. Immich läuft als Stack aus vier Containern: Server, PostgreSQL, Redis und Machine Learning. Offizielles Minimum sind 6 GB RAM, empfohlen 8 GB. Diese Anleitung nutzt einen Cloud VPS 8 von Contabo mit Ubuntu 22.04 LTS, Docker Compose und Caddy als Reverse Proxy mit automatischem Let’s Encrypt-Zertifikat. Immich lauscht intern auf Port 2283, nach außen sind nur 80 und 443 offen.
Diese Anleitung führt dich durch den kompletten Aufbau von Immich, einer quelloffenen Alternative zu Google Photos, auf einem Cloud VPS 8 von Contabo mit Docker Compose. Sie deckt die Bereitstellung des VPS ab, die Docker-Installation, den Immich-Compose-Stack, einen Caddy-Reverse-Proxy mit automatischem SSL, die Migration auf v3 und die Konfiguration der Mobile-App.
Voraussetzungen
Ein Docker-Deployment von Immich stützt sich auf einen kleinen Stack von Containern, die zusammenarbeiten: den Hauptserver, PostgreSQL, Redis und einen Machine-Learning-Container. Der VPS braucht genug Luft, um alle davon ohne Konkurrenz um Ressourcen zu betreiben.
- VPS: Cloud VPS 8 von Contabo (8 vCores, 24 GB RAM, 300 GB SSD) oder ein vergleichbarer Tarif mit mindestens 6 GB RAM. Damit laufen alle Container bequem, mit Reserve für eine wachsende Fotobibliothek.
- Betriebssystem: Ubuntu 22.04 LTS oder neuer
- Docker Engine und das Docker-Compose-Plugin
- Eine registrierte Domain, die per A-Record auf den VPS zeigt
- Ein Reverse Proxy für die HTTPS-Terminierung. In dieser Anleitung kommt durchgehend Caddy zum Einsatz, weil es Zertifikate selbst verwaltet
Schritt 1: VPS bereitstellen und absichern
Bevor du den ersten Container anfasst, gehören ein paar Standard-Härtungsschritte auf den Server. Diese Phase zu überspringen ist einer der häufigeren Gründe, warum selbstgehostete Dienste am Ende kompromittiert werden, denn ein frisch bereitgestellter VPS ist ab dem Moment des Bootens aus dem öffentlichen Internet erreichbar.
- Bestelle einen Cloud VPS 8 und wähle bei der Bereitstellung Ubuntu 22.04 LTS als Basis-Image. Der Server ist typischerweise innerhalb weniger Minuten bereitgestellt, die Root-Zugangsdaten kommen anschließend per Mail.
- Erzeuge lokal ein SSH-Schlüsselpaar mit
ssh-keygenund lade den öffentlichen Schlüssel beim Setup auf den VPS, oder trage ihn danach im Contabo-Control-Panel nach. Sobald der Login per Schlüssel bestätigt funktioniert, deaktiviere die Passwort-Authentifizierung in/etc/ssh/sshd_configmit PasswordAuthentication no und starte den SSH-Dienst neu. - Konfiguriere UFW so, dass nur die benötigten Ports offen sind: SSH (22), HTTP (80) und HTTPS (443). Führe
sudo ufw allow OpenSSH, sudo ufw allow httpundsudo ufw allow httpsaus, dann aktiviere die Firewall mitsudo ufw enable. Port 2283, auf dem Immich lauscht, bleibt zum öffentlichen Internet geschlossen, denn der gesamte externe Verkehr läuft über den Reverse Proxy. - Lege mit
adduserundusermod -aG sudoeinen Nutzer ohne Root-Rechte an und wechsle für den Rest des Setups auf dieses Konto. Docker als root zu betreiben vergrößert den Schaden, falls ein Container einmal kompromittiert wird.
Schritt 2: Docker und Docker Compose installieren
Installiere Docker Engine und das Compose-Plugin direkt aus dem offiziellen Repository von Docker und nicht aus den älteren Paketen, die Ubuntu mitbringt, denn die hängen meist mehrere Versionen zurück:
sudo apt update && sudo apt upgrade -y
sudo apt install ca-certificates curl gnupg -y
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo usermod -aG docker $USERMelde dich danach ab und wieder an, damit die neue Gruppenmitgliedschaft greift. Prüfe die Installation mit docker --version und docker compose version, beide sollten aktuelle stabile Versionsnummern melden.
Schritt 3: Immich mit Docker Compose deployen
Steht Docker, folgt die Immich-Installation der offiziellen Compose-Konfiguration. Erstelle ein Verzeichnis für das Deployment und hole dir die benötigten Dateien aus dem aktuellen GitHub-Release:
mkdir ~/immich-app && cd ~/immich-app
curl -o docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
curl -o .env https://github.com/immich-app/immich/releases/latest/download/example.envÖffne die Datei .env und setze die folgenden Werte, bevor du den Stack startest:
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
DB_PASSWORD=a-strong-generated-password
IMMICH_VERSION=release
TZ=Etc/UTCLass DB_PASSWORD generieren statt es von Hand zu tippen und bleibe bei alphanumerischen Zeichen, damit Docker Sonderzeichen in der Environment-Datei nicht falsch interpretiert. Sobald die Werte stehen, startest du den Stack:
docker compose up -dFühre docker compose ps aus, um zu prüfen, ob jeder Container einen gesunden Zustand erreicht. Beim ersten Start dauert das typischerweise ein bis zwei Minuten, während die Datenbank ihr Schema anlegt. Immich ist danach unter http://server-ip:2283 erreichbar, braucht für den täglichen Einsatz aber noch Domain und SSL-Zertifikat.
Schritt 4: Reverse Proxy mit SSL einrichten (Caddy)
Caddy holt und erneuert Let’s Encrypt-Zertifikate automatisch und nimmt dir damit eine Wartungsaufgabe ab, die andere Proxies von Hand über Certbot abwickeln. Installiere Caddy aus dem offiziellen APT-Repository und bearbeite dann /etc/caddy/Caddyfile:
photos.example.com {
reverse_proxy localhost:2283 {
header_up X-Forwarded-Proto {scheme}
}
}Ersetze photos.example.com durch die Domain, die per DNS-A-Record auf den VPS zeigt, und lade Caddy neu, damit die Änderung greift:
sudo systemctl reload caddyCaddy fragt das Zertifikat für die Domain bei der ersten eingehenden Anfrage automatisch an. Der gesamte Verkehr auf Port 2283 läuft über HTTPS auf Port 443, und weil UFW von außen nur die Ports 80 und 443 zulässt, bleibt der eigentliche Immich-Port direkt nicht erreichbar.
Schritt 5: Von Immich v2 auf v3 migrieren
Das Release v3 bündelt Breaking Changes an API und Datenbankschema. Migrationen sind nicht darauf ausgelegt, sich nach dem Durchlauf sauber zurückrollen zu lassen. Lies deshalb immer die offiziellen Release Notes zu v3, bevor du anfängst, besonders bei Deployments mit Integrationen von Dritten.
- Sichere die PostgreSQL-Datenbank und das Upload-Verzeichnis, bevor du irgendetwas anfasst. Schema-Migrationen der Datenbank lassen sich nach dem Durchlauf nicht sauber zurücknehmen. Nutze
docker exec -t immich_postgres pg_dumpall -c -U postgres > immich_db_backup.sqlund archiviere das Verzeichnis ausUPLOAD_LOCATIONseparat. - Bearbeite
.envund setzeIMMICH_VERSION=v3, oder pinne auf einen konkreten Tag wiev3.0.0.Es lohnt sich, die übrigen Einträge in.envgegen ihre Kommentare zu lesen, denn manchen Deployments hilft es, Pfade auf ein eigenes Daten-Volume zu verlegen. - Hole die aktualisierten Images und starte den Stack neu mit
docker compose pull && docker compose up -d. Damit lädt Docker die aktualisierten Images für Server, Datenbank und Machine Learning herunter, bevor die Container neu erstellt werden. - Beobachte die Logs mit
docker compose logs -f immich-server, bis die Health Checks durchlaufen, und prüfe dann, ob die Weboberfläche lädt und bestehende Alben und Assets sichtbar sind. Kontrolliere alle Tools von Dritten, Backup-Skripte und Integrationen, die die Immich-API direkt aufrufen, gegen die aktuelle v3-API-Dokumentation auf Breaking Changes.
Schritt 6: Mobile-App und Backup konfigurieren
Sobald der Server über HTTPS erreichbar ist, verbindet sich die Immich-App für iOS oder Android damit, indem du die Server-URL im Login-Screen eingibst, zum Beispiel https://photos.example.com. Nach der Anmeldung mit dem Admin-Konto, das du beim ersten Setup angelegt hast, aktivierst du in den App-Einstellungen das Backup im Hintergrund. Neue Fotos und Videos werden dann automatisch hochgeladen, ohne dass du die App öffnen musst.
Auf beiden Plattformen hängt das Hintergrund-Backup davon ab, dass das Betriebssystem den App-Prozess im Leerlauf nicht aggressiv beendet. Schau dir die Einstellungen zur Akku-Optimierung für die Immich-App an und nimm sie von jeder automatischen App-Ruhezustandsfunktion aus, die der Hersteller deines Telefons mitbringt. Hersteller wie Samsung und Xiaomi legen zusätzliche Akku-Beschränkungen über das Standard-Android und können Uploads im Hintergrund in den Standardeinstellungen still stoppen. In der Regel löst es sich, wenn du für die App unbeschränkte Akkunutzung erlaubst und Hintergrunddaten sowohl über WLAN als auch über Mobilfunk zulässt, falls du auch unterwegs synchronisieren willst.
FAQ: Immich installieren
Setze IMMICH_VERSION=v3 (oder einen konkreten Tag wie v3.0.0) in der Datei .env und führe dann docker compose pull und anschließend docker compose up -d aus. Sichere davor Datenbank und Upload-Verzeichnis und prüfe die offiziellen Release Notes zu v3 auf Breaking Changes, von denen Integrationen von Dritten abhängen könnten.
Das offizielle Minimum sind 6 GB RAM, empfohlen werden 8 GB für ein flüssigeres Erlebnis. Damit ist der gemeinsame Footprint von Immich-Server, PostgreSQL, Redis und dem Machine-Learning-Container im laufenden Betrieb abgedeckt.
Immich läuft mit 4 GB RAM, wenn du den Machine-Learning-Container deaktivierst und dazu IMMICH_MACHINE_LEARNING_ENABLED=false in der Datei .env setzt. Damit entfallen Gesichtserkennung und semantische Suche, Upload und Durchsuchen der Bibliothek bleiben aber vollständig nutzbar.
Die PostgreSQL-Datenbank von Immich lässt sich sicher über docker exec mit pg_dumpall sichern:docker exec -t immich_postgres pg_dumpall -c -U postgres > immich_db_backup.sql
Alternativ stoppst du den Stack komplett mit docker compose down, bevor du das Verzeichnis aus DB_DATA_LOCATION direkt kopierst, damit die Datenbank nicht beschädigt wird. Beide Wege sollten regelmäßig nach Plan laufen, zusammen mit einem separaten Backup des Verzeichnisses aus UPLOAD_LOCATION, denn Datenbank und Mediendateien müssen sich gemeinsam wiederherstellen lassen, damit ein Backup etwas wert ist.