megrxu

Imagio: 以 S3 為儲存的圖床管理

Jun 25, 2024  「Web」  

Preface

開發該專案的原因在與,滿足以下需求的圖床管理平臺幾乎不能夠被找到:

  1. 儲存內容在自己手中(或者任意 S3 平臺);
  2. 支援視覺化的上傳和刪除;
  3. 容易部署;
  4. 儘可能做到 Serverless;
  5. 能夠實現圖片的自動裁剪和壓縮。

事實上,上次使用體驗非常好的檔案管理或者是後端儲存還是 RoRActive Storage,其上傳和修改圖片的 API 相當稱手。 但仍然需要基於此進行管理平臺的開發,還需要一個長期線上的後端。 有了 NAS 之後,後端這個條件可以適當放鬆,但使用 Ruby 開發則是必不可少的。最後還是放棄了。

另外一個嘗試是使用 Cloudflare Images。這點則看中的也是無感的 Variant 生成,但是其 API 仍然不夠完善,許多自定義的內容還是需要自己手糊。 嘗試了一段時間(Imagio 的早期版本就是基於 CF Images 的),發覺需要手糊的地方太多,並且其價格對於個體戶來說過於昂貴( 5 + 1 USD / month ),最後還是放棄了這個後端。

那麼,就讓我們遷移到更通用的 S3 吧(然後就可以去薅各種 Provider 的羊毛了 🤣)。

跑一個完整的 DEMO

演示地址: https://imagio.pages.dev/

準備

一般而言,需要手動部署的有兩個元件:

  1. 前端(可部署於支援 SvelteKit 頁面的各種平臺,例如 Cloudflare Pages);
  2. 後端(需要可公網訪問的,可執行由 Rust 編寫的伺服器或平臺)。

以及需要準備好儲存影象和變體快取的 S3 Bucket。

部署後端

部署伺服器相當簡單,只需克隆 imagio-server 專案,並執行

cargo run --release -- --account_id <ACCOUNT_ID> \
  --store <IMAGES_PATH> --cache <CACHE_PATH>     \
  --bucket <BUCKET> --region <REGION>            \
  --endpoint <ENDPOINT>                          \
  --access-key-id <ACCESS_KEY_ID>                \
  --secret-access-key <SECRET_ACCESS_KEY>        \
  s3 serve

部署前端

以 Cloudflare Pages 為例,只需克隆 imagio 專案,在 Cloudflare Pages 頁面上連線你的倉庫,選擇 SvelteKit 構建。 並配置以下環境變數:

SERVER_URL=<IMAGIO_SERVER_URL>
ACCOUNT_ID=<ACCOUNT_ID>
TOKEN=<TOKEN> # 用於驗證的 Token,可以隨意設定
S3_PUBLIC_ACCESS_ENDPOINT= # 如果 S3 Bucket 可公開訪問公開,可新增;也可為空。

即可在部署完成。

使用

  1. 訪問前端頁面,可對圖片進行上傳、刪除、檢視等操作;
  2. 在第一次訪問變體的 URL 時,如 https:///delivery//square ,會自動轉發請求到後端,裁剪並快取圖片;在下一次訪問時,如果配置了 S3_PUBLIC_ACCESS_ENDPOINT 會直接返回快取的圖片,而無需訪問後端。
  3. 因此,後端的線上時間可以適當放鬆,只需保證在第一次訪問時線上即可,適合部署在家用伺服器或者自己的開發機上臨時使用。
  4. (另外還有大量的未實現功能,因此 UI 有些冗餘。)後面慢慢填坑吧。

Ref:使用到的技術和相關專案

  • OpenDAL:用於統一的資料訪問層,支援多種儲存後端;
  • fast_image_resize:用於快速的圖片裁剪和壓縮;
  • image:用於圖片的解碼和編碼。