Managed AddonsObject Storage (S3)

Object Storage (S3)

S3-compatible object storage for uploads, assets, and backups. Provisioning an s3 addon also creates a public-read bucket named default, so you can serve files with zero extra setup.

Provision

lizard add s3

The first S3 addon is named s3, so ${{s3.S3_ENDPOINT}} and friends work immediately.

Environment variables

VariableDescription
S3_ENDPOINTS3-compatible endpoint URL
S3_DEFAULT_BUCKETThe auto-created bucket name (default)
S3_ACCESS_KEY_IDAccess key
S3_SECRET_ACCESS_KEYSecret key
S3_REGIONRegion

Connect a service

lizard secrets set \
  S3_ENDPOINT='${{s3.S3_ENDPOINT}}' \
  S3_DEFAULT_BUCKET='${{s3.S3_DEFAULT_BUCKET}}' \
  S3_ACCESS_KEY_ID='${{s3.S3_ACCESS_KEY_ID}}' \
  S3_SECRET_ACCESS_KEY='${{s3.S3_SECRET_ACCESS_KEY}}' \
  S3_REGION='${{s3.S3_REGION}}' \
  --service api
lizard redeploy --service api

Using an AWS SDK

The endpoint is S3-compatible. Set path-style addressing:

import { S3Client } from "@aws-sdk/client-s3";
 
const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: process.env.S3_REGION,
  forcePathStyle: true, // required
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY_ID!,
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  },
});

Public files

Objects in any public bucket are served without authentication two ways:

  1. Gateway URL (shown in the dashboard):
    https://s3-<region>.onlizard.com/<addonId>/<bucket>/<key>
  2. Platform proxy (the dashboard host, with long-lived immutable cache headers):
    <dashboard-host>/api/s3/<addonId>/public/<bucket>/<key>

Anything uploaded to the default bucket is immediately public at:

<dashboard-host>/api/s3/<addonId>/public/default/<key>

Browse objects

Open the S3 browser in the dashboard (lizard open) to upload, download, and manage objects and buckets.

Bucket ACL changes (making a bucket public/private) aren’t on the CLI yet — manage them from the dashboard.

Grow storage

lizard scale --service s3 --storage 16384