From zeabur
Deploys S3-compatible object storage (MinIO, RustFS) to Zeabur via templates and integrates with apps using internal endpoints, credentials, and env vars.
npx claudepluginhub zeabur/agent-skills --plugin zeaburThis skill uses the workspace's default tool permissions.
> **Always use `npx zeabur@latest` to invoke Zeabur CLI.** Never use `zeabur` directly or any other installation method. If `npx` is not available, install Node.js first.
Guides AWS S3 bucket creation, object operations, versioning, encryption, public access control, lifecycle policies, and storage classes using CLI and boto3.
Manages Cloudflare R2 S3-compatible object storage in Workers: bucket creation, bindings, uploads/downloads, CORS, presigned URLs, multipart uploads. Fixes R2_ERROR and CORS issues.
Manages AWS S3 buckets with versioning, encryption, access control, lifecycle policies, and replication. Use for object storage, static sites, and data lakes.
Share bugs, ideas, or general feedback.
Always use
npx zeabur@latestto invoke Zeabur CLI. Never usezeaburdirectly or any other installation method. Ifnpxis not available, install Node.js first.
Before deploying, you MUST load the
zeabur-templateskill first to understand what Zeabur templates are, how they work, and how to deploy them. This skill only covers object storage-specific integration — all template knowledge lives inzeabur-template.
Search for a storage template:
npx zeabur@latest template search minio -i=false --json
Pick the template with the highest deployment count.
For object storage, you need: S3 API endpoint (how to connect), access key + secret key (how to authenticate), and a bucket name.
service networknpx zeabur@latest service network --id <storage-service-id> -i=false
This shows:
hostname:port for the S3 API (e.g., minio.zeabur.internal:9000)MinIO and RustFS ports are HTTP type, so public access is via domain binding, not port forwarding. Bind a domain to the API port via the Dashboard to get an external S3 endpoint (e.g.,
https://minio-api.zeabur.app).
variable listnpx zeabur@latest variable list --id <storage-service-id> -i=false
This lists the access key, secret key, and other credentials.
variable list)| Variable | Description |
|---|---|
MINIO_USERNAME | Access Key ID (default: minio) |
MINIO_PASSWORD | Secret Access Key (auto-generated) |
MINIO_DEFAULT_BUCKET | Default bucket name (default: zeabur) |
MINIO_CONSOLE_URL | Web console URL |
Set these env vars on your app service:
S3_ENDPOINT=http://minio.zeabur.internal:9000
S3_ACCESS_KEY=${MINIO_USERNAME}
S3_SECRET_KEY=${MINIO_PASSWORD}
S3_BUCKET=zeabur
S3_REGION=us-east-1
S3_FORCE_PATH_STYLE=true
The S3 endpoint is not exposed as a variable — you must hardcode it using the internal hostname from
service network.
Bind a domain to the API port, then use that domain as endpoint:
# MinIO Client (mc)
mc alias set zeabur https://MINIO_API_DOMAIN MINIO_USERNAME MINIO_PASSWORD
mc ls zeabur/
mc cp local-file.txt zeabur/zeabur/
# AWS CLI
aws --endpoint-url https://MINIO_API_DOMAIN s3 ls
Open MINIO_CONSOLE_URL in a browser, login with MINIO_USERNAME / MINIO_PASSWORD. MinIO auto-creates a zeabur bucket on first boot.
variable list)| Variable | Description |
|---|---|
RUSTFS_USERNAME | Access Key ID (default: rustfs) |
RUSTFS_PASSWORD | Secret Access Key (auto-generated) |
Set these env vars on your app service:
S3_ENDPOINT=http://rustfs.zeabur.internal:9000
S3_ACCESS_KEY=${RUSTFS_USERNAME}
S3_SECRET_KEY=${RUSTFS_PASSWORD}
S3_BUCKET=my-bucket
S3_REGION=us-east-1
S3_FORCE_PATH_STYLE=true
The S3 endpoint is not exposed as a variable — you must hardcode it using the internal hostname from
service network. Also checkservice listfor the exact service name (may beRustFSnotrustfs).
You must create a bucket first — unlike MinIO, RustFS starts with zero buckets.
Bind a domain to the API port, then:
mc alias set zeabur https://RUSTFS_API_DOMAIN RUSTFS_USERNAME RUSTFS_PASSWORD
mc mb zeabur/my-bucket
mc ls zeabur/
Open the domain bound to port 9001 in a browser, login with RUSTFS_USERNAME / RUSTFS_PASSWORD. Create a bucket before your app can upload files.
All S3-compatible SDKs need: endpoint, access key, secret key, region, and forcePathStyle: true.
// Node.js (AWS SDK v3)
const { S3Client } = require("@aws-sdk/client-s3");
const s3 = new S3Client({
endpoint: process.env.S3_ENDPOINT,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
},
region: "us-east-1",
forcePathStyle: true,
});
# Python (boto3)
import boto3, os
s3 = boto3.client(
"s3",
endpoint_url=os.environ["S3_ENDPOINT"],
aws_access_key_id=os.environ["S3_ACCESS_KEY"],
aws_secret_access_key=os.environ["S3_SECRET_KEY"],
region_name="us-east-1",
)
// Go (aws-sdk-go-v2)
cfg, _ := config.LoadDefaultConfig(ctx,
config.WithRegion("us-east-1"),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""),
),
)
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String(endpoint)
o.UsePathStyle = true
})
forcePathStyle is required — Without it, S3 SDKs use virtual-hosted-style URLs (http://bucket.host:9000/key) which won't resolve. This is the #1 cause of "bucket not found" errors.zeabur bucket; RustFS does not. Create one via the console or mc mb.service network (internal) or the bound domain (external).${MINIO_USERNAME} etc. via the Zeabur Dashboard — the CLI has a known bug with ${} expansion.9000, console 9090. RustFS: API 9000, console 9001. Apps connect to the API port.