はじめに
最近流行っているおうち NAS を作ろうと思い、自宅サーバーを兼ねるために Proxmox を使用し、色々構築することにしました。
その中でも今回はフォトアルバムの構築に焦点を当てて行きたいと思います。
フォトアルバムといえば Google Photos ですが、容量制限があり課金も必要になります。
私は課金をしたくないので、「NAS も作るしセルフホスト型のフォトアルバムも作ろう!」と考えました。
調べたところ、OSS の Google Photos 代替として名高い Immich があるようなので、これを使って構築してみました。
また、ROCm を使用するために iGPU をパススルーする手順も併せて紹介してみます。
この記事では、ZFS の設定 → LXC コンテナ作成 (バインドマウント/権限設定含む) → GPU パススルー → Immich デプロイ まで、一連の流れを詳しく書き残しておきます。結構長くなりますが、ぜひ参考にしてみてください!
目次
-
ZFS ディレクトリ作成
1-1. データセット作成
1-2. 圧縮の有効化 (容量節約)
1-3. ACL (アクセス制御) を有効化
1-4. 容量上限の設定 (クォータ) -
LXC コンテナの作成と設定
2-1. ホスト側の準備: IOMMU 有効化
2-2. ホスト側の準備: ROCm ドライバーインストール
2-3. デバイスファイルの権限設定 (udev ルール)
2-4. subuid/subgid の設定
2-5. LXC コンテナの作成
2-6. LXC 設定ファイルの編集 -
コンテナ内の設定
3-1. 基本パッケージのインストール
3-2. ROCm のインストール (コンテナ内)
3-3. Docker のインストール -
Immich をデプロイする!
4-1. ディレクトリの準備
4-2. .env ファイルの作成
4-3. docker-compose.yml の作成
4-4. 起動! -
Immich の初期設定
5-1. GPU 動作確認 -
メモ
6-1. Reverse Proxy (NPM) を使っている場合
環境
- OS: Proxmox VE 8.x
- Container: Ubuntu 24.04 (LXC, Unprivileged)
- GPU: AMD Radeon 780M (Ryzen 7 255)
- Storage: ZFS RAIDZ2 (6 TB HDD x 5)
- Middleware: Immich (Docker)
RAIDZ2 は RAID6 相当で、2 台まで故障しても復旧可能。5 台で構成すると実効容量は約 18TB (6TB × 3)
1. ZFS ディレクトリ作成
まずは Proxmox のホスト側で、写真や動画を保存する「ディレクトリ」を作る。
ZFS のデータセットを使うことで、圧縮やクォータ設定が簡単に行える。
1.1 データセット作成
# Proxmoxホストにrootでログイン
ssh root@YOUR_PROXMOX_IP
# Immich用のデータセット作成
zfs create tank/immich
1.2 圧縮の有効化 (容量節約)
# 圧縮を有効化
zfs set compression=lz4 tank/immich
1.3 ACL (アクセス制御) を有効化
LXC (非特権コンテナ) から読み書きできるようにするため、ACL を有効にしておく。
# ACLを有効化
zfs set acltype=posixacl tank/immich
zfs set xattr=sa tank/immich
1.4 容量上限の設定 (クォータ)
無制限に使われると困るので、念のためクォータを設定しておく。
# 容量制限 (例: 5TB)
zfs set quota=5T tank/immich
# 設定確認
zfs list -o name,used,quota,available tank/immich
出力例はこんな感じになるはず:
NAME USED QUOTA AVAIL
tank/immich 100G 5T 4.9T
2. LXC コンテナの作成と設定
次に、Ubuntu 24.04 の LXC コンテナを作成する。
非特権コンテナ (Unprivileged) で作成し、GPU パススルーのために少し設定が必要。
2.1 IOMMU 有効化
AMD の iGPU をパススルーするために、GRUB の設定を変更する。
vi /etc/default/grub
# 以下の行を変更
GRUB_CMDLINE_LINUX_DEFAULT="quiet iommu=pt amd_iommu=on"
# 変更したら適用して再起動
update-grub
reboot
# 再起動後、デバイスファイルを確認
ls -la /dev/dri/
# card0, renderD128 が表示されることを確認
ls -la /dev/kfd
# kfd デバイスが存在することを確認
2.2 ROCm ドライバーインストール
GPU を使うために ROCm ドライバーをホストにインストールする。
ROCm のバージョンは定期的に更新されるため、最新バージョンは AMD 公式リポジトリ で確認すること。
# 1. ROCmリポジトリの追加
# 最新バージョンは公式リポジトリで確認
wget https://repo.radeon.com/amdgpu-install/6.4.3/ubuntu/noble/amdgpu-install_6.4.60403-1_all.deb
apt install ./amdgpu-install_6.4.60403-1_all.deb
# 2. 必要なパッケージのインストール
apt update
apt install "linux-headers-$(uname -r)" "linux-modules-extra-$(uname -r)"
apt install amdgpu-dkms
# 3. ドライバーが読み込まれているか確認
lsmod | grep amdgpu
# 出力があれば正常
2.3 デバイスファイルの権限設定
コンテナから GPU デバイスにアクセスできるように、ホスト側で権限を設定する。
# udevルールファイルの作成
cat > /etc/udev/rules.d/99-gpu-chmod666.rules << 'EOF'
# AMD GPU デバイスの権限設定
KERNEL=="renderD128", MODE="0666"
KERNEL=="kfd", MODE="0666", GROUP="render"
KERNEL=="card0", MODE="0666"
EOF
# ルールの適用
udevadm control --reload-rules && udevadm trigger
# 権限の確認
ls -la /dev/dri/
# 出力例:
# crw-rw-rw- 1 root video 226, 0 card0
# crw-rw-rw- 1 root render 226, 128 renderD128
2.4 subuid/subgid の設定
非特権コンテナでは、UID/GID マッピングが必要。
# /etc/subuidの確認・編集
cat /etc/subuid
# 以下のような内容になっていればOK
# root:100000:65536
# /etc/subgidの確認・編集
cat /etc/subgid
# 以下のような内容になっていればOK
# root:100000:65536
video グループ (44) と render グループ (104) を直接マッピングするため、追加設定が必要な場合がある。
2.5 LXC コンテナの作成
Proxmox Web UI でコンテナを作成する。
作成手順は省略する。
参考 (宣伝):
2.6 LXC 設定ファイルの編集
コンテナ作成後、設定ファイルを直接編集して GPU パススルーとバインドマウントを追加する。
vi /etc/pve/lxc/100.conf
以下の内容を追加・編集:
# 標準的な設定はお好みで。
arch: amd64
cores: 4
features: nesting=1,keyctl=1
hostname: immich-container
memory: 16384
swap: 8192
net0: name=eth0,bridge=vmbr0,firewall=1,gw=192.168.1.1,hwaddr=BC:24:11:26:5C:7F,ip=192.168.1.100/24,ip6=dhcp,type=veth
onboot: 1
ostype: ubuntu
rootfs: local-lvm:vm-100-disk-0,size=192G
unprivileged: 1
# GPU Device Passthrough (Proxmox VE 8.1+ の新方式)
dev0: /dev/kfd,gid=104,mode=0666
dev1: /dev/dri/card0,gid=44,mode=0666
dev2: /dev/dri/renderD128,gid=104,mode=0666
# バインドマウント (ZFSデータセットをコンテナにマウント)
mp0: /tank/immich,mp=/mnt/immich,acl=1
# UID/GIDマッピング (GPUパススルー用)
lxc.idmap: u 0 100000 65536
lxc.idmap: g 0 100000 44
lxc.idmap: g 44 44 1
lxc.idmap: g 45 100045 59
lxc.idmap: g 104 104 1
lxc.idmap: g 105 100105 65431
UID/GID マッピングの解説
非特権コンテナでは、コンテナ内の UID 0 (root) がホストの UID 100000 にマッピングされる。
video グループ (44) と render グループ (104) を直接マッピングすることで、コンテナから GPU デバイスにアクセスできるようになる。
3. コンテナ内の設定
コンテナを起動して、中に入って設定を行う。
# コンテナの起動
pct start 100
# コンテナに接続
pct enter 100
3.1 基本パッケージのインストール
apt update && apt upgrade -y
apt install -y wget curl vi build-essential ca-certificates gnupg
3.2 ROCm のインストール (コンテナ内)
コンテナ内にも ROCm をインストールする。ただし、DKMS は不要 (カーネルモジュールはホスト側で動くため)。
RDNA3 (Ryzen 7000/8000 系) の注意点
公式にはサポートされていない場合があるため、環境変数 HSA_OVERRIDE_GFX_VERSION=11.0.0 が必須。これがないと ROCm が動かないので注意。
また、バージョンについても最新のものを参照すること。
# ROCmリポジトリの追加
wget https://repo.radeon.com/amdgpu-install/6.4.3/ubuntu/noble/amdgpu-install_6.4.60403-1_all.deb
apt install ./amdgpu-install_6.4.60403-1_all.deb
# ROCmインストール (DKMSなし)
amdgpu-install --usecase=rocm --no-dkms
# ユーザーをグループに追加
usermod -aG video root
usermod -aG render root
環境変数の設定
# RDNA3 (780M) を動かすための魔法の呪文 (AI に聞いたら出してきたやつ)
echo 'export HSA_OVERRIDE_GFX_VERSION=11.0.0' >> ~/.bashrc
echo 'export PATH=$PATH:/opt/rocm-6.4.3/bin' >> ~/.bashrc
source ~/.bashrc
動作確認
# ROCm情報の表示
rocminfo | grep "Marketing Name"
# 出力例: Marketing Name: AMD Radeon 780M
# OpenCLデバイスの確認 (オプション)
apt install -y mesa-opencl-icd clinfo
clinfo | grep "Device Name"
# 出力例: Device Name: gfx1103
3.3 Docker のインストール
Immich は Docker で動かすので、Docker をインストールする。
# Docker公式GPGキーを追加
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
# リポジトリを追加
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# インストール
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 動作確認
docker --version
docker compose version
4. Immich をデプロイする!
いよいよ本題の Immich を構築していく。
4.1 ディレクトリの準備
mkdir -p /opt/immich/postgres
4.2 .env ファイルの作成
vi /opt/immich/.env
以下の内容を記述:
# 必須設定
DB_USERNAME=postgres
DB_PASSWORD=YOUR_SECURE_PASSWORD_HERE
DB_DATABASE_NAME=immich
# パス設定
UPLOAD_LOCATION=/mnt/immich/library
DB_DATA_LOCATION=/opt/immich/postgres
# バージョン
IMMICH_VERSION=release
4.3 docker-compose.yml の作成
vi /opt/immich/docker-compose.yml
以下の内容を記述:
name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
environment:
DB_HOSTNAME: immich_postgres
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE_NAME: ${DB_DATABASE_NAME}
REDIS_HOSTNAME: immich_redis
ports:
- 2283:2283
depends_on:
- redis
- database
restart: always
immich-machine-learning:
container_name: immich_machine_learning
# 重要: ROCm対応のイメージタグを指定!
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}-rocm
# GPUデバイスのマウント
devices:
- /dev/dri:/dev/dri
- /dev/kfd:/dev/kfd
# videoグループとrenderグループへの追加 (GPUアクセスに必要)
group_add:
- video
- render
volumes:
- model-cache:/cache
environment:
DB_HOSTNAME: immich_postgres
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_DATABASE_NAME: ${DB_DATABASE_NAME}
REDIS_HOSTNAME: immich_redis
# モデルのタイムアウト設定 (GPUアイドル時の電力消費対策)
MACHINE_LEARNING_MODEL_TTL: "300"
restart: always
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm
restart: always
database:
container_name: immich_postgres
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: '--data-checksums'
volumes:
- ${DB_DATA_LOCATION}:/var/lib/postgresql/data
restart: always
volumes:
model-cache:
4.4 起動!
cd /opt/immich
docker compose up -d
初回起動は Docker イメージのダウンロードがあるので少し時間がかかる。
# 起動状況の確認
docker compose ps
# ログの確認
docker compose logs -f
5. Immich の初期設定
ブラウザから http://192.168.1.100:2283 にアクセスする。
-
管理者アカウントを作成する
初回アクセス時に管理者アカウントの作成を求められる。 -
設定の確認
Administration→Settingsから各種設定を確認・変更できる。
GPU 動作確認
GPU が正しく認識されているかは、ジョブを実行して immich-machine-learning コンテナのログを見て確認する。
docker logs -f immich_machine_learning
ログに HSA や ROCm 関連のエラーが出ていなければ成功!
CPU だと数十分かかる顔認識処理が、GPU だと一瞬で終わる。これがハードウェアアクセラレーションの力...!
メモ
Reverse Proxy (NPM) を使っている場合
Nginx Proxy Manager などのリバースプロキシを使用している場合は、大きなファイルのアップロードのために client_max_body_size の設定が必要。
Advanced 設定に以下を追加:
client_max_body_size 50000M;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
おわり
構築はかなり大変 (特にパススルー/権限周り) でしたが、今では快適に使えています。
また、月額料金もかからず大容量の領域を使用できるため非常に満足です。
スマホアプリの出来も非常によく、バックグラウンドでの自動アップロードも良い感じで良きです。
アカウント制御のため、家族などに共有してやれるのも良いポイントだと思います。
Google Photos 難民の方、Proxmox で「おうちクラウド」始めてみてはいかがでしょうか?
気になった方はぜひやってみてください!
それでは良き Proxmox & Immich ライフを!
参考
