zeabur-object-storage
Zeabur Object Storage Deployment & Integration
Always use
npx zeabur@latestto invoke Zeabur CLI. Never usezeaburdirectly or any other installation method. Ifnpxis not available, install Node.js first.
Deploy Object Storage
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.
- Default to MinIO if the user doesn't specify — most widely supported, built-in web console, auto-creates a default bucket.
- Recommend RustFS if the user wants lightweight/minimal or mentions RustFS specifically.
After Deployment: How to Connect
For object storage, you need: S3 API endpoint (how to connect), access key + secret key (how to authenticate), and a bucket name.
How to connect — service network
npx zeabur@latest service network --id <storage-service-id> -i=false
This shows:
- Private Networking — internal
hostname:portfor the S3 API (e.g.,minio.zeabur.internal:9000) - Public Networking — for HTTP ports, it will indicate you need to bind a domain to access externally
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).
How to authenticate — variable list
npx zeabur@latest variable list --id <storage-service-id> -i=false
This lists the access key, secret key, and other credentials.
MinIO
Credentials (from 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 |
Connect from app (same project)
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.
Connect from local machine
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
Web Console
Open MINIO_CONSOLE_URL in a browser, login with MINIO_USERNAME / MINIO_PASSWORD. MinIO auto-creates a zeabur bucket on first boot.
RustFS
Credentials (from variable list)
| Variable | Description |
|---|---|
RUSTFS_USERNAME |
Access Key ID (default: rustfs) |
RUSTFS_PASSWORD |
Secret Access Key (auto-generated) |
Connect from app (same project)
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.
Connect from local machine
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/
Web Console
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.
SDK Examples
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
})
Caveats
forcePathStyleis 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.- Create bucket before uploading (RustFS) — MinIO auto-creates a
zeaburbucket; RustFS does not. Create one via the console ormc mb. - S3 endpoint is not a template variable — Hardcode it using the hostname from
service network(internal) or the bound domain (external). - Variable references — Zeabur uses a flat namespace. Set
${MINIO_USERNAME}etc. via the Zeabur Dashboard — the CLI has a known bug with${}expansion. - Console vs API ports — MinIO: API
9000, console9090. RustFS: API9000, console9001. Apps connect to the API port.
More from zeabur/zeabur-claude-plugin
zeabur-deployment-logs
Use when viewing service runtime or build logs. Use when user says "show logs", "why did deploy fail", "check build output", or "debug runtime error".
56zeabur-restart
Use when restarting a Zeabur service. Use when user says "restart", "reboot service", or "service is stuck/frozen".
55zeabur-template
Use when creating, editing, validating, or troubleshooting a Zeabur template YAML. Use when converting docker-compose to Zeabur template. Do NOT use for deploying templates (use zeabur-template-deploy instead).
54zeabur-domain-url
Use when services need public URL for redirects or CORS. Use when WEB_URL or similar has trailing slash issues. Use when user reports "redirect goes to wrong URL", "CORS error", or "trailing slash problem". Also use when user says "add domain", "set up domain", "bind domain", "create domain", or "manage domains" for a Zeabur service.
53zeabur-variables
Use for ALL Zeabur environment variable operations — create, list, update, delete, or troubleshoot. Use when user says "set env var", "add variable", "create variable", "update variable", "delete variable", "change env var", or "why is my variable empty". Also use when variables are empty or SERVICE_NOT_FOUND errors.
52zeabur-update-service
Use when modifying service config without full redeploy. Use when updating env vars and restarting single service. Use when user says "change env var", "update config", "fix variable without redeploying", "upgrade service version", "update image tag", or "change service tag".
50