Object Storage (S3)
S3 Object Storage
stry keeps these files in S3-compatible object storage:
- Conversions: thumbnails and other generated images
Videos are played directly from the media disk. Their DASH and HLS segments are packaged on request and cached on the local /cache volume, and encryption keys are derived from APP_KEY, so neither needs a bucket.
Any S3 service that works with Laravel and supports signed URLs will do, such as AWS S3, MinIO, RustFS or Garage.
Setup
This guide uses RustFS.
1. Make sure RustFS is running:
systemctl --user start stry-rustfs
systemctl --user status stry-rustfs
With the development preset, the RustFS web console is available at http://localhost:9001. The production preset used in production doesn't make it available by default. To reach it through the app's reverse proxy, add it to the CaddySites::render() map in config/octane.php.
2. Run the setup command inside the app container. If you don't have a shell open yet, start one with lpod stry shell.
php artisan podman:s3-setup
The command uses the s3 disk from config/filesystems.php, which reads AWS_ENDPOINT, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY from .env. These must match the credentials of your S3 service.
It creates the buckets listed in podman.s3_buckets and applies the CORS policy to the buckets in podman.s3_cors_buckets. To change either list, set PODMAN_S3_BUCKETS or PODMAN_S3_CORS_BUCKETS in .env, or edit config/podman.php.
RustFS credentials
RustFS uses its own names for the same credentials:
RUSTFS_ACCESS_KEYis the same asAWS_ACCESS_KEY_IDRUSTFS_SECRET_KEYis the same asAWS_SECRET_ACCESS_KEY
RustFS reads them from the stry-rustfs-access-key and stry-rustfs-secret-key Podman secrets (see rustfs.quadlets). Set them with:
lpod stry-rustfs secrets
In production, always use strong, random values for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, and never reuse your development credentials. You can generate a secret key with:
openssl rand -hex 16
Put the new credentials in your .env file before you run the setup command.
All buckets are private. podman:s3-setup only creates the buckets and applies the CORS policy; it never makes a bucket public. Files are served with signed URLs, which carry their own credentials (AWS SigV4), so the buckets don't need public access.
CORS
Browsers check CORS even for signed URLs. If a bucket doesn't send an Access-Control-Allow-Origin header, the browser blocks the request. podman:s3-setup applies the CORS policy from the s3 preset's cors.json for you. That's containers/stubs/s3/cors.json if you published the preset, or the package default if you didn't.
To check the policy on a bucket:
aws s3api get-bucket-cors --bucket conversions
See also
- Production Setup: the full deployment guide
- Application Configuration: storage settings
- CLI Interaction: command-line tools
- Podman Quadlet: managing the containers
