Laravel com MinIO: uma solução para o S3 em ambiente de desenvolvimento

Leonardo Henrique Steil
4 min readAug 2, 2021

--

Fala pessoal, beleza?

Estou desenvolvendo uma aplicação utilizando o framework Laravel onde surgiu a necessidade de fazer o upload de arquivos. Como o deploy da aplicação seria em um ambiente na AWS, o armazenamento dos arquivos, por conveniência será no Amazon S3.

Com isso, pensei em criar um bucket que seria utilizado no ambiente de desenvolvimento, mas pensando no longo prazo, essa não é uma alternativa muito viável. Então, lendo a documentação do Laravel conheci o MinIO.

O MinIO é um serviço open-source de Object Store compatível com o Amazon S3. Com ele podemos simular localmente o S3, utilizando o File Storage do Laravel da mesma forma que seria utilizado em um ambiente de produção.

Neste artigo não vou me aprofundar na instalação do MinIO. Para quem utiliza Docker no ambiente de desenvolvimento, o MinIO pode ser inserido no docker-compose. Atualmente o Laravel conta com o Laravel Sail, que é muito útil pra quem quer utitilizar o Docker. Também é possível utilizá-lo junto com a instalação do Laravel via Homestead. Bem como instalá-lo de forma direta na sua máquina. Abaixo segue a instalação do MinIO utilizando-se o Laravel Sail para uma nova aplicação:

curl -s "https://laravel.build/example-app?with=minio" | bash

Para maiores informações sobre os serviços oferecidos pelo Sail é possível consultar os links: https://laravel.com/docs/8.x/installation#choosing-your-sail-services e https://laravel.com/docs/8.x/sail

O primeiro passo após a instalação é inserir as credencias utilizadas pelo MinIO dentro do .env. Essas informações podem ser encontradas em https://laravel.com/docs/8.x/sail#file-storage.

FILESYSTEM_DRIVER=s3
AWS_ACCESS_KEY_ID=sail
AWS_SECRET_ACCESS_KEY=password
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=local
AWS_ENDPOINT=http://minio:9000
AWS_URL=http://localhost:9000/local
AWS_USE_PATH_STYLE_ENDPOINT=true

Além das informações presentes nas documentações do Laravel, precisei buscar mais na web sobre como fazer a ferramenta funcionar no meu ambiente local. Não existem muitas informações sobre, então precisei experimentar algumas configurações e cheguei no que está descrito acima.

Na variavel AWS_URL, precisei colocar o bucket no final. Por algum motivo que ainda não descobri, quando estou buscando informações, a variável AWS_BUCKET está sendo ignorada. A variável AWS_URL é utilizada na comunicação entre o localhost e o serviço do MinIO. Já a AWS_ENDPOINT, é utilizada pelo container do PHP para comunicação com o container do MinIO.

Atenção: 1. se instalado pelo Laravel Sail, a porta para acessar o MinIO será a 9000, porém isso pode variar de acordo com sua instalação. 2. é importante salientar que essa configuração básica pode variar um pouco de acordo com a instalação do MinIO.

Com isso configurado, então teremos acesso a plataforma através http://localhost:9000/minio/. Abaixo temos duas imagens da plataforma.

MinIO: página de login
Tela de login do MinIO
Tela Inicial do MinIO

Na tela inicial, no botão da parte baixa da direita, você deve criar um um bucket com o mesmo nome do valor da config AWS_BUCKET.

Bucket local criado

O MinIO permite realizar o permissionamento da mesma forma que o AWS S3. Porém, para fins práticos e de estudo, vamos liberar a leitura e escrita para todos os usuários. Para isso, ao passar o mouse em cima do bucket irá surgir um ícone com três pontinhos. Clique ali e depois em Edit Policy. Em seguida na tela abaixo, utilize * no prefix e Read and Write ao lado.

Agora vamos para a parte prática, onde demonstrarei em uma aplicação simples o uso do MinIO. Serão dois endpoints, um para fazer o upload e outro para exibir os arquivos que foram armazenados. Vamos restringir o upload apenas a imagens, apenas para facilitar o manuseio das informações. Os layouts utilizados na aplicação podem ser encontrados aqui: https://codepen.io/aaroniker/pen/jjZGLG

Bora começar com o upload:

Route::get('/upload_images', function () {
return view('upload-image');
});
Route::post(
'/upload_files',
[UploadFileController::class, 'uploadImages']
);

Os métodos do controller UploadFileController são bem simples. O método uploadImages possui um validador para garantir a entrada apenas de imagens e após a validação, o mesmo insere as imagens na raiz do bucket local. O método showUploadedImages é responsável por trazer as urls das imagens que foram salvas.

<?phpnamespace App\Http\Controllers;use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class UploadFileController extends Controller
{
public function uploadImages(Request $request)
{
$request->validate([
'file' => 'required|image',
]);
$request->file->store('.');

return view('upload-image');
}
public function showUploadedImages(Request $request)
{
$imagesUrl = Storage::disk('s3')->allFiles('');
return view('images', compact('imagesUrl'));
}
}

Além destas rotas, outra foi criada para chamar uma action utilizada para exibir as imagens salvas.

Route::get(
'/images',
[UploadFileController::class, 'showUploadedImages']
);

Repositório no GitHub da aplicação: https://github.com/leosteil/laravel-minio-tutorial

Deixei no Readme, uma explicação de como vocês podem fazer para executar o projeto caso tenham interesse.

Estou totalmente aberto a tentar ajudar vocês com dúvidas e a receber feedbacks sobre o material.

Obrigado pela leitura!

--

--

Leonardo Henrique Steil
Leonardo Henrique Steil

Written by Leonardo Henrique Steil

Desenvolvedor Backend Laravel, entusiasta de tecnologia e quem sabe um dia fullstack.

Responses (1)