图片存储
本地存储与 S3 兼容 (AWS / OSS / COS / R2 / MinIO) 配置
Imagic 抽象了一层 Storage 接口, 当前两种实现:
| Driver | 适用场景 | 数据落点 |
|---|---|---|
local | 单机部署, 数据量可控 | ./data/<yyyy>/<mm>/<dd>/<rand>.<ext> |
s3 | 多实例 / 大数据量 / 需要 CDN | 任意 S3 兼容对象存储 |
切换驱动不会自动迁移已有图片, 历史 URL 仍指向旧存储。建议初次部署就选定驱动。
切换 driver 在 admin /admin/settings → 存储 中改动, 即时生效, 不需重启。
Local 驱动 (默认)
零配置即可工作。仅一个 setting:
| Setting | 默认 | 说明 |
|---|---|---|
storage.local.dir | ./data | 本地存储根目录, Docker 部署时挂宿主机做持久化 |
公开访问通过 /data/<key> 路径, 由 Imagic 内置静态路由提供。
随机 key 不可枚举, 但 URL 一旦泄露就能访问, 适合内容公开度较高的场景。
S3 驱动
支持任何 S3 兼容对象存储 (AWS S3 / 阿里云 OSS / 腾讯云 COS / Cloudflare R2 / MinIO 等),
底层用 minio-go/v7, 公开访问采用 公开桶 + 直链 策略, 不走预签名也不经后端反代。
Settings 列表
| Setting | 必填 | 说明 |
|---|---|---|
storage.driver | 是 | 改成 s3 |
storage.s3.endpoint | 是 | host[:port], 带 http(s):// 也可; 不带时由 use_ssl 决定 |
storage.s3.bucket | 是 | 桶名 |
storage.s3.region | 视厂商 | AWS 必填; OSS / COS / R2 一般可空或填厂商指定值 |
storage.s3.access_key | 是 | Access Key |
storage.s3.secret_key | 是 | Secret Key |
storage.s3.use_ssl | 否 | endpoint 不带 scheme 时由该值决定 https/http |
storage.s3.prefix | 否 | 桶内统一前缀 (如 imagic/prod), 不带前导 / 后导 / |
storage.s3.public_url | 否 | CDN 或自定义域名前缀, 留空则按 endpoint 自动拼 |
各厂商 endpoint 示例
| 厂商 | endpoint 示例 | region |
|---|---|---|
| AWS S3 | s3.us-east-1.amazonaws.com | us-east-1 |
| 阿里云 OSS (公网) | oss-cn-hangzhou.aliyuncs.com | oss-cn-hangzhou |
| 阿里云 OSS (VPC) | oss-cn-hangzhou-internal.aliyuncs.com | oss-cn-hangzhou |
| 腾讯云 COS | cos.ap-shanghai.myqcloud.com | ap-shanghai |
| Cloudflare R2 | <account>.r2.cloudflarestorage.com | auto |
| MinIO 自建 | minio.example.com:9000 | us-east-1 (任意) |
桶配置
Imagic 在 Put 时不显式设 ACL, 因此桶必须公开可读才能让浏览器直接访问图片。
推荐做法: 公开整个桶 或 配置桶级策略只放行 s3:GetObject。
AWS S3 / MinIO 桶策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::your-bucket-name/*"]
}
]
}AWS 还要在桶 → Block public access 里关闭"Block all public access"。
阿里云 OSS
控制台 → 桶 → 权限管理 → 读写权限 → "公共读"。
或用细粒度 Bucket Policy 只放行 oss:GetObject。
腾讯云 COS
控制台 → 桶 → 权限管理 → 访问权限 → "公有读私有写"。
Cloudflare R2
R2 默认私有, 需要在桶 → Settings → Public Access → 启用 "Allow Access" 并绑定一个 R2.dev
子域 (临时) 或自定义域名。绑定完成后把那个域名填到 storage.s3.public_url,
否则 Imagic 拼出来的 URL 是 https://<account>.r2.cloudflarestorage.com/..., 无法直接公开访问。
CDN / 自定义域名
CDN 加速强烈建议启用, 直连对象存储延迟与带宽都不理想。
storage.s3.public_url = https://cdn.imagic.example.com设置后, Imagic 上传成功返回的 URL 就是 https://cdn.imagic.example.com/<key>,
对象存储里的 key 与 URL key 一一对应; CDN 回源指向你的桶 endpoint 即可。
留空时按 <scheme>://<endpoint>/<bucket>/<key> 自动拼。
验证
改完 settings 后:
- 进创造页随便生一张图, 等 final 帧出来
- 右键查看图片地址, 应该是
<public_url>/<yyyy>/<mm>/<dd>/<rand>.<ext>这种形态 - 用浏览器无痕模式直接打开该地址, 能正常显示即配置成功
如果失败, 看 admin 后台保存时是否报错; 或 imagic 容器日志是否有 storage init failed。
配置失败时后端会保留旧 storage 实例, 不会把整个图片存储弄坏, 修正参数重新保存即可。
数据迁移
local → s3 没有内置迁移工具。建议:
- 在容器或宿主机上用
aws s3 sync/ossutil/coscli把./data/<yyyy>/...目录全量同步到桶 - 同步完成后切换
storage.driver到s3 - 老的图片 URL 仍是
/data/..., 历史记录不受影响 (前提是 local 目录文件还在); 想彻底切干净 需要在数据库里更新generations.imagesJSON 字段, 这一步需要谨慎
S3 模式下 /data/* 路由仍存在但读不到对象, 返回 404; 历史数据只能通过迁移前的本地文件
继续访问。