GUILHERME YAMAKAWA DE OLIVEIRA

PT|EN

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.

Configuration AWS

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:

  1. 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.

  2. Verificar como o Active Storage gera esse path_for e mandar ele gerar direto sem essas subpastas.

    Pesquisei e não encontrei nenhum lugar onde conseguisse fazer isso.

  3. 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.

  4. 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_storage

Conclusã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