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:用于图片的解码和编码。