尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Supabase Storage 深度解析:S3 兼容对象存储、图片变换与 RLS 权限体系的实现与自托管实战

Supabase Storage 深度解析:S3 兼容对象存储、图片变换与 RLS 权限体系的实现与自托管实战 Supabase Storage 深度解析S3 兼容对象存储、图片变换与 RLS 权限体系的实现与自托管实战【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabaseSupabase Storage 是一个与 Supabase Auth、Postgres 深度集成的开源对象存储服务提供 S3 兼容 API、URL 参数式图片变换和基于 Postgres 行级安全策略RLS的细粒度访问控制。本文以 Supabase 主仓库supa/supabase中的产品文档为骨架结合docker/目录下的 Compose 编排、配置参考与端到端测试脚本讲清 Storage 的五项核心能力、三种桶类型以及在自托管环境中如何配置file/S3两种存储后端、接入 imgproxy 图片变换并用 AWS CLI 完成 S3 协议验证。一、Supabase Storage 是什么官方文档apps/www/content/md/storage.md对 Supabase Storage 的定位是一个开源对象存储原生集成 Supabase Auth 与 Postgres支持三种面向不同工作负载的桶类型——files通用资产、analyticsApache Iceberg 表格式、vector向量嵌入。与其他“数据库自带文件字段”的方案不同Supabase Storage 的权限体系直接复用 Postgres每个对象都会落入storageschema 的元数据表中访问控制通过写在storage.objects表上的 RLS 策略实现。这意味着授权逻辑可以用 SQL 表达并且与 Auth 签发的 JWTanon/authenticated/service_role等角色天然打通。二、五大核心能力与仓库证据文档列出了五项 Key Features。下面逐条展开并给出当前仓库中可以查证的实现依据。1. S3 兼容标准 S3 APIStorage 暴露了一个 S3 协议端点自托管场景下挂载在/storage/v1/s3路径。docker/tests/test-s3.sh 中可以看到端点的确切拼法S3_ENDPOINT$BASE_URL/storage/v1/s3该测试脚本用aws cli v2完整走了一遍 S3 协议栈验证了 13 个环节ListBuckets—— 列出所有桶CreateBucket—— 建桶后回查 ListBuckets 确认存在PutObject—— 上传文件并校验upload:输出ListObjectsV2—— 确认对象出现在对象列表中HeadObject—— 用ContentLength精确比对上传字节数GetObject—— 下载后逐字节校验内容一致CopyObject—— 服务端复制再下载副本验证内容DeleteObject—— 删除后确认对象不再出现分片上传—— 构造 7 MB 随机文件触发 multipart 路径5 MB 即分片并双向校验远端与下载尺寸Range 请求——--range bytes0-4只取前 5 字节验证部分 GET预签名 URL——aws s3 presign生成临时 URL 并用curl拉取内容比对鉴权失败路径—— 故意使用无效凭证确认返回 403/401 类错误清理—— 递归删对象、删桶并确认桶已消失。运行方式脚本头部注释即为准# 前置已按 S3 配置启动自托管实例 docker compose -f docker/docker-compose.yml -f docker/docker-compose.s3.yml up -d # .env 中需配置 S3_PROTOCOL_ACCESS_KEY_ID / S3_PROTOCOL_ACCESS_KEY_SECRET / REGION sh docker/tests/test-s3.sh # 默认 http://localhost:8000 sh docker/tests/test-s3.sh base_url # 自定义地址前置依赖是awsCLI v2 和jq脚本会自动检查。凭证从 .env 读取其中S3_PROTOCOL_ACCESS_KEY_ID与S3_PROTOCOL_ACCESS_KEY_SECRET是静态 SigV4 密钥供外部 S3 客户端aws cli、rclone 等签名请求使用。配置参考docker/CONFIG.md “Storage / S3 backend” 小节中的关键变量变量类型说明S3_PROTOCOL_ENABLEDboolean启用 S3 兼容 API默认trueS3_PROTOCOL_ACCESS_KEY_IDstring静态 SigV4 Access Key单租户S3_PROTOCOL_ACCESS_KEY_SECRETstring静态 SigV4 SecretS3_PROTOCOL_PREFIXstringS3 路由的 URL 前缀默认空S3_PROTOCOL_ENFORCE_REGIONboolean是否拒绝 region 与STORAGE_S3_REGION不符的 SigV4 请求默认falseS3_ALLOW_FORWARDED_HEADERboolean重建 SigV4 规范化 URL 时是否信任Forwarded头默认false2. 全球 CDN托管平台的分发能力文档称托管版资产“从全球 285 城市低延迟分发”。需要说明边界CDN 属于托管平台能力自托管 Compose 编排中并未包含 CDN 层自托管下对象由本地file后端或外接 S3 后端直出可通过RESPONSE_S_MAXAGE默认0秒为公开响应追加 CDNs-maxage缓存寿命为前置反向代理/CDN 预留缓存策略。3. 图片变换imgproxy 实时处理Storage 的图片变换由独立的 imgproxy 服务承担。docker/docker-compose.yml 中可以看到完整的服务定义imgproxy: container_name: supabase-imgproxy image: darthsim/imgproxy:v3.30.1 volumes: - ./volumes/storage:/var/lib/storage:z environment: IMGPROXY_BIND: :5001 IMGPROXY_LOCAL_FILESYSTEM_ROOT: / IMGPROXY_USE_ETAG: true IMGPROXY_AUTO_WEBP: ${IMGPROXY_AUTO_WEBP} IMGPROXY_MAX_SRC_RESOLUTION: 16.8三个关键设计点imgproxy 与 storage 共享同一个数据卷./volumes/storage:/var/lib/storage因此可以直接按本地路径读取源图IMGPROXY_LOCAL_FILESYSTEM_ROOT: /允许其按绝对路径寻址卷内文件storage服务声明了对imgproxy的depends_ondocker-compose.yml并启用变换ENABLE_IMAGE_TRANSFORMATION: true与IMGPROXY_URL: http://imgproxy:5001。相关配置变量来自 docker/CONFIG.md “Image transformation” 小节变量默认值说明IMAGE_TRANSFORMATION_ENABLEDfalse总开关旧名ENABLE_IMAGE_TRANSFORMATIONIMGPROXY_URL无imgproxy 基址启用变换时必填IMAGE_TRANSFORMATION_LIMIT_MAX_SIZE2000允许请求的最大变换尺寸pxIMAGE_TRANSFORMATION_LIMIT_MIN_SIZE1允许请求的最小变换尺寸pxIMGPROXY_REQUEST_TIMEOUT15imgproxy 调用超时秒IMGPROXY_HTTP_MAX_SOCKETS5000imgproxy HTTP agent 最大并发连接对应文档中 “resize, crop, format conversion (WebP, AVIF) via URL parameters” 的能力变换通过对象 URL 上的参数触发IMGPROXY_AUTO_WEBP控制是否自动转 WebP变换路径还有配套的限流变量RATE_LIMITER_*memory/redis两种驱动渲染路径默认上限5req/s防止变换端点被滥用。4. 行级安全Postgres RLS 即访问策略文档明确授权机制是写在storage.objects表上的 Postgres RLS 策略并与 Supabase Auth 集成。这一点在自托管编排里有直接对应storage 服务以专用角色supabase_storage_admin连接数据库DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}...docker-compose.yml该角色在 docker/volumes/db/roles.sql 中被创建并赋密配置参考中定义了 Storage 识别的三个 Postgres 角色DB_ANON_ROLE默认anon、DB_AUTHENTICATED_ROLE默认authenticated、DB_SERVICE_ROLE默认service_role。请求携带的 JWT 决定 Storage 以哪个角色执行 SQLRLS 策略据此放行或拒绝——这就是“Access policies written in SQL”的落地链路SERVICE_KEYservice_role JWT可以绕过 RLS因此必须按机密管理。5. Dashboard可视化文件管理文档提到控制台支持拖拽上传、文件浏览、多选操作与文件夹管理。自托管下该能力由 Studio 提供docker/docker-compose.yml 中studio服务注入SUPABASE_ANON_KEY/SUPABASE_SERVICE_KEY后即可通过网关http://localhost:8000以标准 Supabase 客户端方式操作存储对象权限模型与托管版一致同样受 RLS 约束。三、三种桶类型Bucket Types文档将桶划分为三类对应不同工作负载Files 桶日常资产与用户内容图片、视频、文档、PDF、归档包等通用资产走全球 CDN托管或本地后端自托管分发访问控制细化到 RLS 策略级别。这是绝大多数场景使用的默认桶类型。Analytics 桶开放表格式上的分析负载面向 Apache Iceberg 等开放表格式的大规模分析负载适合历史数据、时间序列、日志与 ETL 产出物可选地经 Postgres 查询。Vector 桶AI/ML 工作负载为 AI/ML 场景存储并索引向量嵌入支持多种距离度量、元数据过滤与快速相似性查询服务于 RAG 系统与 AI 搜索。仓库中可以看到 vector 桶在 Storage 服务侧的配置面docker/CONFIG.md “Tenant features (Vector)” 小节变量默认值说明VECTOR_ENABLEDfalse是否启用 vector 桶支持VECTOR_MAX_BUCKETS10每租户最多 vector 桶数VECTOR_MAX_INDEXES20每个 vector 桶最多索引数VECTOR_S3_BUCKETS无承载向量索引的 S3 桶列表逗号分隔VECTOR_BUCKET_REGION无vector 桶所在 AWS 区域从这些变量可以推断vector 索引的物理数据落在独立的 S3 桶上VECTOR_S3_BUCKETS与 files 桶的数据面解耦。四、技术细节协议、限制与上限汇总综合文档 “Technical Details” 一节与仓库配置关键参数如下维度值仓库证据协议S3 兼容 APItest-s3.sh、S3_PROTOCOL_*变量CDN托管版 285 边缘节点文档声明自托管由反向代理/CDN 自理单文件上限默认自托管50 MBFILE_SIZE_LIMIT: 52428800docker-compose.yml单文件上限托管付费计划500 GB经 multipart 上传文档声明S3 分片大小默认 16 MiB低于 5 MiB 时自动向上钳制STORAGE_S3_UPLOAD_PART_SIZETUS 断点续传分片默认 50 MBURL 有效期 1 h路径/upload/resumableTUS_PART_SIZE/TUS_URL_EXPIRY_MS/TUS_URL_PATH图片变换resize / crop / WebP / AVIF 格式转换imgproxy 服务 IMAGE_TRANSFORMATION_*授权storage.objects表上的 Postgres RLSDB_*_ROLE变量、roles.sql上传限额相关的完整变量组docker/CONFIG.md “Upload limits” 小节变量默认值说明FILE_SIZE_LIMIT/UPLOAD_FILE_SIZE_LIMIT必填上传大小上限字节Compose 中设为 5242880050 MBUPLOAD_FILE_SIZE_LIMIT_STANDARD0不限制非断点续传上传的单独上限TUS_PART_SIZE50MBTUS 分片大小TUS_MAX_CONCURRENT_UPLOADS500最大并发 TUS 会话数TUS_URL_EXPIRY_MS36000001 小时TUS 上传 URL 有效期UPLOAD_SIGNED_URL_EXPIRATION_TIME60秒签名上传 URL 默认有效期TUS_LOCK_TYPEpostgresTUS 上传锁的存储后端postgres/s3另外STORAGE_EMPTY_BUCKET_MAX默认200000限制单次“清空桶”调用可删除的对象数REQUEST_URL_LENGTH_LIMIT默认7500约束对象 Key 的 URL 长度——两者都是大规模对象场景下容易踩到的隐性上限。五、自托管实战两种存储后端的完整配置场景 A默认 file 后端本地文件系统docker/docker-compose.yml 中storage服务镜像supabase/storage-api:v1.60.4的默认编排即 file 后端storage: container_name: supabase-storage image: supabase/storage-api:v1.60.4 depends_on: db: { condition: service_healthy } rest: { condition: service_started } imgproxy: { condition: service_started } environment: ANON_KEY: ${ANON_KEY} SERVICE_KEY: ${SERVICE_ROLE_KEY} POSTGREST_URL: http://rest:3000 AUTH_JWT_SECRET: ${JWT_SECRET} DATABASE_URL: postgres://supabase_storage_admin:${POSTGRES_PASSWORD}${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} STORAGE_PUBLIC_URL: ${SUPABASE_PUBLIC_URL} REQUEST_ALLOW_X_FORWARDED_PATH: true FILE_SIZE_LIMIT: 52428800 STORAGE_BACKEND: file GLOBAL_S3_BUCKET: ${GLOBAL_S3_BUCKET} # file 后端下为目录名 FILE_STORAGE_BACKEND_PATH: /var/lib/storage TENANT_ID: ${STORAGE_TENANT_ID} REGION: ${REGION} ENABLE_IMAGE_TRANSFORMATION: true IMGPROXY_URL: http://imgproxy:5001 S3_PROTOCOL_ACCESS_KEY_ID: ${S3_PROTOCOL_ACCESS_KEY_ID} S3_PROTOCOL_ACCESS_KEY_SECRET: ${S3_PROTOCOL_ACCESS_KEY_SECRET} volumes: - ./volumes/storage:/var/lib/storage:z要点STORAGE_BACKEND: file时GLOBAL_S3_BUCKET的语义变为目录名注释原话“S3 bucket when using S3 backend, directory name when using file”docker/.env.example 中示例值为stub数据落在宿主机docker/volumes/storage下随卷持久化file后端的 ETag 算法可用STORAGE_FILE_ETAG_ALGORITHM在md5默认与mtime间切换REQUEST_ALLOW_X_FORWARDED_PATH: true让 Storage 在计算对外公开 URL 时信任X-Forwarded-Path适配网关重写路径的部署健康检查探测http://storage:5000/status服务默认端口5000admin 端口5001。数据库侧配置docker/CONFIG.md “Database” 小节值得注意的默认值DATABASE_MAX_CONNECTIONS每租户连接池 20、DATABASE_STATEMENT_TIMEOUT30000 ms、DATABASE_CONNECTION_TIMEOUT3000 ms若前置 Supavisor/PgBouncer可用DATABASE_POOL_URL接管此时DATABASE_MAX_CONNECTIONS被忽略。场景 BS3 后端MinIO / RustFS官方提供了两份可叠加的 Compose 覆盖文件启动命令形如docker compose -f docker/docker-compose.yml -f docker/docker-compose.s3.yml up -ddocker/docker-compose.s3.yml 引入 MinIO 作为对象后端编排链为minio健康检查mc ready local→minio-createbucket一次性容器mc alias set supa-minio http://minio:9000 ...后执行mc mb --ignore-existing supa-minio/${GLOBAL_S3_BUCKET}→storage依赖建桶容器成功退出。storage 服务的叠加环境变量STORAGE_BACKEND: s3 GLOBAL_S3_ENDPOINT: http://minio:9000 GLOBAL_S3_PROTOCOL: http GLOBAL_S3_FORCE_PATH_STYLE: true AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER} AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD}几个必须理解的细节GLOBAL_S3_*系列是STORAGE_S3_*的遗留别名两者等价见 docker/CONFIG.md新写配置建议用STORAGE_S3_*MinIO 内部地址用路径式寻址FORCE_PATH_STYLE: true这也是自托管 S3 兼容服务的常见要求桶名由GLOBAL_S3_BUCKET统一创建容器用--ignore-existing保证幂等可重复docker compose updocker/docker-compose.rustfs.yml 是同一套模式的 RustFSRust 实现的 S3 兼容服务变体结构与 MinIO 版完全对称rustfs→rustfs-createbucket→storage可视为 MinIO 的替换件二者择一。验证与回归后端切换完成后用 docker/tests/test-s3.sh 跑一遍 S3 协议冒烟测试是最直接的验收手段——它覆盖建桶、上传/下载/复制/删除、7 MB 分片上传、Range 请求、预签名 URL 与错误凭证拒绝共 13 项检查全部通过才退出码 0。脚本末尾输出 Results: N passed, 0 failed 即为通过标准。六、小结Supabase Storage 的本质是**“Postgres 元数据 RLS 权限 可插拔对象后端file / S3 imgproxy 变换”** 的组合权限面完全复用 Auth/Postgres数据面可落在本地文件系统或任意 S3 兼容服务上三种桶类型files / analytics / vector分别对应通用资产、Iceberg 分析表与向量嵌入负载vector 能力由VECTOR_*变量族控制默认关闭自托管落地时docker/docker-compose.yml提供 file 后端开箱配置50 MB 上限、imgproxy 变换、S3 协议端点密钥docker/docker-compose.s3.yml/docker/docker-compose.rustfs.yml提供 MinIO/RustFS 后端的叠加编排docker/CONFIG.md 是逐变量的权威参考docker/tests/test-s3.sh 则给出可复制的验收脚本托管与自托管的能力边界要分清全球 CDN、500 GB 分片上限等属于托管平台规格自托管实例的实际上限由FILE_SIZE_LIMIT、STORAGE_S3_UPLOAD_PART_SIZE等环境变量自行决定。完整变量清单Server / Database / JWT / S3 backend / File backend / Image transformation / Upload limits / Rate limiting / Webhook / Vector 各小节请查阅 docker/CONFIG.md 的 “Storage” 章节组件清单与生产安全注意事项默认配置不可直接用于生产、需更换全部默认密钥见 docker/README.md。【免费下载链接】supabaseThe Postgres development platform. Supabase gives you a dedicated Postgres database to build your web, mobile, and AI applications.项目地址: https://gitcode.com/GitHub_Trending/supa/supabase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表