Object Storage Integration on Zerops
Keywords
object storage, s3, minio, aws, upload, files, media, storage integration, flysystem, boto3, aws-sdk, path style, bucket, persistent files
TL;DR
Zerops Object Storage is S3-compatible (MinIO). Always set AWS_USE_PATH_STYLE_ENDPOINT: true. Use env var references ${storage_*} for credentials. Container filesystem is lost on deploy — use Object Storage for any files that must persist across deployments.
Environment Variables
When you create an Object Storage service, Zerops auto-generates these env vars (prefix with hostname for cross-service access, e.g. ${storage_apiUrl}):
| Variable | Description |
|---|---|
apiUrl | S3 endpoint URL (accessible from Zerops and remotely) |
accessKeyId | S3 access key |
secretAccessKey | S3 secret key |
bucketName | Auto-generated bucket name (hostname + random prefix, immutable) |
quotaGBytes | Bucket quota in GB |
projectId | Project ID (Zerops-generated) |
serviceId | Service ID (Zerops-generated) |
hostname | Service hostname |
Reference them in zerops.yml run.envVariables:
Path Style Endpoint (Required)
Zerops uses MinIO which requires path-style URLs (not virtual-hosted):
Every S3 client must be configured for path-style access.
Framework Integration
PHP (Laravel — Flysystem)
Package: league/flysystem-aws-s3-v3
Node.js (AWS SDK v3)
Package: @aws-sdk/client-s3
Python (boto3)
Package: boto3
Java (AWS SDK)
S3Client s3 = S3Client.builder()
.endpointOverride(URI.create(System.getenv("S3_ENDPOINT")))
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(true) // REQUIRED
.build())
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(
System.getenv("S3_ACCESS_KEY"),
System.getenv("S3_SECRET_KEY"))))
.region(Region.US_EAST_1)
.build();
import.yaml Definition
Predefined policies (objectStoragePolicy):
private— no anonymous access (documents, backups)public-read— anonymous list + get (media, avatars, static assets)public-objects-read— anonymous get only, no listing (direct links only)public-write— anonymous put onlypublic-read-write— full anonymous access
Custom policy: use objectStorageRawPolicy with IAM Policy JSON instead (template var {{ .BucketName }} available).
Each service = one bucket (auto-named, immutable). Need multiple buckets? Create multiple services.
When to Use Object Storage
| Scenario | Use Object Storage? |
|---|---|
| User uploads (avatars, documents) | Yes — lost on deploy |
| Media files (images, videos) | Yes — serve via public URL |
| Build artifacts | No — deploy via zerops.yaml |
| Temporary files | No — container disk is fine |
| Logs | No — use Zerops logging |
| Database dumps | Yes — for backup storage |
Gotchas
forcePathStyle: true/AWS_USE_PATH_STYLE_ENDPOINT: trueis REQUIRED: Zerops uses MinIO which doesn't support virtual-hosted style- Container filesystem is replaced on deploy: Files on disk survive restarts but are lost when a new container is created (deploy, scale-up). Always use Object Storage for persistent data
- Region is required but ignored: Set
us-east-1— MinIO ignores it but SDKs require it - Public URL format:
{apiUrl}/{bucketName}/path/to/file - Independent infrastructure: Object Storage runs on separate infra from other services — accessible from Zerops and remotely over internet
- One bucket per service: Bucket name auto-generated (hostname + random prefix), cannot be changed. Need multiple buckets? Add more object-storage services
- No Zerops backup: Object Storage is not covered by the Zerops backup system
- No autoscaling: Quota (1-100 GB) must be set manually, changeable in GUI after creation
See Also
- zerops://themes/services — managed service reference (Object Storage section)
- zerops://themes/core — import.yml schema
- zerops://guides/environment-variables — cross-service env var references