SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-28

Immichの必要RAMと安全なアップグレード方法

Immichの正直な必要RAMは6 GB、HTTPSでのポート2283、exit 137のメモリ停止、pgvecto.rsではImmich v3が起動しない理由と復元手順を解説します。

構築するもの

Immich はセルフホスト型の写真・動画バックアップサービスで、Google Photos の実用的な代替手段です。スマートフォンアプリがカメラロールをバックグラウンドでアップロードし、タイムライン、アルバム、顔認識、機械学習による検索を利用できます。タグを手動で付けなくても、「beach」や人物を検索できます。所有する VPS 上で運用するため、オリジナルファイルは自分のディスクに保存され、広告目的でスキャンされることもありません。もう1つの有力な候補と比較検討している場合は、PhotoPrism と Immich の比較で、必要な RAM、スマートフォンアプリ、バックアップコマンドを並べて確認できます。

インストールでは、プロジェクトが提供する Docker Compose ファイルから4つのコンテナを起動します。ここまでは10分で完了します。このガイドで注意が必要なのは、その後の運用です。機械学習コンテナは小規模なマシンでは大量のメモリを必要とし、オリジナルファイルはすぐにディスク容量を消費します。モバイルアプリは HTTP のみのサーバーへの接続を拒否します。また、Immich は互換性を損なう変更を頻繁にリリースするため、不用意な docker compose pull によってデータベースが起動できなくなることがあります。この4点を確実に管理すれば、Immich は非常に安定して動作します。無視すると、週末をトラブル対応に費やすことになります。

前提条件と、注意すべき点

  • RAM: 公式ドキュメントでは最小 6 GB、推奨 8 GB とされています。4 GB に swap を追加した構成を絶対的な下限と考えてください。 immich-server と Postgres のコンテナは比較的軽量です。immich-machine-learning コンテナは、検索インデックスの作成時に CLIP と顔認識モデルを RAM に読み込むため、最も負荷が高くなります。2 GB のサーバーではカーネルによって停止させられます。RAM が 4 GB ある場合でも swap を追加してください。
  • ディスク: ライブラリ全体を保存できる容量に、さらに余裕を持たせてください。 元のファイルは完全な形でコピーされます。さらに Immich がサムネイルとプレビュー画像を生成するため、追加でおよそ 10–20% 必要です。200 GB の写真コレクションには 300 GB のボリュームが必要です。Postgres の使用量はそれと比べると小さいです。
  • CPU: 最新の KVM VPS であれば問題ありませんが、CPU 上での ML 処理は低速です。 大量の写真をインポートした後のスマート検索インデックス作成には、バックグラウンドで数時間かかる場合があります。これは正常な動作です。GPU は必要ありません。
  • VPS に向けて設定したドメイン名。 モバイルアプリは HTTPS エンドポイントを強く推奨します。また、前段にリバースプロキシを置く構成にします。これは Docker、TLS、バックアップを使うセルフホスト Nextcloud インスタンス と同じ構成です。Immich は、そのファイルサーバーに対応する写真管理サービスです。
  • Docker と Compose plugin のインストール。 Docker Engine と Compose v2 plugin は、Docker 独自の apt リポジトリからインストールしてください。手順は Docker Compose 基礎ガイド で説明しています。

最初に swap を追加する

小規模な VPS で Immich が失敗する原因として最も多いのは、ML コンテナが OOM により強制終了されることです。まず、カーネルが使用できる領域を確保します。

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h

free -h の出力に、4.0GiSwap: 行が表示されるはずです。これによって ML の処理が高速になるわけではありませんが、4 GB のマシンでインデックス作成中にコンテナが終了することを防げます。

Step 2: 公式の compose と env を取得し、コピーではなく公式のものを使う

Immich は、リリース時に提供するファイル内でサービスのバージョンと、特にデータベースイメージを固定しています。ブログ(この記事を含む)から compose ファイルを貼り付け、それを信頼できる唯一の情報源にしないでください。リリースアセットをダウンロードします。

sudo mkdir -p /opt/immich && cd /opt/immich
sudo wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
sudo wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

これらはタグ付きリリースから取得されるため、イメージ参照が一致します。compose ファイルには4つのサービスが定義されています。各サービスに触れる前に、役割を確認しておくと作業しやすくなります。

  • immich-serverghcr.io/immich-app/immich-server、コンテナ immich_server):API と Web UI を提供し、ポート 2283 で待ち受けます。アップロードデータを /data にマウントします。
  • immich-machine-learningghcr.io/immich-app/immich-machine-learning、コンテナ immich_machine_learning):CLIP 検索と顔認識を担当します。ダウンロードしたモデルを model-cache ボリュームにキャッシュします。最も多くのメモリを消費するサービスです。
  • database(コンテナ immich_postgres):類似検索を提供する VectorChord ベクトル拡張機能付きの Postgres です。イメージタグは compose ファイル内でダイジェストにより固定されており、例として ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:... のようになります。以前の構成では pgvecto.rs が使われていましたが、Immich v3.0 でサポートが削除されました。そのため、現在インストールするものはすべて VectorChord です。このタグは手動で編集しないでください。
  • redis(コンテナ immich_redis):ジョブキュー用の Valkey/Redis インスタンスです。

ステップ 3: 写真とデータベースを格納する .env を設定する

.env を開き、4 つの項目を設定します。マーカー行より下は変更しません。

# Where original uploads are stored on the host
UPLOAD_LOCATION=/opt/immich/library

# Where the Postgres data lives. NEVER put this on an NFS/network share.
DB_DATA_LOCATION=/opt/immich/postgres

# "v3" is a floating tag that tracks the latest v3.x. Pin a full tag like
# v3.0.2 instead — then you upgrade on purpose, not by surprise.
IMMICH_VERSION=v3.0.2

# Change this to a long random string. Letters and digits only.
DB_PASSWORD=REPLACE_WITH_A_LONG_RANDOM_STRING

# Set your timezone so timestamps and "on this day" line up
TZ=Europe/London

###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

問題を避けるための重要なルールが2つあります。後でデータボリュームを追加する場合、UPLOAD_LOCATION には大容量ディスクを指定し、最初からそのマウントパスを設定してください。後から変更すると、サムネイルの移動とアセットパスの更新が必要になります。また、DB_DATA_LOCATION はローカルディスク上に置く必要があります。NFS または SMB 共有上の Postgres はデータを破損させます。ドキュメントにも明記されています。DB_PASSWORD には英字と数字だけを使用すると、接続文字列のエスケープに関する不具合の一部を回避できます。

手順 4: 初回起動と admin ユーザーの作成

cd /opt/immich
sudo docker compose up -d
sudo docker compose ps

正しい結果は、4 つのコンテナがすべて running で、最終的に healthy になる状態です。

NAME                      STATUS
immich_machine_learning   Up (healthy)
immich_postgres           Up (healthy)
immich_redis              Up (healthy)
immich_server             Up (healthy)

最初の up では数 GB のイメージを複数取得するため、完了まで待ちます。sudo docker compose logs -f immich-server で進行状況を確認できます。準備が完了すると、サーバーはポート 2283 で待ち受けていることをログに記録します。次に、ブラウザーで http://YOUR_SERVER_IP:2283 を開きます。初回アクセスでは Getting Started ウィザードが表示され、最初に作成したアカウントが admin になります。強力なパスワードを設定してください。このアカウントで、後で必要になるサーバー設定、ユーザー管理、ML 設定を管理します。

手順 5: モバイルアプリとバックグラウンドバックアップ

App Store または Play Store から「Immich」をインストールします。ログイン画面で Server Endpoint URL の入力を求められます。スキームを含む完全な URL を入力します。例: https://photos.example.com(アプリが /api を自動的に付加します)。作成したばかりのアカウントでログインし、アプリの Backup 画面を開きます。バックアップ対象のアルバム(通常は Camera と Screenshots)を選択し、Background backup を有効にします。iOS のバックグラウンドバックアップは OS によって制限されます。フォアグラウンドでのアップロードは常に実行されますが、バックグラウンドでのアップロードは OS が許可した場合に実行されます。

ここで行き詰まる人が多いため、アプリの操作に悩む前に手順 6 を読んでください。

Step 6: リバースプロキシ経由の HTTPS と完全な URL のルール

モバイルアプリは HTTPS を強く要求します。ポート 2283 の前段にリバースプロキシを置き、そこで TLS を終端します。すでに複数のコンテナを運用している場合は、複数の Docker アプリで TLS を自動化する Traefik が最も整理しやすい選択肢です。1 つのラベルブロックで photos.example.comimmich-server コンテナへ転送し、証明書も自動取得します。nginx を使う場合は、Certbot と nginx で Let's Encrypt を使用する方法に従うと、証明書と proxy_pass http://127.0.0.1:2283; ブロックを用意できます。このプロキシがあれば、次のサービスを追加するときは主に新しいサブドメインを用意するだけです。そのため、Jellyfin 向けの 90 年代ビデオ店風スキンである Halcyon のようなメディアフロントエンドも、同じサーバー上で Immich と並べて運用できます。Codex と Claude Code を 1 つの API の背後に置くセルフホスト型 HarnessRouter も同様です。このサービスは意図的に loopback に bind し、前段のプロキシが TLS を終端して初めて到達可能になります。サブドメインを割り当てる前に、デフォルトのログイン情報を変更してください。ただし、すべてのコンテナに公開ホスト名が必要なわけではありません。セルフホスト型の open-kritt セキュリティスキャナーのように管理者だけが使うツールは、プロキシの対象から外し、UI を開く必要があるまれな場合だけ SSH トンネル経由でアクセスするほうが適切です。HTTP をまったく使用しないため、プロキシを使わないサービスもあります。セルフホスト型 RustDesk リレーサーバーがその典型例です。このサービスは複数の TCP および UDP の raw ポートで待ち受けるため、サブドメインではなくファイアウォールルールを使用します。Immich では、プロキシの設定が 1 つ重要です。スマートフォンの動画は大きいため、アップロードサイズの上限を引き上げます。nginx では、server ブロック内に client_max_body_size 50000M; を指定します。デフォルトの 1 MB では、動画のアップロードが 413 Request Entity Too Large で拒否されます。

アプリが適用するルールは、エンドポイントに到達でき、実際には HTTPS であることです。http:// のエンドポイントや、ポートを省略した直接 IP アドレスでは、「アプリがサーバーに到達できません」というエラーが発生します。この問題については、以下で名前付きの障害として説明します。

手順 7: 外部ライブラリとアップロード、既存の写真ツリーのインポート

写真を Immich に取り込む方法は 2 つあります。両者は同じものではありません。

  • アップロードは Immich が所有するアセットです。アプリまたは Web アップローダーがファイルを UPLOAD_LOCATION にコピーします。Immich はファイル名の変更、移動、削除を実行できます。
  • 外部ライブラリは、サーバー上のフォルダー、以前の Pictures ツリー、NAS のエクスポートなどに既に存在するファイルを読み取り専用でインポートしたものです。Immich はファイルをその場でインデックス化し、タイムラインに表示しますが、元のファイルを変更または削除することはありません。

既存のツリーをインポートするには、サーバーコンテナ内に読み取り専用でマウントします。immich-server: 配下の docker-compose.yml を編集し、volume を追加します。

  immich-server:
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
      - /srv/photos:/mnt/media/photos:ro

:ro により、Immich が元のファイルに触れることを防止できます。sudo docker compose up -d でコンテナを再作成します。次に Web UI でアバター → Administration → External Libraries → Create Library の順に移動し、所有ユーザーを選択します。Folders の下にある Add をクリックし、ホストパス /srv/photos ではなく、コンテナ内のパス /mnt/media/photos を入力します。Scan をクリックします。ホストパスをコンテナパスの代わりに使用することは、外部ライブラリで最も多いミスです。この場合、スキャンで何も見つからず、アセット数が 0 と報告されます。

ステップ 8: Immich が求めるアップグレードの原則

ここが、正常に動作する Immich と壊れた Immich を分けるポイントです。Immich はリリース頻度が高く、修正のバックポートやダウングレードをサポートしていません。浮動する v3 タグを無条件に追跡すると、最終的にデータベースが壊れます。同じく、タグを固定してからリリースノートを読む習慣は、このサーバー上で長期間稼働するすべてのコンテナに適用する価値があります。そのため、自己ホスト型の KiroCrew エージェントも、既知の正常な 1 つのタグに固定します。次回の再起動時に、意図せず更新される状態にはしません。原則は次のとおりです。

  1. バージョンを固定します。 IMMICH_VERSION には、常に最新の v3.x を取得する浮動タグ v3 ではなく、v3.0.2 のような具体的なタグを設定します。
  2. アップグレードの前に、毎回必ずリリースノートを読みます。 破壊的変更、特にデータベースやベクトル拡張機能の変更は、リリースノートに記載されています。v3.0 リリースがその典型例です。このリリースでは pgvecto.rs が完全に削除されたため、旧拡張機能を使い続けていた場合は、先に VectorChord への移行を完了する必要がありました。VectorChord は v1.133 で導入されています。
  3. 最初にデータベースをバックアップします(ステップ 9)。常に必要ですが、リリースノートにデータベースへの言及がある場合は特に重要です。
  4. 新しい compose ファイルも取得します。 IMMICH_VERSION で固定されるのは server イメージと ML イメージだけです。Postgres イメージは docker-compose.yml 内部 で digest により固定されています。そのため、新しいデータベース拡張機能が必要なバージョンでは、新しい compose ファイルがリリースされます。両方のリリースアセットを再ダウンロードし、.env の値を再設定してからアップグレードします。
  5. モバイルクライアントも同じ時期に更新します。 server は対応するメジャーバージョンとのみ通信し、アプリは現在のメジャーバージョンと 1 つ前のメジャーバージョンをサポートします。server がアプリより先のバージョンへ更新されると、アプリを更新するまでスマートフォンに Your app major version is not compatible with the server! と表示されます。そのため、先にアプリを更新するのが安全です。

新しいファイルを配置した後は、次のコマンドを実行します。

cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune

手順 9: バックアップ、データベースダンプとオリジナルファイル、そして復元テスト

Immich のバックアップには 2 つの要素があり、どちらか一方だけでは役に立ちません。データベースには、アルバム構造、顔認識データ、検索インデックス、アセットとファイルの対応関係が保存されます。オリジナルファイルのディレクトリには、実際の写真が保存されます。一方だけを復元すると、整理情報のない写真だけが残るか、ファイルが見つからない空の構成だけが残ります。この 2 要素の構成は Immich 固有のものではありません。セルフホストの Chatwoot サポートデスクでも、Postgres のダンプとアップロードディレクトリを組み合わせる必要があります。そうしないと、復元した受信箱ですべての添付ファイルが失われます。Postgres のデータディレクトリをファイルツリーとしてコピーすればダンプの手順を省けるように見えますが、実用的なバックアップにはなりません。これは、Immich の完全なバックアップと復元手順で扱う、復元後にタイムラインが空になる典型的な落とし穴です。

Postgres コンテナ内から pg_dump を使用して、データベース全体ではなく immich データベースをダンプします。

sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
  --dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gz

次に UPLOAD_LOCATION、つまり /opt/immich/library ツリー全体をバックアップします。特に library/upload/profile/ サブディレクトリを、resticrsync、または borg で別のマシンやオブジェクトストレージへ保存します。この処理を cron エントリや systemd timer で定期実行する場合は、失敗時の通知先が必要です。自分で用意した ntfy push サーバーを指す systemd OnFailure= unit を設定すれば、ダンプに失敗した夜にスマートフォンへ通知できます。復元時まで失敗に気付かずに済むため、重要な設定です。データベースを先に処理し、ファイルを後に処理します。これにより、ダンプがまだファイルバックアップにコピーされていない写真を参照することを防げます。外部ライブラリは、実際の保存元で別途バックアップします。Immich は外部ライブラリを管理しません。

ここで、誰もが省略しがちな作業を行います。復元をテストします。 復元は、サーバーを一度も起動していない 新しい stack に対して実行する必要があります。また、ダンプと互換性のある vector 拡張機能を備えた Postgres image を使用します。これが、DB image tag を場当たり的に選んではならない理由です。同じ compose と .env を使用する検証用マシンで古い状態を削除し、データベースだけを起動してから、ダンプを読み込みます。

cd /opt/immich
sudo docker compose down -v
sudo docker compose pull
sudo docker compose create
sudo docker start immich_postgres
sleep 10
gunzip --stdout immich-db-2026-07-15.sql.gz |
  sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" |
  sudo docker exec -i immich_postgres psql --dbname=immich --username=postgres --single-transaction --set ON_ERROR_STOP=on
sudo docker compose up -d

VectorChord データベースでは、search_pathsed 書き換えは必須です。省略すると、復元は途中で中断します。オリジナルファイルを配置した状態で stack が起動したら、Web UI を開きます。写真とアルバムが表示されれば、バックアップは正常に機能しています。このテストを一度も実行していない場合、それはバックアップではありません。単なる期待です。

障害パターンと表示される文字列

ML コンテナが OOM により強制終了される。 sudo docker compose logs immich-machine-learning が突然終了し、docker compose psRestarting と表示され、終了コードは 137 です。sudo dmesg | grep -i oom でも Out of memory: Killed process ... (python3) と確認できます。その後、検索ジョブと顔認識ジョブが停止します。原因は、モデルに対して RAM が不足していることです。対処は次の順に行います。swap を追加する(Step 1)、VPS の RAM を増やす、どうしても対応できない場合は Administration → Settings → Machine Learning SettingsSmart SearchFacial Recognition をオフにして ML を無効にする、のいずれかです。バックアップとアルバムは保持されますが、コンテンツによる検索は利用できなくなります。compose file から immich-machine-learning service を削除しても同じ結果になります。

アップグレード後に Postgres が起動しない。 サーバーログに The database currently has VectorChord 0.5.3 activated, but the Postgres instance only has 0.4.2 available. This most likely means the extension was downgraded. のような行が繰り返し表示されます。古い stack では The pgvecto.rs extension is not available in this Postgres instance. と表示される場合があります。原因は、データをアップグレードした際のバージョンより古い extension version を持つ database image が使用されていることです。ほとんどの場合、image tag を手動で編集したか、新しい dump を古い image に復元したことが原因です。対処として、対応する Postgres image を使用し、データベースに対応する release の compose file を使います。ダウングレードは行わず、互換性のある image にのみ復元してください。

モバイルアプリからサーバーに接続できない。 URL を入力すると、ログイン画面に接続エラーまたは Server is not reachable と表示されます。原因は3つあります。proxy が https:// だけを提供しているのに http:// を入力した、backend に直接接続したが port を省略したため example.com:2283 ではなく example.com(port 443)を試行した、または reverse proxy が /api を転送していない、のいずれかです。完全な https://photos.example.com URL を入力し、最初にスマートフォンのブラウザーで読み込めることを確認してください。ブラウザーでは動作するのにアプリでは動作しない場合、proxy が path を削除しているか、certificate が self-signed である可能性があります。アプリは信頼されていない certificate を拒否します。

import の途中でディスク容量が不足する。 upload が失敗し始め、thumbnail が空白になり、ログに ENOSPC: no space left on device または Postgres から could not extend file ... No space left on device と表示されます。df -hUPLOAD_LOCATION volume が 100% であることを確認できます。大規模な library を import する前にディスク容量を確保する必要があるのはこのためです。復旧するには、大容量の volume を接続して stack を停止し、UPLOAD_LOCATION をその volume に移動して .env を更新し、再度起動します。provider が対応していれば、既存のディスクを拡張しても構いません。容量が尽きると Postgres が停止状態になることがあるため、破損を疑う前に空き容量を確保し、database container を再起動してください。

FAQ

Immich にはどの程度の RAM とディスク容量が必要ですか?

Immich の公式要件は、RAM が最小 6 GB、推奨 8 GB です。小規模なライブラリでは、swap を含めて 4 GB が実用上の下限です。いずれの場合も swap を設定してください。最もメモリ使用量が急増するのは machine-learning コンテナです。ディスク容量は、ライブラリ全体のサイズに加えて、生成されるサムネイルとプレビュー用におよそ 10–20% を見積もってください。データはローカルストレージに置き、Postgres のデータディレクトリをネットワーク共有に置かないでください。ほかに何を実行するか検討中であれば、2026 年にセルフホストするサービスのガイドで、Immich の使用リソースを他のサービスと比較できます。

GPU なしで Immich を実行できますか?

はい。machine-learning コンテナは CPU で問題なく動作します。GPU は、スマート検索のインデックス作成を高速化するほか、適切なイメージバリアントを使用した場合は動画のトランスコードも高速化します。CPU では、大規模なライブラリの初回インデックス作成にバックグラウンドで数時間かかることがありますが、バックアップやブラウジングは妨げません。マシンが ML を実行できないほど小規模であれば、管理者設定で Smart Search と Facial Recognition を無効にし、それ以外の機能を利用できます。

Immich を安全にアップグレードするにはどうすればよいですか?

IMMICH_VERSIONv3.0.2 のような具体的なタグに固定し、アップグレードのたびにリリースノートを確認してから、最初にデータベースをバックアップしてください。Postgres イメージは IMMICH_VERSION ではなく docker-compose.yml 内で固定されているため、対象リリースの compose ファイルと example.env を再ダウンロードし、設定値を再適用してから docker compose pull && docker compose up -d を実行します。バージョンを unattended のまま変動させないでください。Immich は互換性を壊す変更をリリースすることがあり、ダウングレードをサポートしていません。

具体的に何をバックアップすればよいですか?

次の 2 つをセットでバックアップします。immich データベースの pg_dump と、UPLOAD_LOCATION originals ディレクトリ全体です。データベースにはアルバム、顔情報、アセットとファイルの対応関係が保存されます。ディレクトリには実際の写真が保存されます。リストアには、この両方に加えて、互換性のある vector extension を含むデータベースイメージが必要です。先にデータベースを dump し、次にファイルをコピーしてください。少なくとも 1 回は scratch box でリストアをテストしてください。テストしていないバックアップは、バックアップとはいえません。

既存の写真フォルダーをインポートするにはどうすればよいですか?

フォルダーを read-only で追加ボリュームとして immich-server コンテナにマウントします(例: - /srv/photos:/mnt/media/photos:ro)。その後、コンテナを再作成し、Administration → External Libraries でライブラリを作成して、container パス /mnt/media/photos を追加します。Immich はファイルをその場所でインデックス化し、ファイルを変更または削除しません。最もよくある間違いは、container パスではなく host パスを入力することです。この場合、スキャンで何も見つかりません。