Cloudflare tunnelとミニPCを使ってGoogleフォトライクな写真管理サーバをセルフホストする

# 概要

Googleアカウントの容量がいっぱいになっているという怖い警告を沢山頂戴していて夜も眠れません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/7cafc675-5e5d-ffd1-e398-66c99822ca02.png)

そんな訳で半年前に買って箱のまま眠っていたミニPCで写真サーバーをセルフホストしてGoogleフォトからおさらばしたいと思います。

# 前提
- ミニPCのスペック
    - CPUはIntel N100（4コア4スレッド）
    - RAMは16GB
    - SSDは512GB
    - OSはwindows11 proのWSL上のUbuntu 22.04
- メインPCもwindows11です、MacやLinuxの人は適宜読み替えてください
- 写真管理は[Immich](https://github.com/immich-app/immich)で
- Cloudflare tunnelを使ってサーバーを公開
- 取得済みのドメインが必要です（もし持っていない場合、Cloudflareで買うと後の設定が少し簡単に出来るし更新料も安いです）
- ドメインの取得以外**全て無料**で行えます！

# Immichのインストール&セットアップ

写真管理サーバーにはImmichというものを使います。公式のスマホアプリがあり、UIが綺麗で自動バックアップなども付いているそうなのでこれにしました。

公式アプリなどの挙動はデモアカウントで試してみることができます。

https://github.com/immich-app/immich?tab=readme-ov-file#Demo

Docker Composeを使ってとても簡単にインストールできます。せっかちな方向けに必要なスクリプトだけ記しておきますが、もしドキュメントが変わっていたりしても責任は一切持ちません。この操作はサーバー側（ミニPC）で行います。（クライアント側ですることは公式アプリのダウンロードぐらいしかないかも...？）

https://immich.app/docs/install/docker-compose

```shell
mkdir ./immich-app
cd ./immich-app
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
docker compose up -d
```
これでインストールができました。次にブラウザで`http://localhost:2283/`にアクセスして管理者アカウントのセットアップなどを行います。こちらは画面に従えば可能だと思います。

:::note info
初期設定時にストレージテンプレートというものを設定するのですが、こちら個人的にはオンにすることをオススメします。オンにしないとハッシュ値かなんかの訳の分からないフォルダ名に写真が振り分けられます。もちろん後から設定で変える事もできます。
:::


# Cloudflare Tunnelの設定

Cloudflare Tunnelを使ってローカルのサーバーをグローバルに公開します。

下記の記事に従って
- Cloudflareアカウントを作成
- ドメインをCloudflareに追加（Cloudflare経由でドメインを買っている場合、ここのステップがいらない）
- Cloudflare tunnel の作成

を行います。

https://zenn.dev/takajun/articles/fbd783e459c722

基本的には上記の記事で出来るのですが、tunnel作成の部分のUIが少し変わっていそうなので一応説明を付しておきます。

サイドバーの`Zero trust`をクリックして画面が遷移した後のサイドバーで`Netwroks` > `tunnnels`でtunnelの作成&管理を行うことができます。

真ん中の`Add a tunnnel`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/0bb9136e-e924-106c-08ad-ba011c40e7d0.png)

こちらで`Cloudflared`を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/5177e5ed-1712-a2e2-eea8-def104b0235e.png)

こちらで適当なtunnel名を決めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/11f2b445-651e-6c62-b1ab-933d3ebc5bec.png)

サーバー側（ミニPC）のデバイスに合わせて環境を選択すると、インストールのためのスクリプトが表示されます。注意書きにもある通り、tokenはcredentialなので隠してあります。dockerのコマンドを実行する際は、記事に従って`-d`と`--network=host`を付けます。サーバー側でこのコマンドを実行すると下部の`Connectors`に表示されるので、`Next`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/0cc81548-c528-31d3-7b37-fd6b1418006e.png)

上段の設定はお好みでいいと思います。私はimmichというサブドメインを付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/3de156b8-346d-923e-e0b3-5ba066d1300f.png)

これでCloudflare tunnelの設定は終わりです！

# スマホアプリの設定

公式のスマホアプリをダウンロードして、さきほど設定したサーバーのエンドポイントのURLと設定したログイン情報を入力することで使うことができるようになります！
これで晴れてセルフホスト完了～～～～～～～🎉🎉🎉🎉

# Googleフォトからのデータの移行

さて、セルフホストが完了してもやらなければいけないことがいくつか残っています。
まずはGoogleフォトのデータをImmichに移行します。

まずは下記記事に従ってGoogleフォトのデータをエクスポートします。こちらですが、ファイルサイズは50GBで形式はzipにした方が後々の都合上楽です。

https://qiita.com/Aichi_Lover/items/eef3186d4b20c603566d

さて、エクスポートしたデータを[Immich-go](https://github.com/simulot/immich-go)というツールを使って、Immichにインポートします。

下記動画を参考にしてImmichへのインポートを行います。私はこの部分はミニPCではなく自分のメインPCで行っています。

<iframe width="560" height="315" src="https://www.youtube.com/embed/rf25QQaFj0M?si=IrQNzgwm8SvHy3K8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

https://github.com/simulot/immich-go

簡単にやることの説明を行うと、
- [リポジトリ](https://github.com/simulot/immich-go)のreleaseから自分のデバイスに合わせたファイルをダウンロードする
- ダウンロードしたファイルを解凍して、その中にエクスポートしたGoogleフォトのzipファイルを入れる。
- ImmichのAPIキーを発行する。
- Immich-goのコマンドを実行してImmichへインポートする。

の4点です。

:::note alert
場合によっては、zipファイルを解凍した際にWindows defenderに`Trojan:Win32/Wacatac.B!ml`なるトロイの木馬だという誤判定を受けて強制的に実行ファイルを消されてしまいます。defenderから元には戻せますが、不安な場合は代替として[Immich CLI](https://immich.app/docs/features/command-line-interface/)の使用もご検討ください。
:::

Immich-goのコマンドの一例は以下の通りです。細かなオプションなどはリポジトリのREADMEに書いてあります。

:::note warn
もし作業中のPCとサーバー（ミニPC）が同じLAN内にいるのなら、下記コマンドのAPIのURLはCloudflare tunnelで設定したものではなく、`http://{server loacl IP}:2283`にすることをオススメします。Cloudflare tunnelは無料プランでは100MBのファイルサイズ制限があり、それを超えたものは送れません。
:::

```shell
.\immich-go -server={your API endpoint} -key={your API key} upload -create-albums -auto-archive -google-photos takeout-*.zip 
```

実行すると下記のような画面になります。（logにはファイル名などが出ているのでマスクしてあります。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/083561b2-d622-e259-07f6-7b8e3b2919ce.png)

これでしばらく（私の場合は2時間弱）待つとImmichへのインポートが完了します。完了した画面は下記のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/8857683b-a7aa-89ff-7fe2-9b39a141fbed.png)

6つの動画がアップロードに失敗したようですが、この程度ならば手動でアップロードしようと思います。これで移行は完了しました！

# Syncthingによるバックアップ

さて移行も済んだのですが、Googleフォトからの移行によってGoogle様の堅固なサーバーではなくなってしまいました。ImmichのREADMEでも`⚠️ Always follow 3-2-1 backup plan for your precious photos and videos!`と言っているので、メインのPCにもバックアップを取れるようにしておきます。

下記記事に従って、サーバー（ミニPC）のUbuntuとメインPCのWindowsにSyncthingを入れて同期を行うようにします。

https://qiita.com/MasanoriIwakura/items/555f3bc0f4f322c63cdf

こちらも記事に従えば可能だと思いますが、簡単にやることを説明すると、
- 同期元と同期先にSyncthingをインストール
- 2台のデバイスを接続
- 同期元で同期したいフォルダを選択（私の場合は`~/immich-app/library/library/admin`でした。細かい内容は[Immichのドキュメント](https://immich.app/docs/administration/backup-and-restore#filesystem)をご確認ください）
- 同期先に同期するフォルダを追加（同期元と同じフォルダIDを指定する）
- 同期フォルダの編集から同期するデバイスを選択

の5点です。

:::note info
同期元で同期するフォルダを選択する際に、パーミッションがないため出来ない的なことが言われる事があります。その場合は、同期したフォルダの直下でsudoなどで`.stfolder`というフォルダを直接作成すると上手くいきます。
:::


3-2-1ルールには程遠いですが、やらないよりは幾分かマシでしょう。

# 終わりに

さてここまで色々やったところで、Googleアカウントの容量の値段を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863326/f0c2c205-58c5-0fe1-fcff-ade02a7c86f6.png)

なんと100GBに容量を増やすのにたったの￥2,500/年です。私の場合はドメインの維持とミニPC代だけで計算してもGoogleに課金するのが割高になるまで20年くらいかかります。しかもこちらは、ブレーカーが落ちてサーバーが死ぬみたいなことは（滅多に）起こりません。でっかい企業ってやっぱりすごいんですね。