Utilizando o MinIO no Rails
Estou em um projeto onde a configuração de upload de arquivos é o Active Storage com o Amazon S3. Porém não tem nenhuma configuração feita pra eu baixar os arquivos do S3 e usar eles em desenvolvimento.
Quando olhei o arquivo config/storage.yml vi a seguinte configuração:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
Logo pensei que seria algo simples, era só trazer tudo que tem dentro do Bucket do S3 pra dentro da pasta app/storage da aplicação.
Baixei o AWS-CLI e configurei com as minhas credenciais.

Depois sincronizei os arquivos do S3 na minha pasta app/storage:
$ aws s3 sync s3://bucket-name ~/Projects/selected-project/storage
Iniciei a aplicação e não deu certo 🙄.
No ActiveStorage, quando o service configurado é Disk, depois que o blob gera a key, o arquivo é salvo dentro de duas pastas e depois a key do blob.
Procurei o path do arquivo pelo console e ele me retornou:
> user = User.first
> ActiveStorage::Blob.service.send(:path_for, u.avatar.key)
=> "storage/jt/Y7/jtY7656jGPvfPMUUA8kX6Vb4"
Notei que essas pastas criadas eram os 4 primeiros caracteres da key.
Pensei em algumas soluções:
-
Escrever um script pra gerar essas subpastas e adicionar os arquivos nelas.
Não fui por essa opção. Talvez não funcionasse, e como não tenho experiência com scripts pra alterar o filesystem, achei que ia demorar muito. -
Verificar como o Active Storage gera esse
path_fore mandar ele gerar direto sem essas subpastas.
Pesquisei e não encontrei nenhum lugar onde conseguisse fazer isso. -
Duplicar o bucket dentro do S3 e usar ele pra desenvolvimento.
Não gostei da ideia, ia ter que pagar o armazenamento de 2 buckets. -
Usar o MinIO.
Foi a opção que achei mais rápida e com melhor custo x benefício.
O MinIO, pra quem não conhece, é um projeto Open Source em Go projetado desde o início pra ser o padrão no armazenamento de objetos na nuvem privada. É um servidor de objetos nativo da nuvem com desempenho simultâneo, escalável e leve (Mais informações).
Preciso configurar o MinIO igual ao S3, porque a aplicação precisa pensar que está falando com o S3. Baixei o MinIO pelo site e configurei as variáveis de ambiente:
export MINIO_ACCESS_KEY="minio_storage_development"
export MINIO_SECRET_KEY="minio_storage_development"
export MINIO_REGION_NAME="us-east-1"
Ele é configurado através das variáveis de ambiente. Você pode verificar todas as configurações pela documentação. (Documentação MinIO)
Agora é só iniciar:
$ minio server ~/minio_storage
Endpoint: http://xxx.xxx.xxx.xxx:9000 http://xxx.xxx.xxx.xxx:9000 http://127.0.0.1:9000
AccessKey: minio_storage_development
SecretKey: minio_storage_development
Region: us-east-1
Browser Access:
http://xxx.xxx.xxx.xxx:9000 http://xxx.xxx.xxx.xxx:9000 http://127.0.0.1:9000
Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
$ mc config host add myminio http://100.100.101.162:9000 minio_storage_development minio_storage_development
Obs: escondi meu IP com o xxx.xxx.xxx.xxx porque ele é fixo e não quero deixar exposto pra Web.
Pronto, temos um servidor MinIO configurado rodando no seu computador.
Acessei ele pelo navegador em http://127.0.0.1:9000/ usando a Access Key e Secret Key, e criei um Bucket chamado rails_app_bucket.
Nas configurações do Rails em config/storage.yml:
local:
service: S3
endpoint: http://127.0.0.1:9000
access_key_id: minio_storage_development
secret_access_key: minio_storage_development
region: us-east-1
bucket: rails_app_bucket
force_path_style: true
Movi todos os arquivos que tinha baixado do Bucket do S3 pra pasta do Bucket do MinIO:
$ mv ~/Projects/selected-project/storage/* ~/minio_storage/rails_app_bucket
Agora pra sincronizar os arquivos do S3 uso o seguinte comando:
$ aws s3 sync s3://bucket-name ~/minio_storage/rails_app_bucket
Também deixei configurado no meu Procfile.development pra iniciar o servidor do MinIO sempre que eu rodar a aplicação pelo foreman:
# Procfile.development
server: bin/rails server
webpacker: bin/webpack-dev-server
redis: redis-server
sidekiq: bundle exec sidekiq
minio: minio server ~/minio_storageConclusão
Ficou muito simples sincronizar os arquivos e não ter mais nenhum 404 de arquivo rodando a aplicação, nem aquele erro do Rails dizendo que o arquivo não existe.
Comentários