-
-
Save crynobone/c5f89034d58598d6c60730e97af60333 to your computer and use it in GitHub Desktop.
Using Minio for Laravel Vapor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FILESYSTEM_DRIVER=minio | |
FILESYSTEM_CLOUD=minio | |
AWS_ACCESS_KEY_ID=minioadmin | |
AWS_SECRET_ACCESS_KEY=minioadmin | |
AWS_DEFAULT_REGION=us-east-1 | |
AWS_BUCKET=local | |
AWS_ENDPOINT=http://127.0.0.1:9000 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Providers; | |
use Illuminate\Support\Facades\Gate; | |
use Illuminate\Support\ServiceProvider; | |
class AppServiceProvider extends ServiceProvider | |
{ | |
/** | |
* Register any application services. | |
* | |
* @return void | |
*/ | |
public function register() | |
{ | |
// | |
} | |
/** | |
* Bootstrap any application services. | |
* | |
* @return void | |
*/ | |
public function boot() | |
{ | |
$this->app->singleton( | |
\Laravel\Vapor\Contracts\SignedStorageUrlController::class, | |
\App\Http\Controllers\SignedStorageUrlController::class | |
); | |
Gate::define('uploadFiles', function ($user) { | |
return true; | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
return [ | |
/* | |
|-------------------------------------------------------------------------- | |
| Default Filesystem Disk | |
|-------------------------------------------------------------------------- | |
| | |
| Here you may specify the default filesystem disk that should be used | |
| by the framework. The "local" disk, as well as a variety of cloud | |
| based disks are available to your application. Just store away! | |
| | |
*/ | |
'default' => env('FILESYSTEM_DRIVER', 'local'), | |
/* | |
|-------------------------------------------------------------------------- | |
| Default Cloud Filesystem Disk | |
|-------------------------------------------------------------------------- | |
| | |
| Many applications store files both locally and in the cloud. For this | |
| reason, you may specify a default "cloud" driver here. This driver | |
| will be bound as the Cloud disk implementation in the container. | |
| | |
*/ | |
'cloud' => env('FILESYSTEM_CLOUD', 's3'), | |
/* | |
|-------------------------------------------------------------------------- | |
| Filesystem Disks | |
|-------------------------------------------------------------------------- | |
| | |
| Here you may configure as many filesystem "disks" as you wish, and you | |
| may even configure multiple disks of the same driver. Defaults have | |
| been setup for each driver as an example of the required options. | |
| | |
| Supported Drivers: "local", "ftp", "sftp", "s3" | |
| | |
*/ | |
'disks' => [ | |
'local' => [ | |
'driver' => 'local', | |
'root' => storage_path('app'), | |
], | |
'public' => [ | |
'driver' => 'local', | |
'root' => storage_path('app/public'), | |
'url' => env('APP_URL').'/storage', | |
'visibility' => 'public', | |
], | |
's3' => [ | |
'driver' => 's3', | |
'key' => env('AWS_ACCESS_KEY_ID'), | |
'secret' => env('AWS_SECRET_ACCESS_KEY'), | |
'region' => env('AWS_DEFAULT_REGION'), | |
'bucket' => env('AWS_BUCKET'), | |
'url' => env('AWS_URL'), | |
'endpoint' => env('AWS_ENDPOINT'), | |
], | |
'minio' => [ | |
'driver' => 's3', | |
'key' => env('AWS_ACCESS_KEY_ID'), | |
'secret' => env('AWS_SECRET_ACCESS_KEY'), | |
'region' => env('AWS_DEFAULT_REGION'), | |
'bucket' => env('AWS_BUCKET'), | |
'endpoint' => env('AWS_ENDPOINT'), | |
'url' => env('AWS_URL'), | |
'use_path_style_endpoint' => true, | |
], | |
], | |
/* | |
|-------------------------------------------------------------------------- | |
| Symbolic Links | |
|-------------------------------------------------------------------------- | |
| | |
| Here you may configure the symbolic links that will be created when the | |
| `storage:link` Artisan command is executed. The array keys should be | |
| the locations of the links and the values should be their targets. | |
| | |
*/ | |
'links' => [ | |
public_path('storage') => storage_path('app/public'), | |
], | |
]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Aws\S3\S3Client; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\Gate; | |
use Illuminate\Support\Str; | |
use InvalidArgumentException; | |
use Laravel\Vapor\Contracts\SignedStorageUrlController as SignedStorageUrlControllerContract; | |
class SignedStorageUrlController extends \Illuminate\Routing\Controller implements SignedStorageUrlControllerContract | |
{ | |
/** | |
* Create a new signed URL. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @return \Illuminate\Http\Response | |
*/ | |
public function store(Request $request) | |
{ | |
Gate::authorize('uploadFiles', [ | |
$request->user(), | |
$bucket = $request->input('bucket') ?: config('filesystems.disks.minio.bucket'), | |
]); | |
$client = $this->storageClient(); | |
$uuid = (string) Str::uuid(); | |
$signedRequest = $client->createPresignedRequest( | |
$this->createCommand($request, $client, $bucket, $key = ('tmp/'.$uuid)), | |
'+10 minutes' | |
); | |
return response()->json([ | |
'uuid' => $uuid, | |
'bucket' => $bucket, | |
'key' => $key, | |
'url' => (string) $signedRequest->getUri(), | |
'headers' => $this->headers($request, $signedRequest), | |
], 201); | |
} | |
/** | |
* Create a command for the PUT operation. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param \Aws\S3\S3Client $client | |
* @param string $bucket | |
* @param string $key | |
* @return \Aws\Command | |
*/ | |
protected function createCommand(Request $request, S3Client $client, $bucket, $key) | |
{ | |
return $client->getCommand('putObject', array_filter([ | |
'Bucket' => $bucket, | |
'Key' => $key, | |
])); | |
} | |
/** | |
* Get the headers that should be used when making the signed request. | |
* | |
* @param \Illuminate\Http\Request $request | |
* @param \GuzzleHttp\Psr7\Request | |
* @return array | |
*/ | |
protected function headers(Request $request, $signedRequest) | |
{ | |
return array_merge( | |
$signedRequest->getHeaders(), | |
[ | |
'Content-Type' => $request->input('content_type') ?: 'application/octet-stream', | |
] | |
); | |
} | |
/** | |
* Get the S3 storage client instance. | |
* | |
* @return \Aws\S3\S3Client | |
*/ | |
protected function storageClient() | |
{ | |
$config = [ | |
'region' => config('filesystems.disks.minio.region'), | |
'version' => 'latest', | |
'use_path_style_endpoint' => true, | |
'url' => config('filesystems.disks.minio.endpoint'), | |
'endpoint' => config('filesystems.disks.minio.endpoint'), | |
'credentials' => [ | |
'key' => config('filesystems.disks.minio.key'), | |
'secret' => config('filesystems.disks.minio.secret'), | |
], | |
]; | |
return S3Client::factory($config); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's actually quite simple to setup
minio
for Laravel Vapor storage when running it locally. But you probably needs to read through Vapor documentation before using this:laravel/vapor-core
laravel-vapor
npm for file uploading (using under Laravel Nova doesn't require this).uploadFiles
based on Vapor documentation (as shown inAppServiceProvider.php
sample code).minio
, personally I usetightenco/takeout
to set minio but it should be rather straightforward using other approach.Now, what's important is to have an alternative
SignedStorageUrlController
sinceminio
has minor different compared to hows3
prepares pre-signed request. Finally it's just a matter for overriding the default route and configurations.