Somewhile ago I had to solve a problem related to dynamic disks configuration for a SAAS project that right now are running with Laravel 8.
We have to import these files in our systems and ofcourse we need to have the report after each import, we wonna also the ability to get these files from the disk A archive in disk B and put the validation in disk C.
Ofcourse each files could be getted frok a different disk and each environment has different disk configuration (local, staging, uat, preprod, prod)
The first solution for me was to create 3 disk in the config/filesystems.php
file with the configuration of all disks parametrized and stored in the .env
file.
But what's happen if we wan't to add more disks? We should add another disk in our configuration file and redeploy for have it applied.
Due this limitation I exclude this solution, since will require a new deploy each time we have to add a new disk for a new file.
The working solution for me was move all (dynamics) disks configuration in the database, in this way if I've to add a new disk I can just add one record with the disks configuration and it will be ready to be used in the entire application (without deploy).
For make this solution I make the following files in laravel project:
app/Providers/AppServiceProvider.php
filefor create the model and the migration I used:
1php artisan make:model FileSystem -m
That command created for me the model and the migration file.
The content of the migration file (database/migrations/2022_11_24_133707_create_filesystems_table.php
) are the following
1<?php 2 3use Illuminate\Database\Migrations\Migration; 4use Illuminate\Database\Schema\Blueprint; 5use Illuminate\Support\Facades\Schema; 6 7return new class extends Migration { 8 public function up() 9 {10 Schema::create('filesystems', function (Blueprint $table) {11 $table->id();12 13 $table->string('name');14 $table->jsonb('configuration')->nullable();15 $table->string('environment');16 17 $table->timestamps();18 $table->softDeletes();19 });20 }21 22 public function down()23 {24 Schema::dropIfExists('filesystems');25 }26};
The content of the model file (app/Models/FileSystem.php
) are the following:
1<?php 2 3namespace App\Models; 4 5use Illuminate\Database\Eloquent\Model; 6use Illuminate\Database\Eloquent\SoftDeletes; 7 8class FileSystem extends Model 9{10 use SoftDeletes;11 12 protected $table = 'filesystems';13 14 protected $fillable = [15 'provider',16 'name',17 'environment',18 'configuration',19 ];20 21 protected $casts = [22 'configuration' => 'json',23 ];24}
Now that you have the content of both files we can go in the app/Providers/AppServiceProvider.php
file that will containts the code for load dynamically our disks in the application.
1<?php 2 3namespace App\Providers; 4 5use App\Models\FileSystem; 6use Illuminate\Support\ServiceProvider; 7 8class AppServiceProvider extends ServiceProvider 9{10 public function register()11 {12 $this->booted(function () {13 $this->loadFilesystemsConfigurations();14 });15 }16 17 private function loadFilesystemsConfigurations(): void18 {19 FileSystem::query()20 ->where('environment', config('app.env'))21 ->cursor()22 ->each(fn(FileSystem $disk) => config([23 'filesystems.disks.' . $disk->name => $disk->configuration,24 ]));25 }26}
With this solution I now can add infinite disk to my application without deploy the entire application.
I hope that this solution can help you and reduce the time waste.