Sitemap

Configuring Minio FilamentPHP and Filament Breezy in Laravel

2 min readMay 13, 2025

--

Install minio via docker-compose

docker-compose.yml

version: "3.8"
services:
minio:
image: quay.io/minio/minio:latest
command: server /mnt/data --console-address ":9001"
ports:
- 9000:9000
- 9001:9001
environment:
MINIO_ROOT_USER: youruser
MINIO_ROOT_PASSWORD: yourpassword
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
volumes:
- minio_data:/mnt/data
volumes:
minio_data:

login on WebUI : http://localhost:9001

create bucket for example : dev

create API key, for example :

  • access_key : your_access_id
  • secret_key_id : your_secret_access_id

dont forget install dependencies

composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies

publish laravel livewire config

php artisan livewire:publish --config

will be create config/livewire.php

'temporary_file_upload' => [
'disk' => 'local', // Example: 'local', 's3' | Default: 'default'
..................................
],

on .env

FILESYSTEM_DISK=s3
FILAMENT_FILESYSTEM_DISK=s3


AWS_ACCESS_KEY_ID=your_access_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_DEFAULT_REGION=ap-southeast-3
AWS_BUCKET=dev
AWS_USE_PATH_STYLE_ENDPOINT=true
AWS_URL=http://localhost:9000/dev
AWS_ENDPOINT=http://localhost:9000

makesure :

  • AWS_ENDPOINT : your minio BaseURL
  • AWS_URL : your minio BaseURL + bucket
  • AWS_USE_PATH_STYLE_ENDPOINT=true

on form resource :

Forms\Components\FileUpload::make('photo')
->disk(env('FILAMENT_FILESYSTEM_DISK', 's3'))->directory('photos')
->visibility('publico')

voila, success

then, we will configure laravel breezy

if you dont installed yet,

https://v2.filamentphp.com/plugins/breezy

composer require jeffgreco13/filament-breezy
php artisan breezy:install

create migration

php artisan make:migration add_avatar_url_column_to_users_table
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar_url')->nullable();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar_url');
});
}
};
php artisan migrate

create new Class BreezyCore in app/Filament/Plugins/BreezyCore

<?php

namespace App\Filament\Plugins;

use Filament\Forms;
class BreezyCore extends \Jeffgreco13\FilamentBreezy\BreezyCore
{
public function getAvatarUploadComponent()
{
$fileUpload = Forms\Components\FileUpload::make('avatar_url')
->disk(env('FILESYSTEM_DISK', 's3'))
->directory('avatars')
->label(__('filament-breezy::default.fields.avatar'))
->avatar();

return is_null($this->avatarUploadComponent) ? $fileUpload : $this->evaluate($this->avatarUploadComponent, namedInjections: [
'fileUpload' => $fileUpload,
]);
}
}

in User Model, add implements HasAvatars and implement it in function getFilamentAvatarUrl

<?php

namespace App\Models;
.................................
use Filament\Models\Contracts\HasAvatar;

class ResUser extends Authenticatable implements HasAvatar
{
.....................

public function getFilamentAvatarUrl(): ?string
{
$avatar_url = $this->avatar_url ? Storage::disk(env('FILESYSTEM_DISK', 's3'))
->url($this->avatar_url) : 'https://ui-avatars.com/api/?name='.urlencode($this->name);
return $avatar_url;
}
}

then add plugin in PanelProvider :

<?php

namespace App\Providers\Filament;
...................................
use App\Filament\Plugins\BreezyCore;

class AdminPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
......................
->plugins([
BreezyCore::make()
->myProfile(
shouldRegisterUserMenu: true, // Sets the 'account' link in the panel User Menu (default = true)
userMenuLabel: 'My Profile', // Customizes the 'account' link label in the panel User Menu (default = null)
shouldRegisterNavigation: true, // Adds a main navigation item for the My Profile page (default = false)
navigationGroup: 'Settings', // Sets the navigation group for the My Profile page (default = null)
hasAvatars: true, // Enables the avatar upload form component (default = false)
slug: 'my-profile' // Sets the slug for the profile page (default = 'my-profile')
)
->enableTwoFactorAuthentication(force: false)
])
.....................
}
}

Reference :

--

--

No responses yet