Featured image of post セルフホストGoogleフォトを構築する

セルフホストGoogleフォトを構築する

この記事は、大阪工業大学 Advent Calendar 2024の 10 日目の記事です。

はじめに

みなさん、写真の管理はどのようにしていますか? ローカルストレージやクラウドストレージを利用したり、色々挙げられると思います。
今回紹介するのは、Google フォトのような使い勝手をそのままに、自宅でセルフホストできる写真管理システムです。

immich

Self-hosted photo and video management solution

デモを触ってもらうと分かりますが、UI は Google フォトに瓜二つです。
特徴としては、iOS/Android クライアントアプリがあり、スマホで撮影したデータをバックグラウンドでアップロードしてくれます。
また、Exif 情報から自動カテゴライズしてくれたり、ローカルで機械学習を行い、文字認識・物体認識・顔認識の機能もあります。

インストール

色々やり方は用意してくれていますが、今回は Docker を使って構築します。

$ # Docker インストール
$ sudo su
# curl https://get.docker.com | sh
# exit
$ sudo usermod -aG docker $USER

$ # immich インストール
$ 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://<machine-ip-address>:2283でアクセスできるようになっているはずです。
管理者ユーザを作成するとトップページにアクセスできます。

immich トップページ

iOS/Android アプリでもログインできます。
サーバーのエンドポイントURLhttps://<machine-ip-address>:2283/apiです。

immich iOS

自宅外からのアクセス

自宅外からアクセスするためには、ルーターでポートフォワードさせるか、Wireguard・Tailscale 等の VPN を利用する方法があります。
ポートフォワードを使う場合、自宅のグローバル IP アドレスが変動する可能性があるため、DDNS を併用することが一般的だと思います。
一方、VPN を利用する場合は、クライアントソフトをインストールする手間が発生します。

これらの課題を解決するために、今回は Cloudflare Zero Trust のサービスを利用します。これにより、簡単に外部から immich へアクセスできる環境を構築します。

  • Cloudflare Tunnel
    • ポートフォワードをせずに自宅内のサービスを公開できます
    • クライアントから見ると Cloudflare のエッジサーバしか見えないので、自宅のグローバル IP を隠すことができます
  • Cloudflare Access
    • Cloudflare Tunnel だけだと、ドメインを知っている人は無条件にアクセスできてしまうので、アクセス制御を行います
    • SSO・ワンタイムパスワード色々な認証方法があります

Cloudflare Tunnel を作成する

Zero Trust > Networks > Tunnel > Create a tunnel > Select Cloudflared

curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb &&

sudo dpkg -i cloudflared.deb &&

sudo cloudflared service install <発行されたTOKEN>

Public hostname<subdomain>.<domain>/<path>を指定します。
Serviceには immich のアドレス・ポートを指定します。

これで、設定した<subdomain>.<domain>/<path>で immich にアクセスできるようになります。

Cloudflare Access を設定する

Authentication

今回は Google IdP を用いた SSO 認証を利用します。

Zero Trust > Settings > Authentication > Google

このドキュメントに従って設定します。

Access groups

Zero Trust > Access > Access groups > Add a Group

SelectorEmailsにして、認証を通したいユーザのメールアドレスを追加します。

Access groups

Service Authentication

モバイルアプリは Cloudflare Access の認証画面に対応できないため、Service Token を使用して認証を行います。
具体的には、モバイルアプリ からの HTTP リクエストヘッダーに作成したトークンを追加することで、認証を通過できるようになります。

Zero Trust > Access > Service auth > Create Service Token

生成された

  • Header and client ID
  • Header and client secret

をメモしておきます。

Applications

Zero Trust > Access > Applications > Add an application > Self-hosted

1. Overview

Cloudflare Tunnel で設定した<subdomain>.<domain>/<path>を指定します。

2. Policies

まずは、Google の認証用のポリシーを作成します。
Add a policyを押し、Access groupsで作成したグループのチェックボックスをクリックします。

次に、モバイルアプリ用のポリシーを作成します。
Add a policyを押し、ActionService AuthSelectorService Tokenに設定します。

これで Cloudflare 側の設定は完了です。

モバイルアプリの設定

歯車マーク > 詳細設定 > カスタムプロキシヘッダ

ヘッダの名前はそれぞれ、

  • CF-Access-Client-Id
  • CF-Access-Client-Secret

ヘッダのバリューに先ほどメモしたclient IDclient secretを入力します。

カスタムプロキシヘッダ

それぞれアクセスしてみる

ブラウザ

設定したドメインにアクセスすると、Cloudflare Access の認証画面が表示されます。

Cloudflare Access

Access groupsで許可した Google アカウントでログインすると、immich のトップページにアクセスできます。

モバイルアプリ

こちらは、カスタムプロキシヘッダを正しく設定していれば、ログイン画面に遷移します。

immich iOS Login

全体像

ドメイン費用はかかりますが、その他に関してはコストをかけずに構築することができました。

topology

おわりに

immich の構築自体はとても簡単にできるのでぜひ一度触ってみてください。

参考

Built with Hugo
Theme Stack designed by Jimmy