proxmox のVM(docker)にクラウドフォトストレージサーバーを立てる (immich)

Memo
この記事は約7分で読めます。

背景

サーバー構成などの前情報はこちらを参照してください

概要

proxmox VE 8.3 のVMに、docker を使って immich クラウドフォトストレージサーバを立てます。
OSは Rocky Linux 9.5
VMに割り振っているIPは 192.168.1.9 とします。
仮想マシンのメモリは4GB、プロセッサは6コアを与えています。
(※初回大量の写真動画登録時はメモリ8~10GBくらい、CPUはあるだけ与えたほうが良いかもしれません。動画のトランスコードにはGPUを使うこともできるようですが、まだ良く分かっていないので今回は取り扱いません。)

オンプレミスで出来るクラウドフォトストレージは色々ありますが、Nextcloudと連携できるようなものとして他にも PhotoPrism や Memories などがありました。
immich を採用した理由…というよりは他を採用しなかった理由は、
PhotoPrismは、複数アカウントを運用する場合のNextCloudのデータ参照方法ができないor良く分からなかった。
Memoriesは、NextCloudのプラグインなので親和性は良さそうな感じはしますが、どちらかがどちらかをミスると巻き添え食らって時共倒れして両方立て直し、な事になるのが怖かったので。

immichだと、アカウント毎に参照するオリジナルデータのパスを指定することができます。
また、NextCloudに影響を与えないようにできるので、immichに何かあっても立て直して再同期するだけで済みます。

私の場合は複雑にしてしまっていますが、全体の構成イメージはこんな感じです

poxmox本体には極力何も入れたくなかったので、別途LXCコンテナに立てているNFS経由で外部に公開する形にしています。

「直接マウント」については https://www.cyane.info/proxmox-renewal/#toc11 を参照

dockerの導入

まず、Dockerリポジトリを追加してインストールします。

[root@localhost ~]# dnf install -y yum-utils
[root@localhost ~]# dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
[root@localhost ~]# dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

自動起動の構成と起動

[root@localhost ~]# systemctl start docker;systemctl enable docker

immichの導入

immich用のディレクトリを作ります。
dockerのデータは /etc/docker/ に置くのが通例(?)のようなので、/etc/docker/immich を作成します。

[root@localhost ~]# mkdir /etc/docker/immich

docker-compose.ymlと環境設定ファイル(.env)をgithubから持ってきます。

[root@localhost ~]# cd /etc/docker/immich
[root@localhost ~]# curl -L https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml --output docker-compose.yml
[root@localhost ~]# curl -L https://github.com/immich-app/immich/releases/latest/download/example.env --output .env

.env ファイルをカスタマイズ
TZ=Etc/UTC のコメントを外して TZ=Asia/Tokyo
DB_PASSWORD、DB_USERNAME、DB_DATABASE_NAME、を適当にカスタマイズ (記号無しの文字のみがお勧めとのこと)

既存の写真ライブラリ(外部データベース)をImmichに追加する

[root@localhost ~]# vim /etc/docker/immich/docker-compose.yml

で以下を設定。
同じパスでややこしいかもしれませんが、左側の /mnt/nextcloud/ がdocker内のマウントポイント
右側の /mnt/nextcloud:ro がVM側のパス。万が一にもNextCloud側に影響を与えないために読み取り専用とする :ro を付けています。

immich-server:
  volumes:
    - /mnt/nextcloud/:/mnt/nextcloud:ro

NextCloudとimmichのサーバーは別なので、NFSでファイル共有アクセスできるようにします。
NFS クライアントインストール

[root@localhost ~]# dnf install -y nfs-utils

マウントポイントの作成とマウント実行
smb.local はNFSサーバー(192.168.1.5)です。

[root@localhost ~]# mkdir /mnt/nextcloud
[root@localhost ~]# mount -t nfs smb.local:/mnt/raid-pool/nextcloud /mnt/nextcloud
[root@localhost ~]# mount -t nfs smb.local:/mnt/raid-pool/immich_lib_cache /etc/docker/immich/library2

起動時にマウントさせる場合は /etc/fstab に以下を記述

smb.local:/mnt/raid-pool/nextcloud /mnt/nextcloud nfs ro 0 0
smb.local:/mnt/raid-pool/immich_lib_cache /etc/docker/immich/library nfs rw 0 0
smb.local:/mnt/ssd-pool/immich_db_cache /etc/docker/immich/postgres nfs rw 0 0

なお、immichのキャッシュデータも割と容量を食うので外部ディスクに置けるようにマウントしています。

起動後の設定

私の環境用の設定ですが参考に記載しておきます。

アカウント作成

利用メンバー分のアカウントを作成しておきます

システム設定

画像設定

  • プレビュー設定
    インターネットから接続時を考慮した速度重視でJPEGとし、解像度は1080pに下げています
    品質は80

ログ

  • ログレベル
    Warn

動画トランスコード設定

トランスコードポリシー
  • トランスコードポリシー
    設定解像度を超える動画、または容認されていない形式の動画
  • 容認する動画コーデック
    VP9
  • 容認する音声コーデック
    全て
  • 容認するコンテナ
    全て

エンコードオプション

  • 動画コーデック
    vp9
  • 音声コーデック
    aac
  • 解像度
    720p
  • CEF値
    35
  • プリセット
    medium
  • 最大ビットレート
    0
  • スレッド数
    0
  • トーンマッピング
    Hable
  • Two-passエンコード
    無効

外部ライブラリ設定

外部参照先毎にその所有者(アカウント)を設定します。

右上の「ライブラリを作成」から対象のアカウントを選択し、作成します。
その後、アカウントのメニューから「インポートパスを編集」から外部ライブラリのパスを設定します。
.envファイルで設定した外部NextCloudのルートパスから、Photosのパスを設定します。
私の場合は「/mnt/nextcloud/lscyane/files/Photos/」としています。

後はスキャンしてエンコードの完了を待ちます。
写真はそうでもですが、やはり動画は時間かかります。私の場合は3日くらいかかったかなと思います。
この辺りはGPUが使えれば良いとは思うのですが、こんな時間かかるのは初回くらいなので手を出せていません。。。

アップデート方法

Immichをアップグレードして再起動する。
デフォルトの docker-compose.yml ならバージョンは lathest を指定しているので、 pull するだけで最新になります。

[root@localhost ~]# cd /etc/docker/immich/
[root@localhost ~]# docker compose pull && docker compose up -d

未使用のDockerイメージをクリーンアップする。
アップデートしても古いイメージは残るのでアウトレージを圧迫します。アップデートしたら不要になったdockerイメージは削除しておきます。

[root@localhost ~]# docker image prune

タイトルとURLをコピーしました