S3
S3 Buckets
podman:s3-setup creates your app's S3 buckets and adds a CORS policy to the ones browsers read from. It uses the S3 API directly, so you don't need the aws CLI.
Requirement: the AWS SDK
Install aws/aws-sdk-php. It isn't included by default because it's large and many apps don't use S3:
composer require aws/aws-sdk-php
Without it, podman:s3-setup shows an error. Other commands still work.
Credentials
The command uses the s3 disk from config/filesystems.php (key, secret, region, endpoint, use_path_style_endpoint). There's nothing extra to configure. It works with AWS S3 and S3-compatible services that support signed URLs, like MinIO, RustFS and Garage.
Configuring buckets
Both lists are empty by default, so the command does nothing until you add buckets:
's3_buckets' => env('PODMAN_S3_BUCKETS', [
'local', 'conversions', 'segments', 'secrets',
]),
's3_cors_buckets' => env('PODMAN_S3_CORS_BUCKETS', [
'conversions', 'segments', 'secrets',
]),
| Key | Purpose |
|---|---|
s3_buckets |
Buckets to create. Buckets that already exist are skipped. |
s3_cors_buckets |
Buckets that get the CORS policy. Each must also be in s3_buckets. |
Both take a PHP array or a comma-separated string.
The CORS policy
The policy comes from the s3 preset's cors.json: your published copy in containers/stubs/s3/ if it exists, otherwise the bundled one. No podman:generate is needed:
php artisan podman:publish s3
php artisan podman:s3-setup
Edit containers/stubs/s3/cors.json. It uses the standard S3 CORS format:
{
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["Content-Length", "Content-Range", "Accept-Ranges", "ETag"],
"MaxAgeSeconds": 7200
}
]
}
Buckets that the browser loads from directly (<img>, <video>, fetch()) need this. Buckets only used by the server, such as by queued jobs, usually don't.
Usage
php artisan podman:s3-setup
It creates the buckets, then adds CORS to s3_cors_buckets:
Creating buckets...
-> local
-> conversions
-> segments
-> secrets
Applying CORS policy...
-> conversions
-> segments
-> secrets
Done.
