platformcommunity/flysystem-bunnycdn
Laravel Flysystem adapter for BunnyCDN Storage. Use BunnyCDN as a filesystem disk for uploads and file management, with support for common Flysystem operations like read/write, delete, directories, and URL generation for serving assets via BunnyCDN.
## Getting Started
### Minimal Setup
1. **Install the package** via Composer:
```bash
composer require platformcommunity/flysystem-bunnycdn
Publish the config (optional but recommended):
php artisan vendor:publish --provider="PlatformCommunity\FlysystemBunnycdn\FlysystemBunnycdnServiceProvider" --tag="config"
This generates config/filesystems.php with a bunnycdn disk entry.
Configure config/filesystems.php:
'disks' => [
'bunnycdn' => [
'driver' => 'bunnycdn',
'key' => env('BUNNYCDN_ACCESS_KEY'),
'secret' => env('BUNNYCDN_SECRET_KEY'),
'endpoint' => env('BUNNYCDN_ENDPOINT', 'https://storage.bunnycdn.com'),
'bucket' => env('BUNNYCDN_BUCKET'),
'region' => env('BUNNYCDN_REGION', 'auto'), // Optional: 'auto', 'us', 'eu', etc.
'use_path_style_endpoints' => env('BUNNYCDN_USE_PATH_STYLE', false),
'options' => [
// Custom SDK options (e.g., timeout, retries)
'connect_timeout' => 30,
],
],
],
Set environment variables in .env:
BUNNYCDN_ACCESS_KEY=your_access_key
BUNNYCDN_SECRET_KEY=your_secret_key
BUNNYCDN_BUCKET=your_bucket_name
First use case: Upload a file via Laravel’s Storage facade:
use Illuminate\Support\Facades\Storage;
Storage::disk('bunnycdn')->put('path/to/file.txt', 'Hello, BunnyCDN!');
Storage::disk('bunnycdn')->put('folder/file.jpg', file_get_contents('local.jpg'));
// Or with a stream:
Storage::disk('bunnycdn')->writeStream('folder/file.jpg', fopen('local.jpg', 'r'));
$contents = Storage::disk('bunnycdn')->get('folder/file.jpg');
Storage::disk('bunnycdn')->download('folder/file.jpg');
Storage::disk('bunnycdn')->delete('folder/file.jpg');
$files = Storage::disk('bunnycdn')->files('folder/');
$directories = Storage::disk('bunnycdn')->directories('folder/');
Generate public URLs for CDN delivery:
$url = Storage::disk('bunnycdn')->url('folder/file.jpg');
// Output: e.g., "https://storage.bunnycdn.com/your-bucket/folder/file.jpg"
For private files, use temporary URLs or signed URLs (see Gotchas).
hasFile, hasMany):
use Illuminate\Database\Eloquent\Casts\Attribute;
public function getFileUrlAttribute()
{
return Storage::disk('bunnycdn')->url($this->file_path);
}
public function handle()
{
Storage::disk('bunnycdn')->put('processed/' . $this->fileName, $this->processFile());
}
config/media-library.php:
'default_disk' => 'bunnycdn',
Set custom metadata (e.g., for caching or ACLs):
Storage::disk('bunnycdn')->put('file.jpg', $contents, [
'Cache-Control' => 'public, max-age=31536000',
'Content-Type' => 'image/jpeg',
]);
Create symlinks for logical file organization:
Storage::disk('bunnycdn')->createSymlink('original.jpg', 'alias.jpg');
Override disk settings per request or tenant:
$disk = Storage::build([
'driver' => 'bunnycdn',
'bucket' => 'tenant-specific-bucket',
'key' => config('services.bunnycdn.tenant_key'),
]);
Listen to file system events (e.g., storage:file:created):
use PlatformCommunity\FlysystemBunnycdn\Events\FileCreated;
FileCreated::listen(function ($event) {
// Log or notify when a file is uploaded
});
Access the underlying Flysystem adapter for low-level operations:
$adapter = Storage::disk('bunnycdn')->getAdapter();
$file = $adapter->read('file.txt');
Generate time-limited URLs for private files:
$url = Storage::disk('bunnycdn')->temporaryUrl(
'private/file.jpg',
now()->addMinutes(15)
);
Credentials and Permissions
BUNNYCDN_ACCESS_KEY and BUNNYCDN_SECRET_KEY are correct and have sufficient permissions.Endpoint Configuration
use_path_style_endpoints: true in the config.Region Mismatches
region setting matches your BunnyCDN zone (e.g., us, eu, auto).Large File Uploads
'options' => [
'multipart_upload_size' => 10 * 1024 * 1024, // 10MB
],
CORS Issues
Case Sensitivity
Enable SDK Debugging
Add this to your config/filesystems.php under the options array:
'debug' => true,
Check Laravel logs for BunnyCDN SDK responses.
Check HTTP Status Codes
Use Storage::disk('bunnycdn')->getAdapter()->getMetadata('file.txt') to inspect HTTP errors.
Validate Bucket Existence Ensure the bucket exists and is accessible. Test with:
curl -X PUT -H "AccessKey: $BUNNYCDN_ACCESS_KEY" -H "SecretKey: $BUNNYCDN_SECRET_KEY" \
"https://storage.bunnycdn.com/$BUNNYCDN_BUCKET/test.txt"
Network Timeouts
Increase timeouts in options if you encounter timeouts:
'options' => [
'connect_timeout' => 60,
'timeout' => 60,
],
Custom Storage Events Extend the package by listening to events:
// In EventServiceProvider
protected $listen = [
\PlatformCommunity\FlysystemBunnycdn\Events\FileCreated::class => [
\App\Listeners\LogBunnyUpload::class,
],
];
Override Adapter Logic Bind a custom adapter in a service provider:
use PlatformCommunity\FlysystemBunnycdn\BunnycdnAdapter;
$this->app->bind('bunnycdn', function ($app) {
return new BunnycdnAdapter(
$app['config']['filesystems.disks.bunnycdn'],
new \Bunny\Storage\Client($app['config']['filesystems.disks.bunnycdn'])
);
});
Add Custom Metadata Extend the adapter to support additional metadata:
How can I help you explore Laravel packages today?