Zum Hauptinhalt springen

Architektur

Immich verwendet ein traditionelles Client-Server-Design mit einer dedizierten Datenbank zur Datenpersistenz. Die Frontend-Clients kommunizieren über HTTP mit Backend-Diensten unter Verwendung von REST-APIs. Unten sehen Sie ein Diagramm der Architektur auf hoher Ebene.

Diagramm auf hoher Ebene

Immich-Architektur

Das Diagramm zeigt, wie Clients über REST mit der API des Servers kommunizieren. Der Server kommuniziert über Repositories mit nachgelagerten Systemen (z. B. Redis, Postgres, maschinelles Lernen, Dateisystem). Nicht im Diagramm dargestellt ist, dass der Server in zwei separate Container aufgeteilt ist: immich-server und immich-microservices. Der Microservices-Container bearbeitet keine API-Anfragen oder plant Cron-Jobs, sondern verarbeitet hauptsächlich eingehende Job-Anfragen von Redis.

Clients

Immich hat drei Hauptclients:

  1. Mobile App - Android, iOS
  2. Web-App - Responsive Website
  3. CLI - Befehlszeilenprogramm für Massen-Uploads
Info

Alle drei Clients verwenden OpenAPI, um REST-Clients für eine einfache Integration automatisch zu generieren. Weitere Informationen zu diesem Prozess finden Sie unter OpenAPI.

Mobile App

Die Mobile App ist in Dart mit Flutter geschrieben. Unten sehen Sie einen Architekturüberblick:

Mobile App
Mobile App
Services
Services
Repositories
Repositories
Providers
Providers
Pages
Pages
Widgets
Widgets
User
User
platform
system
platform...
on-device
database
on-device...
server
server
OpenAPI
OpenAPI
UI part
UI part
non-UI part
non-UI part
Models
Models
Entities
Entities

Die Diagramme zeigen die Zielarchitektur. Der aktuelle Zustand des Code-Basis folgt noch nicht immer der Architektur. Neuer Code und Beiträge sollten sich an dieser Architektur orientieren. Derzeit verwendet die Mobile App Isar Database für eine lokale Datenbank und Riverpod für das State Management (Provider). Entitäten und Modelle sind die zwei Arten von Datenklassen, die verwendet werden. Während Entitäten in der Datenbank des Geräts gespeichert werden, sind Modelle flüchtig und werden nur im Speicher gehalten. Die Repositories sollten der einzige Ort sein, an dem intern andere Datenklassen verwendet werden (wie OpenAPI-DTOs). Ihre Schnittstellen dürfen jedoch keine fremden Datenklassen verwenden!

Web-Client

Die Web-App ist ein TypeScript-Projekt, das SvelteKit und Tailwindcss verwendet.

CLI

Das Immich-CLI ist ein npm-Paket, das es Benutzern ermöglicht, ihre Immich-Instanz von der Befehlszeile aus zu steuern. Es verwendet die API, um verschiedene Aufgaben auszuführen, insbesondere das Hochladen von Ressourcen. Weitere Informationen finden Sie in der CLI-Dokumentation.

Server

Das Immich-Backend ist in mehrere Dienste unterteilt, die jeweils als eigene Docker-Container ausgeführt werden.

  1. immich-server - Bearbeitung und Beantwortung von REST-API-Anfragen sowie Ausführung von Hintergrundjobs (Thumbnails generieren, Metadaten extrahieren, Transkodieren usw.)
  2. immich-machine-learning - Ausführung von Modellen des maschinellen Lernens
  3. postgres - Persistente Datenspeicherung
  4. redis - Warteschlangenmanagement für Hintergrundjobs

Immich-Server

Der Immich-Server ist ein TypeScript-Projekt, das für Node.js geschrieben wurde. Er verwendet das Nest.js-Framework, den Express-Server und den Abfrage-Builder Kysely. Der Server-Code basiert lose auf der Hexagonalen Architektur. Ziel ist insbesondere, technologie-spezifische Implementierungen (src/repositories) von der Kern-Business-Logik (src/services) zu trennen.

API-Endpunkte

Eine eingehende HTTP-Anfrage wird zu einem Controller (src/controllers) zugeordnet. Controller sind Sammlungen von HTTP-Endpunkten. Jeder Controller implementiert in der Regel die folgenden CRUD-Operationen für seine Ressourcentypen:

  • POST /<type> - Erstellen
  • GET /<type> - Lesen (alle)
  • GET /<type>/:id - Lesen (nach ID)
  • PUT /<type>/:id - Aktualisieren (nach ID)
  • DELETE /<type>/:id - Löschen (nach ID)

Domain Transfer Objects (DTOs)

Der Server verwendet Domain Transfer Objects als öffentliche Schnittstellen für die Eingaben (Abfrage, Parameter und Body) und Ausgaben (Antwort) für jeden Endpunkt. DTOs werden in OpenAPI-Schemas übersetzt und steuern den generierten Code, der von jedem Client verwendet wird.

Hintergrundjobs

Immich verwendet einen Worker zur Ausführung von Hintergrundjobs. Zu diesen Jobs gehören unter anderem:

  • Thumbnails generieren
  • Metadaten extrahieren
  • Video-Transkodierung
  • Intelligente Suche
  • Gesichtserkennung
  • Migration von Speicher-Templates
  • Sidecar (siehe XMP-Sidecars)
  • Hintergrundjobs (Dateilöschung, Nutzerlöschung)
Info

Diese Liste entspricht weitgehend dem, was auf der Seite Verwaltung > Jobs verfügbar ist, die einige Funktionen für das Remote-Warteschlangenmanagement bietet.

Maschinelles Lernen

Der Dienst für maschinelles Lernen ist in Python geschrieben und verwendet FastAPI für die HTTP-Kommunikation.

Alle mit maschinellem Lernen verbundenen Operationen wurden in diesen Dienst, immich-machine-learning, ausgelagert. Python ist eine natürliche Wahl für KI und maschinelles Lernen. Gleichzeitig hat es sehr spezifische Hardwareanforderungen. Das Ausführen als separater Container ermöglicht es, den Container auf einem separaten Rechner auszuführen oder ihn einfach komplett zu deaktivieren.

Jede Anfrage an den Dienst für maschinelles Lernen enthält relevante Metadaten für die Modellaufgabe, den Modellnamen usw. Diese Einstellungen werden zusammen mit anderen Systemkonfigurationen in Postgres gespeichert. Für jede Anfrage ruft der Microservices-Container diese Einstellungen ab, um sie an die Anfrage anzuhängen.

Intern lädt und konfiguriert der Dienst für maschinelles Lernen das angeforderte Modell für eine Anfrage, bevor er die Text- oder Bildnutzlast damit verarbeitet. Geladene Modelle werden zwischengespeichert und über Anfragen hinweg wiederverwendet. Ein Threadpool wird verwendet, um jede Anfrage in einem separaten Thread zu verarbeiten und so die asynchrone Ereignisschleife nicht zu blockieren.

Alle Modelle liegen im ONNX-Format vor. Dieses Format wird in der Branche breit unterstützt, das bedeutet, dass die meisten anderen Modellformate exportiert werden können und viele Hardware-APIs dies unterstützen. Es ist auch ziemlich schnell.

Modelle des maschinellen Lernens sind auch recht groß und benötigen sehr viel Speicher. Wir suchen ständig nach Möglichkeiten, diesen Aspekt dieses Containers speziell zu verbessern und zu optimieren.

Postgres

Immich speichert Daten in Postgres, einschließlich Informationen zu Zugriffs- und Berechtigungsverwaltung, Nutzern, Alben, Ressourcen, Freigabeeinstellungen usw.

Info

Weitere Informationen zum Modifizieren der Datenbank zum Erstellen eines Indexes, zum Ändern einer Tabelle, zum Hinzufügen einer neuen Spalte usw. finden Sie unter Datenbankmigrationen.

Redis

Immich verwendet Redis über BullMQ, um Job-Warteschlangen zu verwalten. Einige Jobs lösen nachfolgende Jobs aus. Zum Beispiel verlassen sich intelligente Suche und Gesichtserkennung auf die Thumbnail-Generierung und werden automatisch ausgeführt, nachdem eines generiert wurde.