使用 Google Photos 當作圖床
引子
撰寫部落格,沒有圖床怎麼行呢?
目前本站搭建在 Vultr 提供的 VPS 服務上。 基本方案下,這台主機有 25GB 的 SSD 可供使用。 雖然目前可用空間還有 14 GB , 但是時候先想好圖片的儲存方案了, 總不能一直把圖片往這部主機塞。
好在目前我的手機是 PIXEL 5, 享有無限量上傳的 Google Photos 服務。 所以只要能夠接受一點點壓縮圖片的代價, 無限空間的圖床理論上是沒問題。
動手開工
目前部落格的各個頁面是用 Hugo 搭建的。 在每則文章的 markdown 檔案中, 可以使用絕對路徑或相對路徑來指定圖片連結。例如:
![](https://topo.tw/photos/foo.jpg)
![](../../photos/foo.jpg)
但不管怎樣,都要讓 VPS 先有一個 /photos/
的 path 來提供圖片。
因此,我們會需要有一個圖片的專屬目錄供 Nginx 使用。
要如何把 Google Photos API 轉換為可掛載到檔案系統的目錄呢? 嘿嘿,要把各種雲端儲存服務掛載到檔案系統, 早就有大名鼎鼎的 rclone 可供使用啦。
設定
網路上有關 rclone 的教學資源相當豐富, 官方也有提供 docker image,所以這邊我就不多作贅述了。 只把目前情境下需要的設定紀錄下來:
IMAGE=rclone/rclone:1.58.0
# 使用 docker 執行 rclone
# 進入 config 模式
docker run \
--rm -it \
--name rclone \
--user `id -u`:`id -g` \
--volume ~/.config/rclone:/config/rclone \
--volume ~/rclone:/data \
--network host \
$IMAGE \
config
# 依照提示,新增一個指向 Google Photos 的 Remote
# 大部分的設定使用預設選項即可
...
# 掛載相關的 Remote 到目錄 ~/data/photos/
# 為了不要在檔案權限上太花時間,這邊我們把 /etc/passwd 和 /etc/group 傳進去
# 讓 docker container 內的使用者和目前使用者一模一樣
mkdir -p ~/data/photos
docker run \
--name rclone \
--rm --detach \
--user `id -u`:`id -g` \
--volume ~/.config/rclone:/config/rclone \
--volume ~/data:/data:shared \
--volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro \
--device /dev/fuse --cap-add SYS_ADMIN --security-opt apparmor:unconfined \
$IMAGE \
mount photos:media/by-day /data/photos --gphotos-read-size --allow-other
值得注意的是:預設情況下,掛載的目錄只可以顯示檔名而無法取得圖片內容
根據官方文件1,這是因為讀取圖片需要知道圖片的 size, 而用 Google Photos API 取得 size 需要額外的 transaction , 會大大拖慢同步的速度。
不過因為我們的目的就是要取得圖片內容,因此參數需要加上 gphotos-read-size
。
執行指令後,我們就完成掛載啦。
Google Photos 類型的目錄下有不同的圖片分類方式:
例如 all/
, by-year/
, by-month/
, by-day/
等。
因為我們僅掛載 media/by-day
,所以目錄結構會長這樣:
~/data/photos/2022
├── 2022-01-01
│ ├── PXL_20220101_055706343.jpg
│ ├── PXL_20220101_060221557.jpg
│ ├── PXL_20220101_060725049.jpg
│ ├── PXL_20220101_064911561.jpg
│ └── PXL_20220101_065919363.MP.jpg
接著,就只要把 Nginx 調整好就完成圖床服務啦!