Using Minio on Laravel + Vapor Locally

Published in Laravel NovaLaravel on Nov 19, 2020

Testing Laravel Vapor application with file uploads locally can be tricky. It is possible to setup S3 bucket to receive file from localhost by adding required CORS configuration but now you have the alternative of using Minio.

Minio S3 Compatibility

Prequisite

  • Setup laravel/vapor-core using Composer.
  • Setup laravel-vapor using NPM to allow file uploading.

Setup Minio

You can setup Minio locally using Docker or Homestead, however for this demonstration I will be using Takeout. Remember that you need to update config/filesystems.php to include minio disk configuration:

        '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' => env('AWS_USE_PATH_STYLE_ENDPOINT', true),
        ],

Also don't forget to update .env:

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"
AWS_USE_PATH_STYLE_ENDPOINT=(true)

Setup Laravel

Next we need to setup Laravel to authorize file uploads. You can refer to Storage > Authorization documentation. For testing you can just do the following on AppServiceProvider:

if ($this->app->isLocal()) {
    Gate::define('uploadFiles', fn ($user) => true);
}

Finally you need to map SignedStorageUrlController with the following files:

use App\Http\Controllers\SignedStorageUrlController;
use Laravel\Vapor\Contracts\SignedStorageUrlController as SignedStorageUrlControllerContract;

if ($this->app->isLocal()) {
    $this->app->singleton(
        SignedStorageUrlControllerContract::class, 
        SignedStorageUrlController::class
    );
}

And the following Gist should be published to app/Http/Controller/SignedStorageUrlController.php: