<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Immich – Serverküche</title><link>https://serverkueche.de/tags/immich/</link><description>Immich – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>de-DE</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Mon, 20 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/tags/immich/index.xml" rel="self" type="application/rss+xml"/><item><title>Immich selbst hosten: dein privates Foto-Backup hinter Traefik</title><link>https://serverkueche.de/tutorials/immich-fotos-selbst-hosten/</link><pubDate>Mon, 20 Jul 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/tutorials/immich-fotos-selbst-hosten/</guid><description>Immich mit Docker hinter Traefik aufsetzen: die selbst gehostete Alternative zu Google Fotos – mit automatischem Handy-Backup, Gesichtserkennung und HTTPS.</description><content:encoded><![CDATA[<p>Tausende Fotos und Videos vom Handy – und alle liegen bei Google oder Apple.
<strong>Immich</strong> 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.</p>
<h2 id="was-bauen-wir">Was bauen wir?</h2>
<p>Am Ende läuft <strong>Immich v3</strong> hinter deinem Traefik-Proxy, erreichbar unter
<code>https://photos.DEINE_DOMAIN</code> mit gültigem HTTPS. Die offizielle <strong>Immich-Handy-App</strong>
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&quot;, „Hund&quot;) und lässt Immich Gesichter gruppieren.</p>
<p>Immich besteht aus <strong>vier Containern</strong>: 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.</p>
<p>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 <strong>Backups</strong>: 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.</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Immich ist schnelllebig – Version pinnen
  </p>
  <div class="prose-kitchen text-sm">Immich entwickelt sich rasant. Datenbank-Migrationen laufen beim Update automatisch und
sind <strong>nicht rückwärtskompatibel</strong> – ein Downgrade ist danach nicht mehr sauber möglich.
Pinne deshalb <strong>immer eine feste Version</strong> (hier <code>v3.0.3</code>) statt <code>release</code> oder <code>latest</code>,
und mache <strong>vor jedem Update ein Backup</strong>. So bestimmst du, wann aktualisiert wird.</div>
</div>
<h2 id="voraussetzungen">Voraussetzungen</h2>
<ul>
<li>Ein laufender <strong>Traefik-Reverse-Proxy</strong> mit dem <code>proxy</code>-Netzwerk und dem
Let&rsquo;s-Encrypt-Resolver <code>le</code> – siehe
<a href="/tutorials/reverse-proxy-traefik/">Reverse Proxy mit Traefik</a>.</li>
<li>Eine Subdomain <code>photos.DEINE_DOMAIN</code> mit DNS-Record auf deine Server-IP – siehe
<a href="/tutorials/domain-mit-server-verbinden/">Domain mit Server verbinden</a>.</li>
<li>Ein <strong>Backup</strong>. Deine Fotosammlung ist unersetzlich – richte zuerst
<a href="/tutorials/backups-mit-restic/">Backups mit Restic</a> ein.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Wie groß muss der Server sein?
  </p>
  <div class="prose-kitchen text-sm">Immich ist der ressourcenhungrigste Dienst der Serverküche. Offiziell werden
<strong>mindestens 6 GB RAM (empfohlen 8)</strong> verlangt – vor allem der Machine-Learning-Dienst
für Gesichtserkennung und Suche braucht Speicher. Der getestete <strong>VPS 1000 mit 8 GB RAM</strong>
erfüllt das gerade, hat aber wenig Reserve. Für eine große Bibliothek oder mehrere Nutzer
ist ein Server mit <strong>16 GB RAM</strong> (z. B. VPS 2000) entspannter. Auf einem 4-GB-Server
läuft Immich nur mit <strong>abgeschaltetem ML</strong> (siehe „Wenn es nicht funktioniert&quot;).
Und: Fotos brauchen Platz – plane genügend Festplatte ein.</div>
</div>
<p>Wie viel RAM deine Foto-Bibliothek samt KI-Suche wirklich braucht, rechnet dir der
<a href="/serverempfehlung/">Server-Rechner</a> aus.</p>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Empfehlung</span>
    <span title="Mit * markierte Links sind Affiliate-Links.">Anzeige</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 2000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">8 vCore · 16 GB RAM · 512 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">ab 19,24 €/Monat</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">Für eine große Foto-Bibliothek mit Gesichtserkennung sind 16 GB RAM angenehm.</p>
    </div>
    <a href="https://www.netcup.com/de/server/vps/vps-2000-g12-12m?ref=44083" rel="sponsored noopener" target="_blank"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Zu netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € Gutschein</strong> für netcup-Neukunden:</span>
  <code class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(nur Neukunden, keine Domains)</span>
</p></div>
</div>

<h2 id="schritt-für-schritt">Schritt für Schritt</h2>
<h3 id="schritt-1-dns-record-anlegen">Schritt 1: DNS-Record anlegen</h3>
<p>Lege einen Eintrag <code>photos.DEINE_DOMAIN</code> an, der auf deine Server-IP zeigt, und prüfe ihn:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short photos.DEINE_DOMAIN</span></span></code></pre></div>
</div>
<p>Es muss deine Server-IP zurückkommen – sonst holt Traefik später kein Zertifikat.</p>
<h3 id="schritt-2-ordner-und-env-vorbereiten">Schritt 2: Ordner und .env vorbereiten</h3>
<p>Immich wird über eine <code>.env</code>-Datei konfiguriert. Leg das Projekt an:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/immich <span class="o">&amp;&amp;</span> <span class="nb">cd</span> ~/immich</span></span></code></pre></div>
</div>
<p>Erstelle eine <code>.env</code> mit den Kernwerten (ein starkes DB-Passwort einsetzen – <strong>nur
Buchstaben und Ziffern</strong>, keine Sonderzeichen, das mag Immichs DB-Init nicht):</p>
<div class="sk-code">
  <span class="sk-code-head">INI</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="na">UPLOAD_LOCATION</span><span class="o">=</span><span class="s">./library</span>
</span></span><span class="line"><span class="cl"><span class="na">DB_DATA_LOCATION</span><span class="o">=</span><span class="s">./postgres</span>
</span></span><span class="line"><span class="cl"><span class="na">DB_PASSWORD</span><span class="o">=</span><span class="s">DEIN_DB_PASSWORT</span>
</span></span><span class="line"><span class="cl"><span class="na">DB_USERNAME</span><span class="o">=</span><span class="s">postgres</span>
</span></span><span class="line"><span class="cl"><span class="na">DB_DATABASE_NAME</span><span class="o">=</span><span class="s">immich</span>
</span></span><span class="line"><span class="cl"><span class="na">IMMICH_VERSION</span><span class="o">=</span><span class="s">v3.0.3</span></span></span></code></pre></div>
</div>
<ul>
<li><strong><code>UPLOAD_LOCATION</code></strong> – hier landen deine <strong>Fotos und Videos</strong>. Das ist das
wichtigste Verzeichnis fürs Backup.</li>
<li><strong><code>DB_DATA_LOCATION</code></strong> – die PostgreSQL-Daten. Muss auf einer <strong>lokalen Platte</strong> liegen
(kein Netzlaufwerk/NFS – die DB nimmt das übel).</li>
<li><strong><code>IMMICH_VERSION</code></strong> – die gepinnte Version.</li>
</ul>
<h3 id="schritt-3-die-composeyaml-anlegen">Schritt 3: Die compose.yaml anlegen</h3>
<p>Wir übernehmen die offizielle Immich-Vorlage und ergänzen nur die Traefik-Labels am
<code>immich-server</code>. Erstelle <code>compose.yaml</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">immich</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">immich-server</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/immich-app/immich-server:${IMMICH_VERSION}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">${UPLOAD_LOCATION}:/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/etc/localtime:/etc/localtime:ro</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">env_file</span><span class="p">:</span><span class="w"> </span><span class="l">.env</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">DB_HOSTNAME</span><span class="p">:</span><span class="w"> </span><span class="l">database</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">REDIS_HOSTNAME</span><span class="p">:</span><span class="w"> </span><span class="l">redis</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">depends_on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">redis</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">condition</span><span class="p">:</span><span class="w"> </span><span class="l">service_started</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">database</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">condition</span><span class="p">:</span><span class="w"> </span><span class="l">service_healthy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.enable=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.immich.rule=Host(`photos.DEINE_DOMAIN`)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.immich.entrypoints=websecure&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.immich.tls.certresolver=le&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.immich.loadbalancer.server.port=2283&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">default, proxy]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">immich-machine-learning</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">model-cache:/cache</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">default]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">redis</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">docker.io/valkey/valkey:9</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">default]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">database</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">POSTGRES_PASSWORD</span><span class="p">:</span><span class="w"> </span><span class="l">${DB_PASSWORD}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">POSTGRES_USER</span><span class="p">:</span><span class="w"> </span><span class="l">${DB_USERNAME}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">POSTGRES_DB</span><span class="p">:</span><span class="w"> </span><span class="l">${DB_DATABASE_NAME}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">${DB_DATA_LOCATION}:/var/lib/postgresql/data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">healthcheck</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">test</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;CMD-SHELL&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;pg_isready -U ${DB_USERNAME} -d ${DB_DATABASE_NAME}&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">interval</span><span class="p">:</span><span class="w"> </span><span class="l">10s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">5s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">retries</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">default]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">model-cache</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">proxy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">external</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></div>
</div>
<p>Wichtig zu verstehen:</p>
<ul>
<li><strong>Nur <code>immich-server</code> hängt im <code>proxy</code>-Netz</strong> und trägt Traefik-Labels. Der ML-Dienst,
Valkey und die Datenbank bleiben ausschließlich im internen <code>default</code>-Netz – von außen
nicht erreichbar.</li>
<li><strong><code>loadbalancer.server.port=2283</code></strong> – Immich lauscht im Container auf Port 2283.</li>
<li>Die <strong>Datenbank</strong> ist bewusst das vorgebaute Immich-Postgres-Image mit der
Vektor-Erweiterung <em>VectorChord</em> (für die Bildsuche). Nimm nicht einfach ein
Standard-<code>postgres</code> – die Erweiterung fehlt dann.</li>
<li><strong>Valkey</strong> ist der Redis-Nachfolger; der Service heißt in der Immich-Vorlage aus
Kompatibilitätsgründen weiterhin <code>redis</code>.</li>
<li>Der <strong>Healthcheck</strong> an der Datenbank meldet, wann Postgres wirklich bereit ist. Über
<code>depends_on: … condition: service_healthy</code> startet <code>immich-server</code> erst dann – das
verhindert Migrationsfehler und den „Datenbank nicht erreichbar&quot;-Start beim ersten Hochfahren.</li>
</ul>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Änderungen an der .env übernehmen
  </p>
  <div class="prose-kitchen text-sm">Wenn du später etwas in der <code>.env</code> änderst, reicht ein <code>docker compose restart</code> <strong>nicht</strong> –
Docker liest die Umgebungsvariablen nur beim <strong>Neuerstellen</strong> der Container. Nutze dann
<code>docker compose up -d</code>; Compose erkennt die Änderung und baut die betroffenen Container neu.</div>
</div>
<h3 id="schritt-4-große-uploads-erlauben-traefik-timeout">Schritt 4: Große Uploads erlauben (Traefik-Timeout)</h3>
<p>Das ist <strong>der</strong> Stolperstein bei Immich hinter Traefik: Standardmäßig bricht Traefik
Verbindungen nach <strong>60 Sekunden</strong> ab (<code>readTimeout</code>). Beim Hochladen großer Videos vom
Handy führt das zu abgebrochenen Uploads (Fehler 502/499). Erhöhe den Timeout am
<code>websecure</code>-Entrypoint in deiner <strong>Traefik-Konfiguration</strong> (der <code>traefik</code>-Service aus dem
<a href="/tutorials/reverse-proxy-traefik/">Traefik-Tutorial</a>):</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">    </span><span class="nt">command</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># ... deine bestehenden Zeilen ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;--entrypoints.websecure.transport.respondingTimeouts.readTimeout=600s&#34;</span></span></span></code></pre></div>
</div>
<p>Starte Traefik danach neu (<code>docker compose up -d</code> im Traefik-Ordner). Anders als nginx hat
Traefik kein festes Größenlimit für Uploads – nur dieser Timeout muss hoch.</p>
<h3 id="schritt-5-starten-und-den-erst-setup-durchlaufen">Schritt 5: Starten und den Erst-Setup durchlaufen</h3>
<p>Zieh die Images (mehrere GB – das dauert) und starte:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d
</span></span><span class="line"><span class="cl">docker compose logs -f immich-server</span></span></code></pre></div>
</div>
<p>Die Images sind mehrere Gigabyte groß – der erste <code>pull</code> braucht je nach Anbindung ein
paar Minuten. Prüfe danach, dass alle vier Container laufen:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose ps</span></span></code></pre></div>
</div>
<p>Du solltest <code>immich-server</code>, <code>immich-machine-learning</code>, <code>redis</code> und <code>database</code> mit Status
<code>running</code> (die Datenbank <code>healthy</code>) sehen. Warte, bis im Log
<code>Immich Server is listening on http://[::1]:2283 [v3.0.3]</code> erscheint.
Ruf dann <code>https://photos.DEINE_DOMAIN</code> auf. Traefik holt beim ersten Zugriff das
Let&rsquo;s-Encrypt-Zertifikat (einen Moment Geduld). Beim allerersten Start begrüßt dich Immich mit
<strong>„Willkommen bei Immich&quot;</strong> und der Wahl, ob du <strong>neu startest</strong> oder eine Sicherung
wiederherstellst:</p>
<p>![Der Willkommensbildschirm von Immich mit den Optionen „Erste Schritte&quot; und „Von Datenbank wiederherstellen&quot;](immich-willkommen.png &ldquo;Erster Aufruf: „Erste Schritte&rdquo; wählen für eine frische Installation&quot;)</p>
<p>Klick auf <strong>Erste Schritte</strong> (Wiederherstellen brauchst du nur, wenn du ein Backup
einspielst). Danach legst du das <strong>Administrator-Konto</strong> an – als erster Nutzer wirst du
automatisch Admin:</p>
<p><figure class="my-6"><img src="/tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_9eb529b3092ecb0f.webp" srcset="/tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_b01ab1b78a362cf8.webp 480w, /tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_9eb529b3092ecb0f.webp 768w, /tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_e1ac72235e36411a.webp 1200w, /tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_6c10d20e7518a92e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/immich-fotos-selbst-hosten/immich-registrierung_hu_21707351f7f5a98d.webp"
    alt="Das Immich-Formular „Admin-Registrierung&quot; mit Feldern für E-Mail, Passwort und Name" title="Admin-Registrierung – der erste Nutzer wird automatisch Administrator"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Admin-Registrierung – der erste Nutzer wird automatisch Administrator</figcaption></figure></p>
<p>Nach dem ersten Login führt dich ein kurzer <strong>Einrichtungs-Assistent</strong> durch Theme,
Sprache und Datenschutz-Grundeinstellungen:</p>
<p><figure class="my-6"><img src="/tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_f414a63437dc818.webp" srcset="/tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_fa155ce76ab7d4ae.webp 480w, /tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_f414a63437dc818.webp 768w, /tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_e1c128859e8abc5.webp 1200w, /tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_b32c5bf3ebed1c7e.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/immich-fotos-selbst-hosten/immich-onboarding_hu_93e44cae02bd6aa4.webp"
    alt="Der Immich-Einrichtungsassistent begrüßt den neuen Administrator" title="Der Onboarding-Assistent nach dem ersten Login"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Der Onboarding-Assistent nach dem ersten Login</figcaption></figure></p>
<p>Danach landest du auf deiner (noch leeren) <strong>Zeitleiste</strong> – das Herzstück von Immich:</p>
<p><figure class="my-6"><img src="/tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_22e64ce51c6c0a00.webp" srcset="/tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_f6682d8a8fbc043f.webp 480w, /tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_22e64ce51c6c0a00.webp 768w, /tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_dd26bf995c060373.webp 1200w, /tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_6b803b47ac9db0b8.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/immich-fotos-selbst-hosten/immich-timeline_hu_bdb998e8763cf029.webp"
    alt="Die leere Foto-Zeitleiste von Immich mit der Aufforderung, das erste Foto hochzuladen" title="Die Foto-Zeitleiste – hier laufen später alle Bilder ein (Server online, v3.0.3)"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Die Foto-Zeitleiste – hier laufen später alle Bilder ein (Server online, v3.0.3)</figcaption></figure></p>
<h3 id="schritt-6-die-handy-app-verbinden">Schritt 6: Die Handy-App verbinden</h3>
<p>Der eigentliche Nutzen kommt von der App. Installiere <strong>Immich</strong> aus dem App Store bzw.
Play Store (oder F-Droid). Beim Start fragt sie nach der <strong>Server-Adresse</strong> – trag
<code>https://photos.DEINE_DOMAIN</code> ein und melde dich mit deinem Konto an. Aktiviere dann in den
App-Einstellungen die <strong>Sicherung</strong> und wähle die Alben, die hochgeladen werden sollen.</p>
<p>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.</p>
<p>Nach dem Upload arbeitet Immich im Hintergrund weiter: Es erzeugt Vorschaubilder, liest
die Aufnahme-Metadaten (Datum, Ort) aus und lässt den ML-Dienst <strong>Gesichter erkennen</strong> und
die Bilder für die <strong>intelligente Suche</strong> 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 <strong>Administration → Auftragswarteschlangen</strong>. In der
Seitenleiste findest du dann die typischen Foto-Funktionen: <strong>Erkunden</strong> (nach Personen und
Orten), die <strong>Karte</strong> mit Geo-Verortung, <strong>Alben</strong> zum Teilen und die <strong>Rückblicke</strong>
(„Vor einem Jahr&quot;).</p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-sky-300 bg-sky-50 dark:border-sky-800 dark:bg-sky-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">ℹ️</span>Videos &amp; Transcoding auf dem VPS
  </p>
  <div class="prose-kitchen text-sm">Immich wandelt Videos für die Wiedergabe im Browser um (Transcoding). Auf einem normalen
VPS <strong>ohne Grafikkarte</strong> 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.</div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-herb-400 bg-herb-50 dark:border-herb-700 dark:bg-herb-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">🧑‍🍳</span>Weitere Nutzer
  </p>
  <div class="prose-kitchen text-sm">Für die Familie legst du unter <strong>Administration → Benutzer</strong> 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.</div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Deine Fotos hängen im Internet
  </p>
  <div class="prose-kitchen text-sm">Sobald Immich über <code>photos.DEINE_DOMAIN</code> erreichbar ist, steht die Anmeldeseite offen im
Netz. Vergib deshalb ein <strong>langes, einmaliges Passwort</strong> für das Admin- und alle
Nutzerkonten und aktiviere die <strong>Zwei-Faktor-Authentifizierung</strong> 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.</div>
</div>
<h2 id="wenn-es-nicht-funktioniert">Wenn es nicht funktioniert</h2>
<p><strong>Symptom:</strong> Uploads großer Videos brechen nach etwa einer Minute ab (Fehler 502 oder 499).</p>
<p><strong>Ursache &amp; Lösung:</strong> Traefiks <code>readTimeout</code> (Standard 60 s) greift. Setz ihn wie in
Schritt 4 auf <code>600s</code> (oder höher) und starte Traefik neu. Das ist mit Abstand der
häufigste Immich-hinter-Proxy-Fehler.</p>
<p><strong>Symptom:</strong> Der <code>immich-machine-learning</code>-Container stürzt ab bzw. beendet sich mit
„exit 137&quot;, Suche und Gesichtserkennung funktionieren nicht.</p>
<p><strong>Ursache &amp; Lösung:</strong> Zu wenig RAM – der Container wurde vom System beendet (Out of
Memory). Gib dem Server mehr Speicher, oder <strong>deaktiviere ML</strong>, indem du den Service
<code>immich-machine-learning</code> aus der <code>compose.yaml</code> entfernst. Immich läuft dann ohne
Gesichtserkennung und intelligente Suche, aber Upload und Zeitleiste funktionieren normal.</p>
<p><strong>Symptom:</strong> Nach einem Update starten die Container nicht mehr oder melden
Migrationsfehler.</p>
<p><strong>Ursache &amp; Lösung:</strong> Server, Machine-Learning und Datenbank müssen auf <strong>derselben</strong>
Version laufen. Setz in der <code>.env</code> die neue <code>IMMICH_VERSION</code> und aktualisiere <strong>alle</strong>
Container gemeinsam (<code>docker compose pull &amp;&amp; docker compose up -d</code>). Ein Downgrade nach
einer Migration ist nicht möglich – nur ein Rücksetzen aus dem Backup.</p>
<p><strong>Symptom:</strong> Immich zeigt „Wartungsmodus&quot; / „Vorübergehend nicht verfügbar&quot;.</p>
<p><strong>Ursache &amp; Lösung:</strong> Immich v3 startet bei bestimmten Datenbank-Zuständen in einen
Wartungsmodus. Im Log (<code>docker compose logs immich-server</code>) steht dann eine URL mit einem
<strong>einmaligen Token</strong> (<code>…/maintenance?token=…</code>) – darüber meldest du dich am Wartungsmodus
an und wählst „neu starten&quot; bzw. beendest ihn. Danach ist die normale Oberfläche wieder da.</p>
<p><strong>Symptom:</strong> Container startet nicht, „permission denied&quot; beim Datenbank- oder
Upload-Verzeichnis.</p>
<p><strong>Ursache &amp; Lösung:</strong> <code>UPLOAD_LOCATION</code> oder <code>DB_DATA_LOCATION</code> haben die falschen
Zugriffsrechte oder liegen auf einem Netzlaufwerk. Lege beide auf einer lokalen Platte an
und stelle sicher, dass Docker hineinschreiben darf.</p>
<h2 id="wartung--backups">Wartung &amp; Backups</h2>
<ul>
<li>
<p><strong>Zwei Dinge gehören ins Backup – konsistent zusammen.</strong> Deine <strong>Fotos</strong>
(<code>UPLOAD_LOCATION</code>, also <code>~/immich/library</code>) und die <strong>Datenbank</strong>. 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:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose stop immich-server
</span></span><span class="line"><span class="cl">docker compose <span class="nb">exec</span> -T database pg_dump --clean --if-exists <span class="se">\
</span></span></span><span class="line"><span class="cl">  --dbname<span class="o">=</span>immich --username<span class="o">=</span>postgres <span class="p">|</span> gzip &gt; immich-db.sql.gz
</span></span><span class="line"><span class="cl">docker compose start immich-server</span></span></code></pre></div>
</div>
<p>Sichere den Dump zusammen mit dem <code>library</code>-Ordner <strong>verschlüsselt und off-site</strong> mit
<a href="/tutorials/backups-mit-restic/">Restic</a>. Alternativ kann Immich unter
<strong>Administration → Auftragswarteschlangen</strong> automatische DB-Dumps erzeugen – die Fotos
musst du trotzdem separat sichern.</p>
</li>
<li>
<p><strong>Den Ernstfall einmal proben.</strong> 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 <code>library</code>-Ordner an dieselbe Stelle – Immich bietet
dafür beim ersten Start den Punkt <strong>„Von Datenbank wiederherstellen&quot;</strong> an (der zweite
Knopf aus Schritt 5). Wichtig ist die <strong>gleiche Version</strong>: Datenbank-Stand und Programm
müssen zusammenpassen.</p>
</li>
<li>
<p><strong>Backup vor jedem Update.</strong> Weil Migrationen nicht umkehrbar sind, ist das Backup dein
einziger Rückweg. Erst sichern, dann <code>IMMICH_VERSION</code> erhöhen, dann
<code>docker compose pull &amp;&amp; docker compose up -d</code>.</p>
</li>
<li>
<p><strong>Ehrlich zum Aufwand:</strong> 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.</p>
</li>
<li>
<p><strong>Speicherplatz im Blick behalten.</strong> Fotos und Videos wachsen stetig; Immich legt
zusätzlich Vorschaubilder und umgewandelte Videos an. Überwache die Plattenbelegung
(z. B. mit <a href="/tutorials/uptime-kuma-monitoring/">Uptime Kuma</a>), damit dir der Server nicht
volläuft.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>