构建产品
私有存储上传
通过策略、套餐、配额、校验和与持久删除控制配置 S3 兼容私有上传。
已与启动模板提交
2a1a04a同步。
当产品需要保存头像、文档、导入文件或生成内容,又不希望文件公开、也不希望所有字节都经过 Next.js 服务器时,请使用此能力。完成本页后,已登录用户应能在账户 → 文件中上传、下载和删除文件,而其他组织无法访问。
选择适合产品的存储方案
- Docker Compose 默认使用仍在维护的开源 Garage,并自动创建私有 bucket。生产环境常用 Cloudflare R2 或 AWS S3。自行运营的团队仍可使用
minio,但它不再是内置本地默认值。所有提供器共用同一适配器。 - 混合文件选
general,仅图片选images(策略上限 10 MB),办公/文本文件选documents,必须由浏览器提供 SHA-256 时选verified。 - 最终大小上限取套餐、
STORAGE_MAX_UPLOAD_MB与策略上限中的最小值。bucket 应保持私有;模板默认通过短期签名 URL 交付。
可以上线的标准: UI 全流程可用,CORS 只允许你运营的来源,对象公共 URL 无法读取,跨组织访问被拒绝,并且 Cron 最终会删除已删除文件对应的对象。
将 STORAGE_PROVIDER 设为 garage、s3、r2 或 minio,再配置 bucket、region、endpoint 与凭据。对象保持私有,浏览器只获得短期签名 URL。图像生成示例也使用同一私有文件生命周期。
上传契约
POST /api/storage/uploads检查组织成员、storage.uploadentitlement、策略(general、images、documents、verified)、类型,以及套餐/环境/策略三者中最小的大小上限,并原子预留组织配额。- 浏览器直接 PUT 到对象存储;上传器仅为显示进度而使用 XHR。
POST /api/storage/uploads/complete校验对象元数据和可选 SHA-256,再激活记录。GET /api/storage/files/[uuid]?download=1返回按组织限定的签名下载 URL。DELETE /api/storage/files/[uuid]软删除并安排持久storage_object_delete任务。
未完成上传一小时后释放预留。删除由任务队列重试,因此 cron 必须运行。对象 key 由服务生成,不能接受客户端自选 bucket key。
上线前测试完整流程、错误 MIME/checksum、配额竞争、过期 URL、跨组织访问、删除重试与清理。供应商 CORS 细节见模板 docs/storage-providers.md。
下一步: 配置持久任务与就绪检查,确保临时故障后仍能清理放弃的上传和已删除的对象。