メインコンテンツにスキップ

アーキテクチャ

Immichは、データ永続化のための専用データベースを備えた従来型のクライアント-サーバー設計を使用しています。フロントエンドクライアントは、REST APIを使用してバックエンドサービスとHTTP通信を行います。以下にアーキテクチャの高レベルな図を示します。

高レベルの図

Immich Architecture

この図は、クライアントがRESTを介してサーバーのAPIと通信する様子を示しています。サーバーは、リポジトリーインターフェースを通じて、下流システム(例:Redis、Postgres、機械学習、ファイルシステム)と通信します。この図には示されていませんが、サーバーはimmich-serverimmich-microservicesの2つの個別コンテナに分割されています。microservicesコンテナはAPIリクエストやcronジョブのスケジュールを処理せず、主にRedisからのジョブリクエストを処理します。

クライアント

Immichには主に3つのクライアントがあります:

  1. モバイルアプリ - Android、iOS
  2. ウェブアプリ - レスポンシブウェブサイト
  3. CLI - 大量アップロード用のコマンドラインユーティリティ
情報

これら3つのクライアントはすべて、容易な統合のためにOpenAPIを使用してRESTクライアントを自動生成します。このプロセスの詳細についてはOpenAPIを参照してください。

モバイルアプリ

モバイルアプリはDartFlutterを使用して作成されています。以下にアーキテクチャの概要を示します:

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

この図は目標とするアーキテクチャを示したものであり、現在のコードベースの状態は必ずしもこのアーキテクチャに従っていません。新しいコードや貢献はこのアーキテクチャに従うべきです。 現在、ローカルデータベースにIsar Databaseを使用し、状態管理(プロバイダー)にRiverpodを使用しています。 エンティティとモデルの2種類のデータクラスが使用されています。エンティティはデバイス内のデータベースに保存されますが、モデルは一時的なものでありメモリ内にのみ保持されます。 リポジトリは、他のデータクラス(例:OpenAPI DTO)の内部使用が許可されている唯一の場所です。ただし、そのインターフェースは外部データクラスを使用してはなりません!

ウェブクライアント

ウェブアプリはTypeScriptを使用したプロジェクトで、SvelteKitTailwindcssを使用しています。

CLI

Immich CLIは、ユーザーがコマンドラインからImmichインスタンスを制御できるnpmパッケージです。APIを使用して、特にアセットのアップロードなどのさまざまなタスクを実行します。詳細はCLIドキュメントを参照してください。

サーバー

Immichのバックエンドは、個別のDockerコンテナとして実行される複数のサービスに分割されています。

  1. immich-server - REST APIリクエストの処理と応答、バックグラウンドジョブの実行(サムネイル生成、メタデータ抽出、トランスコードなど)
  2. immich-machine-learning - 機械学習モデルの実行
  3. postgres - 永続的なデータストレージ
  4. redis - バックグラウンドジョブのキュー管理

Immichサーバー

ImmichサーバーはNode.js向けに作成されたTypeScriptプロジェクトです。Nest.jsフレームワーク、Expressサーバー、およびクエリビルダーKyselyを使用しています。サーバーのコードベースは六角形アーキテクチャに大まかに従っています。具体的には、技術固有の実装(src/repositories)とコアビジネスロジック(src/services)を分離することを目指しています。

APIエンドポイント

受信HTTPリクエストは、コントローラ(src/controllers)にマッピングされます。コントローラはHTTPエンドポイントの集合体です。各コントローラは通常、各リソースタイプに対して以下のCRUD操作を実装します:

  • POST /<type> - 作成
  • GET /<type> - 読み取り(すべて)
  • GET /<type>/:id - 読み取り(IDによる)
  • PUT /<type>/:id - 更新(IDによる)
  • DELETE /<type>/:id - 削除(IDによる)

ドメイン転送オブジェクト(DTO)

サーバーは、各エンドポイントの入力(クエリ、パラメータ、本文)および出力(応答)用のパブリックインターフェースとしてドメイン転送オブジェクトを使用します。DTOはOpenAPIスキーマに変換され、各クライアントで使用される生成コードを制御します。

バックグラウンドジョブ

Immichはworkerを使用してバックグラウンドジョブを実行します。これらのジョブには次のものが含まれます:

  • サムネイル生成
  • メタデータ抽出
  • ビデオトランスコード
  • スマート検索
  • 顔認識
  • ストレージテンプレートの移行
  • サイドカー(XMPサイドカーを参照)
  • バックグラウンドジョブ(ファイルの削除、ユーザーの削除)
情報

このリストは、管理 > ジョブページにあるリモートキュー管理機能にほぼ一致します。

機械学習

機械学習サービスはPythonで記述され、HTTP通信にFastAPIを使用しています。

機械学習関連のすべての操作はこのサービスimmich-machine-learningに外部化されています。PythonはAIおよび機械学習に適しています。また、非常に特定のハードウェア要件もあります。そのため、独立したコンテナとして実行することで、別のマシンで簡単に実行したり、完全に無効化したりできます。

機械学習サービスへの各リクエストには、モデルタスク、モデル名などの関連メタデータが含まれています。これらの設定は他のシステム構成とともにPostgresに保存されます。各リクエストに対して、マイクロサービスコンテナはこれらの設定を取得し、リクエストに添付します。

内部では、機械学習サービスが、リクエストに指定されたモデルをダウンロード、読み込み、設定し、その後にそのモデルを使ってテキストまたは画像のペイロードを処理します。読み込まれたモデルはキャッシュされ、リクエスト間で再利用されます。スレッドプールを使用して各リクエストを別々のスレッドで処理し、非同期イベントループをブロックしないようにします。

すべてのモデルはONNX形式です。この形式は業界で広くサポートされており、ほとんどの他のモデル形式をエクスポートしたり、多くのハードウェアAPIでサポートしたりできます。また非常に高速です。

機械学習モデルは非常に大きく、かなり多くのメモリを必要とします。このコンテナに関しては、この点を改善および最適化する方法を常に模索しています。

Postgres

Immichは、アクセスと認可、ユーザー、アルバム、アセット、共有設定などの情報をPostgresに永続化します。

情報

データベースのインデックス作成、テーブルの変更、新しいカラムの追加など、データベースを変更する方法についてはデータベースマイグレーションを参照してください。

Redis

ImmichはRedisvia BullMQを介してジョブキューを管理します。いくつかのジョブは後続のジョブをトリガーします。例として、スマート検索と顔認識はサムネイル生成に依存しており、自動的にそれが生成された後に実行されます。