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 :