果報

二度寝して待つ

PhotoviewというフォトライブラリをPodmanで動かす

Photoviewというオープンソースの写真閲覧ソフトをPodmanで動作させたときのメモです。

photoview.github.io

はじめに

Photoviewを知らない方向けに、主な特徴を以下に列挙します。

  • ディレクトリ単位で自動的にアルバムを作成
    • ソフト上でアルバムを作成する機能はない
  • 軽量でシンプルな設計
    • アクセスはウェブブラウザのみ(一応、スマホ表示には対応)
    • 専用アプリや写真アップロード機能はなし
  • オープンソースかつ無料で、最近まで更新している
    • Dockerにも対応している

これらの特徴が、「フォルダ毎に整理した写真を単にウェブで見たいだけ」の私にとって最適解でした。

他の選択肢として、以下の比較サイトを参考にPiwigoLycheeも試してみましたが、操作性やUIがイマイチでした。また、Immichは全てを兼ね備えていましたが、高機能すぎるという理由で今回は見送りました。

meichthys.github.io

前提として、以下の環境で作業します。公式はDockerを推奨していますが、今回はPodmanを使ってみます。

  • OS: Ubuntu 24.04 LTS
  • podman: 4.9.3

Podman

podmanのインストール

aptでインストールします。

$ sudo apt install podman -y

Quadletファイルの作成

PodmanのQuadletを使って、Photoview本体とデータベース(MariaDB)の2つのコンテナをルートレスユーザで管理します。

まずは必要なディレクトリとファイルを作成します。

$ mkdir -p ~/.config/containers/systemd
$ mkdir -p ~/photoview/cache
$ mkdir -p ~/photoview/mariadb
$ nano ~/.config/containers/systemd/photoview.container
$ nano ~/.config/containers/systemd/photoview-mariadb.container

photoview.containerの内容は以下です。

[Unit]
Description=Photo gallery for self-hosted personal servers
After=network.target photoview-mariadb.service
Requires=photoview-mariadb.service

[Container]
## General
AutoUpdate=registry
Image=docker.io/photoview/photoview:latest
ContainerName=photoview

## Network
PublishPort=8000:8000
Network=photoview-network

## Volumes
Volume=/mnt/smb/Photos:/photos:ro
Volume=%h/photoview/cache:/home/photoview/media-cache

## Environment
Environment=PHOTOVIEW_DATABASE_DRIVER=mysql
Environment=PHOTOVIEW_MYSQL_URL=photoview:photosecret@tcp(photoview-mariadb:3306)/photoview
Environment=PHOTOVIEW_LISTEN_IP=0.0.0.0
Environment=PHOTOVIEW_LISTEN_PORT=8000
Environment=MAPBOX_TOKEN=pk.xxxxxxxxxxxxxxxxxxxxxxx
Environment=TZ=Asia/Tokyo

## Resources
UserNS=keep-id
User=1000
Group=1000
PodmanArgs=--cpus 1.0

[Service]
Restart=always
SuccessExitStatus=0 143
TimeoutStartSec=900

[Install]
WantedBy=multi-user.target default.target
  • [Unit]AfterRequiresでMariaDBコンテナとの依存関係を定義します。
  • PublishPort:ホスト側のポート(8000)は環境に応じて修正します。
  • Volume:ホスト側の写真保存先/mnt/smb/Photosを読み取り専用(ro)でマウントします。
  • MAPBOX_TOKEN:任意ですが、設定すると地図上で写真を表示できます。Mapboxで無料アカウントを作成後、トークンを取得します。
  • UserNS=keep-id:コンテナ内のUID/GIDをホストと一致させます(User=1000Group=1000は保険)。
  • PodmanArgs=--cpus 1.0:写真スキャン時のCPU負荷を制限します(300%まで上昇して高温になったので)。

photoview-mariadb.containerの内容は以下です。

[Unit]
Description=MariaDB Container for Photoview
After=network.target

[Container]
## General
AutoUpdate=registry
Image=docker.io/library/mariadb:lts
ContainerName=photoview-mariadb

## Volumes
Volume=%h/photoview/mariadb:/var/lib/mysql
Volume=%h/photoview/custom.cnf:/etc/mysql/conf.d/custom.cnf

## Environment Variables
Environment=MARIADB_DATABASE=photoview
Environment=MARIADB_USER=photoview
Environment=MARIADB_PASSWORD=photosecret
Environment=MARIADB_ROOT_PASSWORD=superphotosecret
Environment=TZ=Asia/Tokyo

Network=photoview-network
UserNS=keep-id
User=1000
Group=1000

[Service]
Restart=always
SuccessExitStatus=0 143
TimeoutStartSec=900

[Install]
WantedBy=multi-user.target default.target
  • UserNS=keep-id:コンテナ内のUID/GIDをホストと一致させます(User=1000Group=1000は保険)。
  • MariaDBのパフォーマンス用の設定は以下の~/photoview/custom.cnfで定義します。
[mariadbd]
innodb-buffer-pool-size=512M
transaction-isolation=READ-COMMITTED
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max-connections=512
innodb-rollback-on-timeout=OFF
innodb-lock-wait-timeout=120
query-cache-size=64M
tmp-table-size=64M
max-heap-table-size=64M

以下のコマンドで、コンテナ間で通信するための専用ネットワークを作成します。

$ podman network create photoview-network

作成したQuadletファイルを検証します。エラーが出なければOKです。

$ /usr/libexec/podman/quadlet -dryrun -user

コンテナの起動(systemdサービス化)

作成したQuadletファイルをサービスとして認識させます。

$ systemctl --user daemon-reload

サービスを起動します。

$ systemctl --user start photoview-mariadb.service
$ systemctl --user start photoview.service

なお、サーバ再起動時やログアウト後もサービスを維持するには、初回のみ以下を実行します。

$ loginctl enable-linger $USER

Caddy

リバースプロキシ用のCaddyを設定します。インストールは完了している前提です。

$ sudo nano /etc/caddy/Caddyfile

Caddyfileの内容は以下です。今回は単純な中継のみなのでシンプルです。

{
        email mail@yusukesakai.com
}

photos.yusukesakai.com {
        reverse_proxy localhost:8000
}

SSL/TLS証明書をCloudflareなどで別途用意する場合は、emailのグローバル設定も不要です。

以下のコマンドで設定ファイルを検証後、エラーがなければCaddyを再起動します。

$ sudo caddy validate --config /etc/caddy/Caddyfile
$ sudo systemctl restart caddy

DNSで設定したアドレスにアクセスすると、Photoviewの初期設定画面が表示されるはずです。

Photoview

初回アクセス時、初期設定画面が表示されるため、管理者のユーザ名、パスワードを入力します。また、PHOTO PATHにはコンテナで定義した/photosを入力します。

ログイン後、Settingsページから「Scan all users」またはユーザ一覧の「Scan」をクリックすると写真のスキャンが始まります。

初回は写真の枚数やサーバスペック次第で時間がかかりますが、2回目以降は差分のみなので高速です。

一度スキャンされた写真は、枚数が多くても軽快に表示してくれます。また、シンプルで直感的なインタフェースのおかげで操作も簡単です。

おわりに

もともと、Nextcloudで写真を管理していましたが、NextcloudをやめてSambaに切り替えたことで代替手段を模索しているときに、このPhotoviewに出会いました。

操作性も良く、機能も自分の理想に適していて、とても満足しています。今後も開発が継続してくれることを願っています。