Skip to content
homeport

Docs · Configure

Storage

Open an environment’s Storage tab and choose Add storage. You get a private S3-compatible bucket for that environment, with a key that can reach it and nothing else, set as variables. Any S3 client or SDK works with it, and downloads are free.

The variables it sets

Both the names the AWS SDKs and Laravel read, and a plain set:

Storage variables
AWS_ACCESS_KEY_ID=…
AWS_SECRET_ACCESS_KEY=…
AWS_DEFAULT_REGION=auto
AWS_BUCKET=…
AWS_ENDPOINT=https://…
AWS_USE_PATH_STYLE_ENDPOINT=true

S3_BUCKET=…
S3_ENDPOINT=…
S3_REGION=auto
S3_ACCESS_KEY_ID=…
S3_SECRET_ACCESS_KEY=…

A Laravel app also gets FILESYSTEM_DISK=s3, so Storage::put() and uploads go to the bucket with no code changes. Install the S3 driver if you have not: composer require league/flysystem-aws-s3-v3.

Like a database’s, these variables are managed: they cannot be edited by hand, and storage cannot be added while you have a variable of one of these names already. Reset keys makes a new key, restarts the app with it, then revokes the old one.

Using it

  • The bucket is private. Serve files through your app, or hand out presigned URLs from your S3 SDK for direct downloads.
  • Each environment has its own bucket, so staging never writes to production’s files.
  • Empty bucket deletes every file in it, after you type its name. The bucket and its key stay.
Bun
import { S3Client } from 'bun'

const s3 = new S3Client({
  bucket: process.env.S3_BUCKET,
  endpoint: process.env.S3_ENDPOINT,
  accessKeyId: process.env.S3_ACCESS_KEY_ID,
  secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
})
await s3.write('hello.txt', 'Hello')

Public buckets

On a paid plan, an environment can also have a public bucket, beside its private one or alone. Every file in it is served to anyone at its own HTTPS address, which suits images, downloads and other assets. The whole bucket is public; a private bucket is never served.

  • Its variables have PUBLIC in their names, like AWS_PUBLIC_BUCKET and AWS_PUBLIC_URL, so they never replace the private bucket’s. It is never Laravel’s default disk: a plain Storage::put() can’t land where anyone can read it. Point an s3-public disk at it and use Storage::disk('s3-public').
  • It is billed like any bucket, and serving its files is free: reads are counted as reads.
  • Starter has 2 public buckets of up to 25 GB each, Growth 10 of up to 250 GB, Business as many as it uses.

Deleting and restoring

Deleting storage removes its variables and revokes its key at once, but keeps the files for 7 days. Until then, any of the team’s environments can restore it, with a new key. After 7 days the files are deleted for good.

What it costs

Storage prices
FreePaid plans
Buckets1 per Free teamOne per environment, as many as you need
Data storedUp to 1 GB$0.02 per GB-month
Writes and lists (Class A)100,000 a month$6 per million
Reads (Class B)1,000,000 a month$0.50 per million
Data outFreeFree
BilledNeverFrom your plan’s included usage first

10 GB of files with 100,000 uploads and a million reads a month comes to $0.20 + $0.60 + $0.50: $1.30, inside what any paid plan includes.

On Free

  • One bucket, never billed.
  • Past 100,000 writes in a calendar month, or while it holds 1 GB or more, it becomes read-only. Past 1,000,000 reads it is switched off until the 1st. The team’s owners are emailed, and no file is deleted.
  • Deleting files below 1 GB lets it write again. A paid plan lifts the limits at once.