How to store the disk configuration in the database Published in Laravel, PHP on Nov 25, 2022

How to store the disk configuration in the database

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.

Requirement

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)

Solutions

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:

  • create a new migration
  • create a new model
  • adding some function in the app/Providers/AppServiceProvider.php file

for 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(): void
18 {
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.