Skip to content
Self-Hosting

配置 S3 存储

Enable S3-compatible client endpoint and set up an S3 backend for self-hosted Supabase Storage.

自托管的 Supabase 存储有两个独立的 S3 相关功能:

🌐 Self-hosted Supabase Storage has two independent S3-related features:

  • S3 协议端点 - Storage 在 /storage/v1/s3 上提供的兼容 S3 的 API。这使得像 rclone 和 AWS CLI 这样的标准 S3 工具可以与你的 Storage 实例进行交互。
  • S3 后端 - 存储保存数据的地方。默认情况下,文件会存储在本地文件系统上。你可以切换到兼容 S3 的服务(AWS S3、MinIO 等),以获得更好的耐久性、可扩展性,或者利用现有的基础设施。

你可以独立配置任一功能。例如,你可以启用 S3 协议端点来使用 rclone,同时保持默认的基于文件的存储,或者切换到 S3 后端而不启用 S3 协议端点。

🌐 You can configure either feature independently. For example, you can enable the S3 protocol endpoint to use rclone while keeping the default file-based storage, or switch to an S3 backend without enabling the S3 protocol endpoint.

启用 S3 协议端点 #

🌐 Enable the S3 protocol endpoint

位于 /storage/v1/s3 的 S3 协议端点允许标准的 S3 客户端与你的自建存储实例进行交互。它可以与任何存储后端一起使用,包括默认的基于文件的存储——你不需要先配置一个 S3 后端。Supabase 的 REST API 和 SDK 不使用 S3 协议。

🌐 The S3 protocol endpoint at /storage/v1/s3 allows standard S3 clients to interact with your self-hosted Storage instance. It works with any storage backend, including the default file-based storage - you do not need to configure an S3 backend first. The Supabase REST API and SDK do not use the S3 protocol.

确保检查你的 .env 文件中 REGIONS3_PROTOCOL_ACCESS_KEY_IDS3_PROTOCOL_ACCESS_KEY_SECRET 是否已正确配置。想了解更多关于密钥和密码的信息,请参阅 配置和保护 Supabase

🌐 Make sure to check that REGION, S3_PROTOCOL_ACCESS_KEY_ID and S3_PROTOCOL_ACCESS_KEY_SECRET are properly configured in your .env file. Read more about the secrets and passwords in Configuring and securing Supabase.

docker-compose.yml
1
storage:
2
environment:
3
# ... existing variables ...
4
REGION: ${REGION}
5
S3_PROTOCOL_ACCESS_KEY_ID: ${S3_PROTOCOL_ACCESS_KEY_ID}
6
S3_PROTOCOL_ACCESS_KEY_SECRET: ${S3_PROTOCOL_ACCESS_KEY_SECRET}

用 AWS CLI 测试 #

🌐 Test with the AWS CLI

1
( set -a && \
2
source .env > /dev/null 2>&1 && \
3
echo "" && \
4
AWS_ACCESS_KEY_ID=$S3_PROTOCOL_ACCESS_KEY_ID \
5
AWS_SECRET_ACCESS_KEY=$S3_PROTOCOL_ACCESS_KEY_SECRET \
6
aws s3 ls \
7
--endpoint-url http://localhost:8000/storage/v1/s3 \
8
--region $REGION \
9
s3://your-storage-bucket )

用 rclone 测试 #

🌐 Test with rclone

1
( set -a && \
2
source .env > /dev/null 2>&1 && \
3
echo "" && \
4
rclone ls \
5
--s3-endpoint http://localhost:8000/storage/v1/s3 \
6
--s3-region $REGION \
7
--s3-provider Other \
8
--s3-access-key-id "$S3_PROTOCOL_ACCESS_KEY_ID" \
9
--s3-secret-access-key "$S3_PROTOCOL_ACCESS_KEY_SECRET" \
10
:s3:your-storage-bucket )

使用 aws loginrclone config 进行持久配置。

🌐 Use aws login and rclone config for persistent configuration.

如何配置 S3 后端 #

🌐 How to configure an S3 backend

一般来说,以下配置变量定义了 docker-compose.yml 中 Storage 的 S3 后端配置:

🌐 In general, the following configuration variables define S3 backend configuration for Storage in docker-compose.yml:

docker-compose.yml
1
storage:
2
environment:
3
# ... existing variables ...
4
STORAGE_BACKEND: s3
5
GLOBAL_S3_BUCKET: your-s3-bucket-or-dirname
6
GLOBAL_S3_ENDPOINT: https://your-s3-endpoint
7
GLOBAL_S3_PROTOCOL: https
8
GLOBAL_S3_FORCE_PATH_STYLE: 'true'
9
AWS_ACCESS_KEY_ID: your-access-key-id
10
AWS_SECRET_ACCESS_KEY: your-secret-access-key
11
REGION: your-region

根据你的设置,你可能需要调整这些数值——比如,如果你想使用本地的 S3 兼容服务像 RustFS、MinIO,或者使用像 AWS 这样的云服务提供商。

🌐 Depending on your setup, you may need to adjust these values - for example, to use a local S3-compatible service like RustFS, MinIO or a cloud provider like AWS.

使用 RustFS #

🌐 Using RustFS

可以添加覆盖 docker-compose.rustfs.yml 来启用 RustFS 容器,并为存储后端提供兼容 S3 的 API:

🌐 An override docker-compose.rustfs.yml can be added to enable RustFS container and provide an S3-compatible API for Storage backend:

1
sh run.sh config add rustfs
2
sh run.sh start

确保查看你的 .env 文件中的存储部分,以了解相关的配置选项。

🌐 Make sure to review the Storage section in your .env file for related configuration options.

使用 MinIO #

🌐 Using MinIO

可以添加覆盖 docker-compose.s3.yml 来启用 MinIO 容器,并为存储后端提供兼容 S3 的 API:

🌐 An override docker-compose.s3.yml can be added to enable MinIO container and provide an S3-compatible API for Storage backend:

1
sh run.sh config add s3
2
sh run.sh start

确保查看你的 .env 文件中的存储部分,以了解相关的配置选项。

🌐 Make sure to review the Storage section in your .env file for related configuration options.

使用 AWS S3 #

🌐 Using AWS S3

创建一个 S3 存储桶和一个有访问权限的 IAM 用户。然后配置存储服务:

🌐 Create an S3 bucket and an IAM user with access to it. Then configure the storage service:

docker-compose.yml
1
storage:
2
environment:
3
# ... existing variables ...
4
STORAGE_BACKEND: s3
5
GLOBAL_S3_BUCKET: your-aws-bucket-name
6
AWS_ACCESS_KEY_ID: your-aws-access-key
7
AWS_SECRET_ACCESS_KEY: your-aws-secret-key
8
REGION: your-aws-region

对于 AWS S3,你不需要 GLOBAL_S3_ENDPOINTGLOBAL_S3_FORCE_PATH_STYLE —— Storage S3 客户端会自动根据区域解析端点,并使用虚拟主机风格的 URL,这正是 AWS S3 所期望的。这些变量只在非 AWS S3 兼容的提供商中才需要。

🌐 For AWS S3, you do not need GLOBAL_S3_ENDPOINT or GLOBAL_S3_FORCE_PATH_STYLE - the Storage S3 client automatically resolves the endpoint from the region and uses virtual-hosted-style URLs, which is what AWS S3 expects. These variables are only needed for non-AWS S3-compatible providers.

兼容 S3 的提供商 #

🌐 S3-compatible providers

使用与 MinIO 相同的配置,将端点、存储桶名称、区域和 AWS 凭证替换为你的 S3 兼容提供商提供的值,例如:

🌐 Use the same configuration as MinIO, replacing the endpoint, bucket name, region, and AWS credentials with the values provided by your S3-compatible provider, for example:

docker-compose.yml
1
storage:
2
environment:
3
# ... existing variables ...
4
STORAGE_BACKEND: s3
5
GLOBAL_S3_BUCKET: your-bucket-name
6
GLOBAL_S3_ENDPOINT: https://your-account-id.r2.cloudflarestorage.com
7
GLOBAL_S3_FORCE_PATH_STYLE: 'true'
8
AWS_ACCESS_KEY_ID: your-access-key-id
9
AWS_SECRET_ACCESS_KEY: your-secret-access-key
10
REGION: your-region

验证 #

🌐 Verify

  • 打开 Studio 并上传一个文件到 bucket。使用 AWS CLI 或 rclone 列出文件,确认 S3 端点是否工作。
  • 如果使用 S3 后端:确认文件是否出现在你的 S3 提供商控制台中。

会话令牌 #

🌐 Session token

你可以使用用户的 JWT 来认证 Supabase 的兼容 S3 存储,从而在 S3 操作中执行行级安全 (RLS)。当你在服务器上为特定用户会话初始化 S3 客户端,或者直接在前端使用客户端时,这都很有用。

🌐 You can authenticate to Supabase's S3-compatible storage using a user’s JWT to enforce Row-Level Security (RLS) across S3 operations. This is useful when initializing the S3 client on the server for a specific user session, or when using the client directly from the frontend.

使用会话令牌执行的所有操作都针对已认证的用户,并且存储架构中定义的任何 RLS 策略都会被应用。

🌐 All operations performed with a session token are scoped to the authenticated user, and any RLS policies defined in the storage schema will be applied.

要使用会话令牌进行 S3 身份验证,请提供以下凭证:

🌐 To authenticate with S3 using a session token, provide the following credentials:

  • 区域: 来自你 .env 文件中 REGION 环境变量的值
  • access_key_id: 来自你 .env 文件中 STORAGE_TENANT_ID 环境变量的值
  • secret_access_key: 来自 ANON_KEY 环境变量的值
  • session_token: 一个有效的用户 JWT

使用 aws-sdk 库的示例:

🌐 Example using the aws-sdk library:

1
import { S3Client } from '@aws-sdk/client-s3'
2
3
const {
4
data: { session },
5
} = await supabase.auth.getSession()
6
7
const client = new S3Client({
8
forcePathStyle: true,
9
region: 'stub', // REGION in .env
10
endpoint: 'http://<your-domain>/storage/v1/s3', // Edit <your-domain>
11
credentials: {
12
accessKeyId: 'stub', // STORAGE_TENANT_ID in .env
13
secretAccessKey: 'your-anon-key', // ANON_KEY in .env
14
sessionToken: session.access_token,
15
},
16
})

故障排除 #

🌐 Troubleshooting

签名不匹配错误 #

🌐 Signature mismatch errors

S3 客户端使用访问密钥 ID 和密钥来签署请求。如果你看到 SignatureDoesNotMatch,请检查你的 .env 文件中的 REGIONS3_PROTOCOL_ACCESS_KEY_IDS3_PROTOCOL_ACCESS_KEY_SECRET 是否与你的 S3 客户端使用的一致。

🌐 S3 clients sign requests using the access key ID and secret. If you see SignatureDoesNotMatch, verify that the REGION, S3_PROTOCOL_ACCESS_KEY_ID and S3_PROTOCOL_ACCESS_KEY_SECRET in your .env file match what your S3 client is using.

如果你使用自定义反向代理:使用新的 API 密钥和认证 配置时,请求到 Storage 应该转发到 API 网关以便正确处理。如果你仍然使用旧版 API 密钥并直接代理到 Storage,确保你的代理设置了 X-Forwarded-Prefix 头为 /storage/v1,这样才能正确生成签名 URL。无论哪种情况,STORAGE_PUBLIC_URL 都必须在 docker-compose.yml设置正确

在 Cloudflare R2 上的 TUS 上传错误 #

🌐 TUS upload errors on Cloudflare R2

如果可续传(TUS)上传遇到 HTTP 500 错误并显示关于 x-amz-tagging 的信息,请将 TUS_ALLOW_S3_TAGS: "false" 添加到存储服务环境中。Cloudflare R2 并没有实现这个 S3 功能。

🌐 If resumable (TUS) uploads fail with HTTP 500 and a message about x-amz-tagging, add TUS_ALLOW_S3_TAGS: "false" to the storage service environment. Cloudflare R2 does not implement this S3 feature.

上传被拒绝 #

🌐 Permission denied on uploads

将存储桶设置为“公开”只允许未认证的下载。上传始终被阻止,除非你在 storage.objects 表上创建 RLS 策略。到 Studio 中的 存储 > 文件 > 策略,为相应的角色创建允许 INSERT 的策略。

🌐 Setting a bucket to "Public" only allows unauthenticated downloads. Uploads are always blocked unless you create an RLS policy on the storage.objects table. Go to Storage > Files > Policies in Studio and create a policy that allows INSERT for the appropriate roles.

上传的 URL 指向本地主机 #

🌐 Upload URLs point to localhost

如果浏览器上传失败(CORS 或混合内容错误),请检查你 .env 文件中的 SUPABASE_PUBLIC_URL 是否与你的实际域名和协议匹配,而不是 http://localhost:8000

🌐 If uploads from a browser fail (CORS or mixed content errors), check that SUPABASE_PUBLIC_URL in your .env file matches your actual domain and protocol - not http://localhost:8000.

额外资源 #

🌐 Additional resources