guilherme 44

Home Sobre RSS

Utilizando o MinIO no Rails

  • minio
  • rails
  • ruby
  • storage
  • s3

Estou em um projeto aonde a configuração de upload de arquivos utilizada é o Active Storage com o Amazon S3. Porem não tem nenhuma configuração feita para eu baixar os arquivos do S3 e utilizar eles em desenvolvimento.

Quando olhei a configuração do arquivo config/storage.yml vi a seguinte configuração:

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

Logo pensei que seria algo simples, apenas precisava trazer tudo que tem dentro do Bucket do S3 para dentro da minha pasta app/storage da aplicação.

Baixei o AWS-CLI e configurei com as minhas credenciais.

Após isso sincronizei os arquivos do S3 na minha pasta de app/storage com o comando:

$ 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 após o blob gerar 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 o path seguinte:

> user = User.first
> ActiveStorage::Blob.service.send(:path_for, u.avatar.key)
=> "storage/jt/Y7/jtY7656jGPvfPMUUA8kX6Vb4"

Notei que essas pastas criadas era os 4 primeiros caracteres da key.

Pensei em algumas soluções:

  1. Escrever um script para gerar essas sub-pastas e adicionar os arquivos nelas.

    Não optei por essa opção, talvez ela poderia não funcionar e como não tenho experiencia com scripts em alterar o filesystem, achei que iria demorar muito com isso.

  2. Verificar como o Active Storage gera esse path_for e falar pra ele gerar direto sem essas sub-pastas.

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

  3. Duplicar o bucket dentro do S3 e utilizar ele para desenvolvimento.

    Não gostei dessa ideia pois iria ter que pagar o armazenamento de 2 buckets.

  4. Utilizar o MinIO.

    Foi a opção que acreditei ser mais rapída e com melhor custo x benefício.

O MinIO pra quem não conhece é um projeto Open Source em Go e foi projetado desde o início para ser o padrão no armazenamento de objetos na nuvem privada. Ele é um servidor de objetos nativo da nuvem com desempenho simultâneo, escalável e leve (Mais informações).

Assim preciso configurar o MinIO igual funciona o S3 pois minha aplicação precisa pensar que está no S3. Baixei o MinIO pelo site deles e configurei as variaveis 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 ambientes. Você pode verificar quais são todas as configurações pela documentação dele. (Documentação MinIO)

Agora é apenas 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 o meu IP com o xxx.xxx.xxx.xxx pois ele é fixo e não quero deixar exposto para a Web.

Pronto temos um servidor MinIO configurado rodando no seu computador.

Acessei ele através do meu navegador http://127.0.0.1:9000/ utilizando a Access Key e Secret Key e criei um Bucket chamado rails_app_bucket.

Nas configurações do rails que fica 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 os arquivos todos os arquivos que tinha baixado do Bucket do S3 para a pasta do Bucket MinIO.

$ mv ~/Projects/selected-project/storage/* ~/minio_storage/rails_app_bucket

Agora para sincronizar os arquivos do S3 utilizo o seguinte comando.

$ aws s3 sync s3://bucket-name ~/minio_storage/rails_app_bucket

Também deixei configurado no meu Procfile.development para iniciar o servidor do MinIO sempre que inicio a minha aplicação pelo foreman ficando assim:

# Procfile.development

server: bin/rails server
webpacker: bin/webpack-dev-server
redis: redis-server
sidekiq: bundle exec sidekiq
minio: minio server ~/minio_storage

Finalizando

Ficou muito simples para eu conseguir sincronizar os arquivos e não aparecer nenhum 404 de arquivos quando eu estou rodando aplicação, e muito menos algum erro do rails que mostrando que o arquivo não existe.

Fontes