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:
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.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.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.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
Conclusão
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.
Top comments (2)
Artigo incrível! Me ajudou muito em um projeto aqui! Parabéns, cara!
Valeu Alisson!!