はじめに:脱Google Photos。最強の自前写真サーバーを構築する
スマートフォンのカメラが高画質化するにつれ、あっという間に底をつくクラウドストレージの容量。サブスクリプション費用を払い続けるループから抜け出すため、完全自前の写真バックアップサーバーを構築するベストプラクティスを解説します。


3行まとめ
- 余ってるPCやMiniPCを使い、おうちGooglePhotoを構築します。
- SSD、SSD+SSD、SSD+HDDの3パターンの構成を想定した記事です。
- Ubuntu Serverに、CasaOSとImmich、画像アップロード時に自動圧縮をするImmich Upload Optimizerを導入します。
本記事では、Linuxやサーバー構築が初めての初心者の方でも絶対に迷わずに完成できるよう、画面の遷移から入力するコマンドまで、すべての手順を1つも省略せずに解説します。記事の通りに進めれば、Google Photosの「保存容量の節約モード」と全く同じ環境がご自宅に完成します。
前提:選べる3つのハードウェア構成
サーバーとなるPCは、ご自身の予算や余っている機材に合わせて以下の3パターンから選択できます。どの構成でも本記事の手順で構築可能です。

- 【推奨】ミニPC + デュアルSSD構成(例: TRIGKEY N95搭載機など)
OS用に256GB、写真データ用に2TBのSSDを搭載する構成。OSとデータ領域を物理的に分けることで、将来的な拡張や復旧が容易になります。第12世代のN95などは、QSV(ハードウェアエンコード)が強力に効くため超省電力かつ爆速です。 - 【初心者向け】シングルSSD構成(例: 1TB×1枚)
OSも写真データも1つのSSDに保存する構成。面倒な「ディスクのマウント作業」をスキップできるため、最も簡単に構築できます。 - 【エコ運用】古いPCの再利用(OS用SSD + データ用HDD)
余っている旧型PCを活用する構成。OSをSSDに入れてシステムを高速化し、大容量の写真データは安価なHDDに保存します。設定手順は「パターン1」と全く同じです。
事前準備
まずは、OSをインストールするための機材とUSBメモリを準備します。
- 容量8GB以上の空のUSBメモリ
- USBキーボード
- HDMIケーブルとモニター
- 有線LANケーブル
(※Wi-Fi設定はインストール中に煩雑になるため、初期構築時はルーターから有線LANで直接繋ぐことを強く推奨します)
インストール用USBメモリの作成
- 用意したUSBメモリを、普段使っているメインPCに挿します。
- Ubuntu公式サイトにアクセスし、「Download Ubuntu Server 24.04 LTS」をクリックしてISOファイル(ディスクイメージ)をダウンロードします。
- USB書き込みソフトRufusをダウンロードして起動します。
- Rufusの画面で「デバイス」にUSBメモリを、「ブートの種類」で先ほどダウンロードしたISOファイルを選択し、「スタート」を押します。
(※警告が出ても「OK」で進めてください。USBの中身はすべて消去され、専用のインストール用メディアが完成します)
ステップ1:Ubuntu Serverの完全インストール手順
Windows等のデスクトップOSはリソースを大きく消費するため、今回はマウス操作の画面を持たない「Ubuntu Server」を採用し、サーバーの全パワーを写真処理に回します。
USBメモリからの起動
- サーバー用PCに作成したUSBメモリ、キーボード、モニター、LANケーブル、電源をすべて接続します。
- 電源ボタンを押し、直後からキーボードの
F7キー(またはDeleteキー等、メーカーによる)をトントントンと連続で叩きます。 - 青い画面(BIOS)または「Boot Menu」が表示されたら、起動デバイスのリストから「UEFI: (USBメモリのメーカー名)」を選択して
Enterを押します。 - 黒い画面に白い文字でメニューが出たら、一番上の 「Try or Install Ubuntu Server」 を選んで
Enterを押します。
インストーラーの基本設定
画面に文字がズラッと流れ、しばらくするとインストーラーが起動します。
【重要】ここから先はマウスが使えません。キーボードの「矢印キー」「Tabキー」「スペースキー」「Enterキー」のみで操作します。
- Choose your language(言語の罠):
必ず English を選んでEnterを押します。
※重要: ここで親切心から日本語を選ぶと、後で黒い画面(CUI)で操作する際に文字化け(◆◆◆のような表示)との戦いになります。サーバー構築の鉄則としてシステム言語は英語にします。 - Keyboard configuration(キーボード):
「Layout」に合わせてEnterを押し、リストからJapaneseを選択。同様に「Variant」もJapaneseに変更し、一番下の「Done」を選んでEnter。 - Choose type of install(種類):
デフォルトの「Ubuntu Server」が選ばれている状態で「Done」を選んでEnter。 - Network connections(ネットワーク):
有線LANが繋がっていれば、自動で192.168.x.xのようなIPアドレスが取得・表示されます。このIPアドレスを必ずスマホで写真を撮るかメモしてください。確認したら「Done」でEnter。 - Configure proxy / Ubuntu archive mirror:
何も変更せず、どちらもデフォルトのまま「Done」でEnter。
ストレージ・アカウント・SSH設定(最も慎重に行うステップ)
- Storage configuration(ストレージ構成の要):
「Use an entire disk」にチェック([X])が入っていることを確認します。
Choose the disk to install to: デュアルドライブ構成の場合、ここでOS用の小さな容量のディスク(256GBなど)を確実に選択してください。増設した大容量のデータ用ディスクを選ばないよう注意!
※おすすめ設定:「Set up this disk as an LVM group」のチェックはスペースキーで外す(空白にする)と、構成がシンプルになりトラブルが減ります。
確認したら「Done」→フォーマット警告が出たら「Continue」でEnter。 - Profile setup(ユーザー設定):
以下の項目を入力し、「Done」でEnter。
・Your name: あなたの名前(任意)
・Your server’s name:immich-server等(サーバーの名前)
・Pick a username:admin等は避け、ご自身の名前にするのが安全です。
・Choose a password / Confirm your password: 任意のパスワードを入力 - Upgrade to Ubuntu Pro:
デフォルトの「Skip for now」のまま「Continue」でEnter。 - SSH Setup(【超重要】):
「Install OpenSSH server」の項目に合わせ、スペースキーを押して[X]マークを必ずつけます。これを行わないと後から遠隔操作できなくなります。「Done」でEnter。 - Featured Server Snaps:
DockerやNextcloudなどのパッケージリストが出ますが、ここでは何も選ばずそのまま「Done」でEnter。(後でCasaOS経由で綺麗に入れた方が圧倒的に管理が楽です)。
インストールが開始されます。画面下部に [ Reboot Now ] という文字が表示されるまで数分待ち、表示されたら選択して Enter を押します。
Please remove the installation medium, then press ENTER:
画面に上記のように表示されたら、USBメモリを本体から引っこ抜いて、Enter キーを押します。再起動がかかり、ズラズラと文字が流れた後、以下のようなプロンプトが出ればOSのインストールは完璧に成功です!
immich-server login:
サーバー用PCからモニターやキーボードを外し、ここから先は普段お使いのメインPCから遠隔操作を行います。
ステップ2:SSH接続とシステムの最新化
メインPCのターミナル(WindowsならコマンドプロンプトやPowerShell、Macならターミナルアプリ)を開き、以下のコマンドを入力します。
※ hoge は先ほど作成したユーザー名、192.168.x.x はメモしたサーバーのIPアドレスに読み替えてください。
# サーバーへ遠隔接続する
ssh hoge@192.168.x.x【初心者が不安になるポイント解説】
初回接続時のみ Are you sure you want to continue connecting (yes/no/[fingerprint])? と聞かれます。これは「本当にこのサーバーを信用して繋ぎますか?」という確認なので、キーボードで yes と入力して Enter を押してください。
次にパスワードを聞かれます。
パスワードをキーボードで叩いても、画面には一切文字(***など)が表示されませんが、内部的にはしっかり入力されています。気にせず打ち込み、Enter を押してください。
無事にログインできたら、サーバーの中身を最新状態にアップデートします。以下のコマンドを1行ずつコピペして実行してください。
sudo apt update
sudo apt upgrade -yステップ3:データ用ドライブのマウント(※パターン1・3のみ)
※【シングルSSD構成(パターン2)の方】はこのステップを完全に飛ばして「ステップ4」へ進んでください。
デュアルドライブ構成の場合、増設した2TB等のSSD(またはHDD)をOSに認識させ、/mnt/data というフォルダとして使えるように接続(マウント)します。
# 1. 接続されているディスクの一覧を確認します
lsblk結果の中に、nvme0n1 や sda、sdb といった名前で、容量が 2TB(1.8Tなどと表示されます)のディスクがあるのを見つけてください。ここでは例として nvme0n1 だったとして進めます。ご自身の環境に合わせて適宜コマンド内の名前を書き換えてください。
# 2. ディスクをLinux用の「ext4」形式でフォーマットします(中身はすべて消えます)
# 以下の2行を1行ずつ実行します
sudo parted /dev/nvme0n1 --script mklabel gpt mkpart primary ext4 0% 100%
sudo mkfs.ext4 /dev/nvme0n1p1
# 3. /mnt/data という名前の接続口(フォルダ)を作成し、そこにディスクを合体させます
sudo mkdir -p /mnt/data
sudo mount /dev/nvme0n1p1 /mnt/data
# 4. 今ログインしているユーザー(ここではhoge)が自由に読み書きできるように権限を変更します
sudo chown -R hoge:hoge /mnt/data
# 5. サーバーを再起動しても自動でマウントされるように設定ファイル(fstab)に書き込みます
sudo cp /etc/fstab /etc/fstab.bak
echo "UUID=$(sudo blkid -s UUID -o value /dev/nvme0n1p1) /mnt/data ext4 defaults 0 2" | sudo tee -a /etc/fstab
# 6. エラーが出ないかテストします(何も表示されなければ成功です!)
sudo mount -aステップ4:ブラウザ管理ツール「CasaOS」の導入
黒い画面でのコマンド操作を最小限にするため、ブラウザからマウス操作でサーバーを管理できる「CasaOS」をインストールします。以下のコマンド1行をコピペして実行するだけです。
curl -fsSL https://get.casaos.io | sudo bash数分待って画面に CasaOS is running... と表示されればインストール完了です。
メインPCのブラウザ(Chromeなど)を開き、アドレスバーに 192.168.x.x (サーバーのIPアドレス)を入力します。CasaOSの歓迎画面が出るので、初期アカウント(ユーザー名とパスワード)を作成してダッシュボードを開いておいてください。
ステップ5:Immichの構築準備とファイルの取得
いよいよコアとなる写真管理アプリ「Immich」の構築です。再びターミナル(黒い画面)に戻り、データを保存するベースフォルダを作成し、公式から設計図を取得します。
※構成に応じてどちらか片方だけ!
# 【パターン1・3(デュアルドライブ)の場合】
sudo mkdir -p /mnt/data/immich
cd /mnt/data/immich# 【パターン2(シングルSSD)の場合】
mkdir -p ~/immich
cd ~/immich移動できたら、以下の2行を1行ずつ実行して、公式の設定ファイルをダウンロードします。
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ステップ6:保存先の設定(.env の編集)
ダウンロードした環境変数ファイル(.env)を編集し、実際の写真データが保存されるパスを指定します。ターミナル上でテキストエディタ「nano」を使います。
sudo nano .env黒い画面に文字がいっぱい表示されるエディタが開きます。十字キーで移動して、ご自身のハードウェア構成に合わせて以下の2箇所を書き換えます。
※構成に応じてどちらか片方だけ!
# --- パターン1・3(デュアルドライブ)の場合 ---
【変更前】
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
【変更後】
UPLOAD_LOCATION=/mnt/data/immich/library
DB_DATA_LOCATION=/mnt/data/immich/postgres# --- パターン2(シングルSSD)の場合 ---
【変更前】
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
【変更後】(※hogeはご自身のユーザー名にしてください)
UPLOAD_LOCATION=/home/hoge/immich/library
DB_DATA_LOCATION=/home/hoge/immich/postgres【保存して閉じる操作(nano共通)】
1. キーボードの Ctrl を押しながら O(オー)を押す。
2. 画面下部にファイル名が表示されたら、そのまま Enter を押す。
3. Ctrl を押しながら X を押してエディタを閉じる。
ステップ7:アーキテクチャの魔改造(docker-compose.yml)
ここが本記事の最大のキモです。Immichの公式設計図を編集し、動画変換を爆速にする「QSV有効化」と、画質を保ったまま容量を激減させる「Upload Optimizer」の追加を行います。
sudo nano docker-compose.yml修正箇所1:デバイスのパススルーと既存ポートの閉鎖
十字キーで下にスクロールし、immich-server: と immich-machine-learning: を探します。それぞれに devices: を追記します。また、immich-server: の下にある ports: は行頭に # をつけて無効化(コメントアウト)します。
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
# ↓ここから2行を追加(行の左側の空白の数を上と揃えてください)
devices:
- /dev/dri:/dev/dri
# ↓portsの2行は先頭に # をつけてコメントアウトします
# ports:
# - "2283:2283"
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
# ↓ここから2行を追加
devices:
- /dev/dri:/dev/dri修正箇所2:Optimizerの追加
ファイルの一番下付近までスクロールすると volumes: という行があります。その「すぐ上の空行」に、以下のブロックを丸ごとコピー&ペーストで追記します。一番左の空白(インデント)がズレないように注意してください。
# ↓↓↓ ここから追記 ↓↓↓
immich-upload-optimizer:
container_name: immich_upload_optimizer
image: ghcr.io/miguelangel-nubla/immich-upload-optimizer:latest
ports:
- "2283:2283"
environment:
- IUO_UPSTREAM=http://immich-server:2283
depends_on:
- immich-server
restart: always
# ↑↑↑ ここまで追記 ↑↑↑
volumes: # ←この行の「すぐ上」に追記する
model-cache:【技術Tips】
このOptimizerは、標準設定(デフォルト)のまま動かすのが最も安定して優秀です。自動で画質80の最適化が行われます。自作のタスクファイルを読み込ませると拡張子エラーでアップロードできなくなるため、上記のスッキリした記述が最適解となります。
追記できたら、先ほどと同じように Ctrl+O → Enter → Ctrl+X で保存して閉じます。
ステップ8:システム起動と最終セットアップ
準備がすべて整いました。以下のコマンドを実行してシステム全体を起動します(ダウンロードに数分かかります)。最後に Started と並べば成功です!
sudo docker compose up -d1. CasaOSアイコンのリンク修正
ブラウザでCasaOS(http://192.168.x.x)を開きます。ポートをOptimizerに変更したため、そのままImmichアイコンをクリックしてもエラーになります。
アイコン右上の「⋮(3点リーダー)」→「設定(Settings)」を開き、少し下にある「Web UI ポート」の欄に 2283 を入力して右上(または下部)の「保存」を押してください。これでアイコンから一発でアクセス可能になります。
2. ハードウェアアクセラレーションの有効化
ブラウザで http://192.168.x.x:2283 を開き、「Welcome to Immich!」の画面から初期の管理者アカウントを作成します。
ログイン後、右上のアイコンから「管理(Administration)」→「設定(Settings)」へ進み、以下の2つを設定します。
- Video Transcoding: 開いて Hardware Acceleration を
Quick Sync Video(古いPCならVAAPI)に変更し、保存(Save)を押す。 - Machine Learning: 開いて Hardware Acceleration を
OpenVINOに変更し、保存(Save)を押す。
完成!
以上で、「見た目の画質は保ちながらファイルサイズが数MBから数百KBに激減する、完全自前版Google Photos」の構築がすべて完了しました!お疲れ様でした!
スマートフォンの専用アプリ(iOS/Android対応)から「バックグラウンドアップロード」を設定すれば、日々の写真が自動的に最適化され、ご自身のサーバーに蓄積されていきます。
大容量ストレージと省電力サーバーを組み合わせたこのインフラ環境で、容量を気にせず一生分の写真を保存できる最強の自宅サーバーライフをお楽しみください。
追記:immich-cliを使って写真を一気にドカドカと転送する

準備1:Immichの「APIキー」を発行する
CLIツールがサーバーに安全に接続するための「合鍵」を作ります。
- ブラウザでImmich(http://192.168.x.x:2283)を開き、ログインします。
- 右上のプロフィールアイコン(または歯車)から 「アカウント設定(Account Settings)」 を開きます。
- 左側のメニューから 「APIキー(API Keys)」 を選びます。
- 「新しいAPIキー(New API Key)」 ボタンを押し、名前(pc-upload など何でもOK)をつけて作成します。
- 長い文字列(APIキー)が表示されるので、コピーしてメモ帳などに貼り付けておきます。(※この画面を閉じると二度と見られなくなるので注意してください)
準備2:Windowsに「Node.js」を入れる
CLIツールを動かすためのエンジン(Node.js)をWindowsにインストールします。
(※すでにインストール済みの場合は飛ばしてOKです)
- Node.jsの公式サイト にアクセスし、「LTS(推奨版)」をダウンロードしてインストールします。
- インストール中の設定はすべて「Next(次へ)」で進めて問題ありません。
準備3:ターミナルから爆速アップロード!
Windowsの「コマンドプロンプト」または「PowerShell」を開き、以下のコマンドを順番に実行していきます。
① CLIツールのインストール
npm install -g @immich/cli(数秒〜数十秒でインストールが完了します)
② サーバーへのログイン(合鍵の登録)
先ほどメモしたAPIキーと、サーバーのIPアドレスを使います。※URLの最後に /api をつけるのを絶対に忘れないでください!
immich login http://192.168.x.x:2283/api 自分のAPIキーをここにペースト(例: immich login http://192.168.0.70:2283/api a1b2c3d4e5...)
Successと表示されれば接続成功です。
③ フォルダの一括アップロード
いよいよデスクトップのフォルダを流し込みます。コマンドラインに immich upload -d (最後に半角スペース)まで入力したら、デスクトップにあるそのフォルダを、黒い画面(コマンドプロンプト)に直接ドラッグ&ドロップしてみてください。自動でフォルダのパスが入力されます。
最後に --recursive(フォルダの中のフォルダも全部探す、という指示)をつけてEnterを押します。
# 実行するコマンドのイメージ
immich upload --recursive "C:\Users\ユーザー名\Desktop\写真フォルダ"あとは全自動で終わるのを待つだけです!
コマンドを実行すると、画面に緑色のプログレスバーが表示され、PCのパワーを使って複数の写真を猛スピードで並列アップロードし始めます。
- 重複スキップ: すでにブラウザでアップロード済みの写真は Skipped となり一瞬で飛ばされます。
- エラー耐性: 万が一ネットワークが切れたりPCがスリープして止まってしまっても、もう一度同じコマンド(③)を叩けば、足りない分だけを賢く判断して再開してくれます。
ブラウザのフリーズに怯えることなく、コマンドプロンプト画面を眺めながらコーヒーでも飲んでお待ちください。無事に一括転送がスタートするか、ぜひ試してみてください!
追記)オプションリスト
Options:
-r, --recursive Recursive (default: false, env: IMMICH_RECURSIVE)
-i, --ignore <pattern> Pattern to ignore (env: IMMICH_IGNORE_PATHS)
-h, --skip-hash Don't hash files before upload (default: false, env: IMMICH_SKIP_HASH)
-H, --include-hidden Include hidden folders (default: false, env: IMMICH_INCLUDE_HIDDEN)
-a, --album Automatically create albums based on folder name (default: false, env: IMMICH_AUTO_CREATE_ALBUM)
-A, --album-name <name> Add all assets to specified album (env: IMMICH_ALBUM_NAME)
-n, --dry-run Don't perform any actions, just show what will be done (default: false, env: IMMICH_DRY_RUN)
-c, --concurrency <number> Number of assets to upload at the same time (default: 4, env: IMMICH_UPLOAD_CONCURRENCY)
-j, --json-output Output detailed information in json format (default: false, env: IMMICH_JSON_OUTPUT)
--delete Delete local assets after upload (env: IMMICH_DELETE_ASSETS)
--delete-duplicates Delete local assets that are duplicates (already exist on server) (env: IMMICH_DELETE_DUPLICATES)
--no-progress Hide progress bars (env: IMMICH_PROGRESS_BAR)
--watch Watch for changes and upload automatically (default: false, env: IMMICH_WATCH_CHANGES)
--help display help for commandオプション:
-r, --recursive 再帰的に処理します (デフォルト: false、環境変数: IMMICH_RECURSIVE)
-i, --ignore <pattern> 無視するパターン (環境変数: IMMICH_IGNORE_PATHS)
-h, --skip-hash アップロード前にファイルをハッシュ化しません (デフォルト: false、環境変数: IMMICH_SKIP_HASH)
-H, --include-hidden 隠しフォルダを含めます (デフォルト: false、環境変数: IMMICH_INCLUDE_HIDDEN)
-a, --album フォルダ名に基づいてアルバムを自動的に作成します (デフォルト: false、環境変数: IMMICH_AUTO_CREATE_ALBUM)
-A, --album-name <name> 指定したアルバムにすべてのアセットを追加します (環境変数: IMMICH_ALBUM_NAME)
-n, --dry-run 何も実行せず、実行される内容のみを表示します (デフォルト: false、環境変数: IMMICH_DRY_RUN)
-c, --concurrency <number> 同時にアップロードするアセットの数 (デフォルト: 4、環境変数: IMMICH_UPLOAD_CONCURRENCY)
-j, --json-output 詳細情報を JSON 形式で出力します (デフォルト: false、環境変数: IMMICH_JSON_OUTPUT)
--delete アップロード後にローカルアセットを削除します (環境変数: IMMICH_DELETE_ASSETS)
--delete-duplicates 重複しているローカルアセット (既にサーバー上に存在するアセット) を削除します (環境変数: IMMICH_DELETE_DUPLICATES)
--no-progress プログレスバーを非表示にします (環境変数: IMMICH_PROGRESS_BAR)
--watch 変更を監視し、自動的にアップロードします (デフォルト: false、環境変数: IMMICH_WATCH_CHANGES)
--help コマンドのヘルプを表示します私は写真を保存場所からローカルにコピーして転送しているので、「再帰的に処理」「アップロード後にローカルアセットを削除」「重複しているローカルアセット (既にサーバー上に存在するアセット) を削除」をいれて下記のオプションで実行しています。
# 実行するコマンドのイメージ
immich upload --recursive --delete --delete-duplicates "C:\Users\ユーザー名\Desktop\写真フォルダ"※この記事は私の作業メモをGeminiにまとめさせました。