ImmichをDockerでデプロイ:HomeLabのための自己ホスト型写真・動画バックアップ

HomeLab tutorial - IT technology blog
HomeLab tutorial - IT technology blog

大手テクノロジー企業に思い出を委ねることの問題

ある日Google Photosを開くと、無料の無制限ストレージが2年前に終了していたことに気づく。2021年の写真の半分が宙ぶらりんのまま——気づかないうちに容量の上限に達していたのだ。あるいはこんなメールが届いたかもしれない:「ストレージが95%使用済みです。Google Oneにアップグレードしてください。」

まさにこれが私に起きたことだ。家族の写真、旅行のスナップショット、何気ないスクリーンショット——すべてが他人のサーバーに置かれ、払い続けなければならないサブスクリプションの壁の向こうにある。本当の問題はお金ではない。依存関係だ。サービスが料金体系を変えるか、あるいはサービス終了になれば、あなたの思い出も一緒に消えてしまう。

クラウド写真サービスはユーザーを依存させるように設計されている。最初は便利で、データが蓄積されるとロックインされる。無料枠は縮小し、価格は上がり、写真がどのように保存・圧縮され、広告主と共有されるかについて、あなたには何の制御権もない。

NAS、古いPC、あるいはRaspberry Pi 4でもいい——HomeLabをすでに運用しているなら、自分だけのGoogle Photos代替ソリューションをホストできる。月額費用なし、圧縮なし、プライバシーの妥協なし。それが Immich だ。

Immichとは何か

Immichはオープンソースの自己ホスト型写真・動画バックアップソリューションだ。見た目も動作もGoogle Photosにほぼそっくり——モバイル自動バックアップ、タイムラインビュー、アルバム、共有ライブラリ——しかしすべてが自分のハードウェア上で動く。

Synology PhotosやPhotoPrismのようなシンプルなツールと比べて、Immichが際立つ点がいくつかある:

  • モバイルアプリ:iOSとAndroid向け、バックグラウンド自動バックアップ対応
  • AI機能:顔認識、物体検出、CLIPエンべディングを使ったシーン分類
  • EXIFベースのタイムライン:日付、場所、カメラモデルで写真を閲覧
  • マルチユーザー対応:家族それぞれに独立したライブラリ、共有コントロール付き
  • RAWファイル対応とロスレスオリジナル保存——再圧縮なし
  • ビデオトランスコード:ハードウェアアクセラレーション対応(Intel QSV、NVIDIA NVENC、VA-API)

写真ライブラリを商業クラウドから自分が管理するハードウェアに移すことは、プライバシー重視のHomeLabで最も効果的なことのひとつだ。Immichが稼働すれば、スマートフォンからの自動バックアップはそのまま機能する——Google Photosとまったく同じように、ただしデータは手元に残る。Dockerコンテナのセットとしてデプロイするのでアップデートもクリーンに保て、ロールバックも簡単だ。

始める前に確認すること

デプロイ前にこれらを確認しておこう:

  • DockerとDocker Compose v2以上がインストール済みであること
  • 最低4 GBのRAM——顔認識などのAI機能を有効にするなら8 GBに増やすこと
  • 十分なディスク容量:一般的なスマートフォンは写真と動画で月に5〜10 GBを生成する。最初から外付けドライブかNASをマウントしておくこと
  • ドメイン名はオプションだが、HTTPSリモートアクセスを望むなら用意する価値がある

Docker ComposeでImmichをデプロイする

ステップ1:プロジェクトディレクトリと環境ファイルを作成する

mkdir -p ~/immich && cd ~/immich

公式の docker-compose.yml.env テンプレートをImmichリポジトリから直接取得する:

curl -L https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml -o docker-compose.yml
curl -L https://github.com/immich-app/immich/releases/latest/download/example.env -o .env

ステップ2:.envファイルを設定する

.env を開いて、主要な変数を設定する:

# ホスト上で写真を保存するパス
UPLOAD_LOCATION=/data/immich/photos

# データベースのパス
DB_DATA_LOCATION=/data/immich/postgres

# 特定のリリースに固定するか、最新の安定版には「release」を使用
IMMICH_VERSION=release

# タイムゾーン
TZ=Asia/Tokyo

# データベースパスワード — 長くてランダムなものを使うこと
DB_PASSWORD=your_strong_password_here

/data/immich/photos が十分なスペースとともに存在することを確認する。外付けドライブをマウントしている場合は、UPLOAD_LOCATION をそのマウントパスに向けること。

sudo mkdir -p /data/immich/photos /data/immich/postgres
sudo chown -R $USER:$USER /data/immich

ステップ3:スタックを起動する

docker compose up -d

Dockerが4つのコンテナを取得して起動する:

  • immich-server — メインAPI、Web UI、バックグラウンドジョブ処理
  • immich-machine-learning — 顔認識とCLIPエンべディング
  • redis — ジョブキュー
  • postgres — メタデータデータベース

すべて正常に起動したか確認する:

docker compose ps

Web UIは http://your-server-ip:2283 でアクセスできる。初回アクセス時に管理者アカウントを作成する。

ステップ4:モバイルアプリをセットアップする

スマートフォンにImmichアプリをインストールする(iOSもAndroidも対応)。セットアップ時:

  1. サーバーURLを入力する:http://your-server-ip:2283
  2. 管理者アカウントでログインするか、家族のメンバー用に別のユーザーアカウントを作成する
  3. アプリの設定で自動バックアップを有効にする——新しい写真はGoogle Photosのようにバックグラウンドでアップロードされる

ストレージレイアウトと外付けドライブのマウント

OSドライブが小さい場合(ミニPCやNUCでよくある状況)、最初から別のディスクにImmichを向けておこう。外付けドライブをマウントして接続する方法は以下の通りだ:

# ドライブを探す
lsblk

# マウントポイントを作成する
sudo mkdir -p /mnt/photos

# 自動マウントのために/etc/fstabに追加する(UUIDはblkidで確認したドライブのUUIDに置き換える)
echo 'UUID=your-drive-uuid /mnt/photos ext4 defaults 0 2' | sudo tee -a /etc/fstab
sudo mount -a

# .envのUPLOAD_LOCATIONを更新する
UPLOAD_LOCATION=/mnt/photos/immich

.env を編集した後、変更を反映させるためにスタックを再起動する:

docker compose down && docker compose up -d

ビデオトランスコードのハードウェアアクセラレーションを有効にする

デフォルトでは、ImmichはブラウザでのPlayback用にCPUを使ってビデオをトランスコードする——低消費電力マシンでは非常に遅い。Intel iGPUを使えば状況が大きく変わる。VA-APIトランスコードはN100ミニPCのような控えめなハードウェアでも1080pをリアルタイムで処理できる。

docker-compose.ymlimmich-server サービスを見つけて、デバイスマッピングを追加する:

immich-server:
  # ... 既存の設定 ...
  devices:
    - /dev/dri:/dev/dri

次にImmich管理パネルの 管理 → ビデオトランスコード で、ハードウェアアクセラレーションを VA-API に切り替える。NVIDIA GPUも同じパターンだが、先にホストにNVIDIAコンテナランタイムをインストールする必要がある。

Immichをアップデートし続ける

Immichは頻繁に——時には毎週——アップデートをリリースする。アップデートは3つのコマンドで完了し、写真はそのまま残る:

cd ~/immich
docker compose pull
docker compose up -d

Dockerが新しいイメージに入れ替え、コンテナを再起動し、データベースのマイグレーションを自動的に実行する。これで完了だ。さらに一歩進んでWatchtowerでコンテナ更新を自動化することもできる。

ネットワーク外からImmichに安全にアクセスする

リモートアクセスには2つのクリーンな方法がある:

  • Tailscale — スマートフォンとサーバーの両方にインストールする。ポート転送なし、パブリック公開なしで、プライベートなWireGuardトンネル経由でImmichにアクセスできる
  • リバースプロキシ+HTTPS — CaddyまたはNginx Proxy Managerを使って、Let’s Encrypt証明書付きの適切なドメインの背後にImmichを置く

CaddyはHTTPSを驚くほど簡単にしてくれる。Caddyfileにこれを追記するだけだ:

photos.yourdomain.com {
    reverse_proxy localhost:2283
}

Caddyが証明書のプロビジョニングを自動で処理してくれる。DNS AレコードをサーバーのパブリックIPに向け、ポート443を開放すれば完了——自動更新付きの有効なHTTPSが使える。

Google Photosから移行する

既存のライブラリを移行するのは簡単だ。まずGoogle Takeoutエクスポートから始める:

  1. takeout.google.com にアクセスして写真のエクスポートをリクエストする——ほとんどのライブラリでは数GBのアーカイブが生成される
  2. ローカルに展開する——Googleはアルバムや年ごとにフォルダに整理している
  3. Immich CLIを使ってすべてを一括インポートする:
# Immich CLIをインストール
npm install -g @immich/cli

# まずAPIキーを生成する:Immich Web UI → アカウント設定 → APIキー → 新しいAPIキー

# APIキーでログイン
immich login http://your-server-ip:2283 --api-key YOUR_API_KEY_HERE

# エクスポートディレクトリを再帰的にアップロード
immich upload --recursive /path/to/google-photos-export

CLIはインポート時にEXIFの日付を保持する。写真は正しいタイムライン位置に収まる——2019年の旅行写真は今日の日付ではなく2019年に表示される。

長期間スムーズに運用するために

後々の頭痛を防ぐ3つの習慣:

  • ディスク使用量を監視する:写真は静かに積み重なる。シンプルなcronジョブか、マウントが80%の容量に達したときのGrafanaアラートを設定しておくと、深夜2時にディスクがいっぱいになってから気づくよりずっといい
  • PostgreSQLデータベースをバックアップする:写真ファイル自体はただのファイルだが、Immichのメタデータ——アルバム、顔タグ、人物名——はPostgresに保存されている。定期的にバックアップしよう:
docker exec immich_postgres pg_dumpall -U postgres > immich_backup_$(date +%F).sql
  • インポートを確認するまでGoogle Photosはそのままにしておく:クラウドから何かを削除する前に、異なる年代の数十枚の写真をスポットチェックすること

最終的に手に入るもの

この時点で、HomeLabが写真バックアップをエンドツーエンドで処理している。家中のすべてのスマートフォンが自動的にアップロードする。顔、物体、場所、日付で検索できる。アルバムは共有可能だ。動画はブラウザで再生できる。

これらすべてが自分が所有するハードウェア上で動く。サブスクリプションなし。10年分の家族写真を持つ第三者もいない。Google PhotosやiCloudは必須ではなく選択肢になる——そのシフトこそが、自分のインフラを構築することの意義だ。

Share: