Storage

Configure local filesystem or S3-compatible object storage.

Penombre supports two storage backends: local filesystem (default) and S3-compatible object storage. Switch between them using the STORAGE_BACKEND environment variable.

Local storage (default)

Files are stored on the host filesystem at the path configured by STORAGE_PATH. The default is /data/storage, which maps to the storage_data Docker volume in the bundled compose.yaml.

No additional configuration is required. This is the recommended option for single-node deployments.

VariableDescriptionDefault
STORAGE_PATHAbsolute path to storage root/data/storage

To change the storage location, update STORAGE_PATH in your .env file and make sure the path is mounted in your container:

volumes:
  - /your/host/path:/data/storage

S3-compatible storage

Set STORAGE_BACKEND=s3 to store files in any S3-compatible service (AWS S3, Cloudflare R2, Backblaze B2, self-hosted Garage, etc.).

When STORAGE_BACKEND=s3 is set, S3_BUCKET, S3_ACCESS_KEY_ID, and S3_SECRET_ACCESS_KEY are required. The app will refuse to start if they are missing.

VariableDescriptionDefault
STORAGE_BACKENDlocal or s3local
S3_BUCKETBucket nameRequired
S3_ACCESS_KEY_IDAccess key IDRequired
S3_SECRET_ACCESS_KEYSecret access keyRequired
S3_ENDPOINTCustom endpoint URL (for non-AWS providers)/
S3_REGIONBucket regionus-east-1
S3_PATH_STYLEUse path-style URLs (true/false)false

S3_PATH_STYLE=true is required for most self-hosted providers (Garage, MinIO, etc.) that do not support virtual-hosted-style URLs.

Provider examples

STORAGE_BACKEND=s3
S3_BUCKET=my-penombre-bucket
S3_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
S3_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
S3_REGION=us-east-1
STORAGE_BACKEND=s3
S3_BUCKET=my-penombre-bucket
S3_ACCESS_KEY_ID=<r2-access-key-id>
S3_SECRET_ACCESS_KEY=<r2-secret-access-key>
S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
S3_REGION=auto
S3_PATH_STYLE=false
STORAGE_BACKEND=s3
S3_BUCKET=my-penombre-bucket
S3_ACCESS_KEY_ID=<b2-key-id>
S3_SECRET_ACCESS_KEY=<b2-application-key>
S3_ENDPOINT=https://s3.<region>.backblazeb2.com
S3_REGION=<region>
S3_PATH_STYLE=false
STORAGE_BACKEND=s3
S3_BUCKET=penombre
S3_ACCESS_KEY_ID=<garage-key-id>
S3_SECRET_ACCESS_KEY=<garage-secret-key>
S3_ENDPOINT=http://<garage-host>:3900
S3_REGION=garage
S3_PATH_STYLE=true

See Self-hosted with Garage below for a complete setup guide.

Self-hosted with Garage

Garage is a lightweight, open-source (AGPLv3) S3-compatible object store designed for self-hosted deployments. The bundled compose.yaml includes a pre-configured Garage service.

Using the bundled compose stack

The bundled development compose.yaml already includes a Garage service. To enable it, uncomment the S3 environment variables in your compose.yaml app service:

environment:
  - STORAGE_BACKEND=s3
  - S3_ENDPOINT=http://garage:3900
  - S3_REGION=garage
  - S3_BUCKET=penombre
  - S3_ACCESS_KEY_ID=GK0000000000000000cafe0000
  - S3_SECRET_ACCESS_KEY=cafecafe00000000000000000000000000000000000000000000000000000000
  - S3_PATH_STYLE=true

The Garage container initializes automatically on first start: it assigns a cluster layout, creates a fixed key pair, and creates the penombre bucket. No manual setup needed.

Custom Garage deployment

If you are running Garage separately, create a bucket and key pair using the Garage CLI:

# Assign layout (run once after first start)
garage layout assign -z dc1 -c 10G <node-id>
garage layout apply --version 1

# Create bucket
garage bucket create penombre

# Create access key
garage key create penombre-key

# Allow key to access bucket
garage bucket allow --read --write --owner penombre --key penombre-key

Then configure Penombre with the key ID and secret printed by garage key create.

Found an issue or want to contribute? Edit this page on GitHub

On this page