Deploy de uma aplicação Ruby on Rails 5.2 no Heroku
O Heroku é uma plataforma para hospedagem de aplicações que foi lançado em 2007 e oferece suporte a Ruby oficialmente desde 2009. Nesses mais de 10 anos, a plataforma se tornou muito popular entre desenvolvedores Ruby on Rails e de outras linguagens — hoje são aceitos Node.js, Python, Java, Scala etc.
Por ser vendido como serviço (PaaS), o Heroku possui algumas convenções que sua aplicação deve seguir para poder ser hospedada lá. As convenções utilizadas pelo Heroku se tornaram referência na comunidade de desenvolvimento web e estão disponíveis no site: https://12factor.net/pt_br/
Entre as principais vantagens da plataforma, podemos destacar a facilidade para deploy — que vai ser feito pelo Git, a gestão de infraestrutura que permite aos desenvolvedores focar somente no código da aplicação e, claro, a existência de um plano gratuito com algumas limitações mas que serve perfeitamente para MVPs e testes.
Você pode ler um pouco mais sobre o Heroku e as linguagens suportadas no site oficial.
Adequando nossa aplicação Rails
Por questões de segurança, o Heroku evita que as aplicações publicadas tenham acesso à escrita direta em um disco. A utilização de discos virtuais — que são recriados em diversos momentos — não possibilita o uso de gems que criem arquivos de forma local.
Esta limitação inviabiliza o uso do banco SQLite que é o padrão em aplicações Rails, já que ao reiniciar a aplicação ou fazer um novo deploy, o disco seria recriado e perderíamos todos os dados salvos.
A opção oferecida e recomendada é isolar todo armazenamento da aplicação em outra infraestrutura. Ou seja, a aplicação Rails vai ser executada no Heroku mas vai se conectar a um banco de dados em outro servidor.
O banco de dados recomendado e suportado oficialmente pelo Heroku é o Postgres, mas você pode usar o que preferir. Nesse tutorial vamos seguir com o Postgres :)
O primeiro passo é instalar a gem do Postgres . Essa gem requer a instalação de muitas dependências em nossa máquina, o que pode dificultar tarefas simples como executar o bundle install
em novas máquinas. Felizmente, temos uma opção no Bundler que permite instalar as gems somente em ambientes específicos.
Vamos mudar o Gemfile do projeto para refletir essa mudança somente em produção, mantendo o sqlite
em desenvolvimento e testes e mudando para pg
em produção:
Atenção: Se você está usando Rails 5.1 ou menos, use a versão 0.18 da gem pg
, já que as novas versões funcionam apenas para Rails acima da 5.1.5:
gem 'pg', '~> 0.18'
Ao final, nosso Gemfile estará mais ou menos dessa forma:
group :development, :test do
gem 'sqlite3'
endgroup :production do
gem 'pg'
end
Precisamos atualizar no Gemfile.lock
também, para isso execute:
bundle install --without production
Essa opção + parâmetro garantem que não precisamos efetivamente instalar as gems de produção no ambiente de desenvolvimento. Como dito, a gem pg
, por exemplo, tem muitas dependências e pode ser um pouco trabalhosa para instalar caso você não seja usuário rotineiro de Postgres.
Uma curiosidade é que se essa modificação fosse feita para hospedagem em outro local teríamos que atualizar oconfig/database.yml
que guarda as informações necessárias para acessar seu banco.
Como o Postgres é um dos bancos oficialmente suportados pelo Rails, você pode dar uma olhada no Guides para ver as mudanças que deveriam ser feitas no config/database.yml
— https://guides.rubyonrails.org/configuring.html#configuring-a-postgresql-database.
Automaticamente, ao instalar a nossa gem, o Heroku vai criar o banco e gerar um novo database.yml
, então não temos essa preocupação.
Vamos, então, fazer deploy da nossa aplicação!?
Primeiramente, podemos instalar a Heroku CLI. Você pode fazer download dependendo do seu sistema operacional clicando aqui.
Caso ainda não tem conta no Heroku, é a hora de fazer https://www.heroku.com/.
Em seguida, use o comando heroku login
no terminal para fazer login e utilizar a CLI.
Para criar nosso app no Heroku após o login, usamos o comando:
heroku create nome-da-sua-aplicacao
Este nome vai na sua url, então não utilize espaços!
Ao executar o comando, o Heroku vai criar um repositório Git para nossa aplicação e adicionar esse novo repositório como um remote
localmente chamado heroku
. Podemos confirmar isso rodando git remote -v
.
Para fazer deploy, vamos precisar ter todo código commitado localmente. Caso você ainda não tenha feito nenhum commit
, chegou a hora :)
git add .
git commit -m 'Primeiro commit'
Para fazer deploy do seu código, vamos executar o comando:
git push heroku master
Agora, você verá no seu terminal o log do Heroku instalando sua aplicação na máquina. É interessante notar alguns momentos cruciais em andamento como: bundle install
, a compilação dos assets para produção (https://guides.rubyonrails.org/asset_pipeline.html#in-production) e a inicialização em si da aplicação.
Para rodar nossa app você pode executar heroku open
e aguardar o seu navegador abrir uma nova aba com o endereço do Heroku. No entanto, a chance de você se deparar com uma tela como essa abaixo é alta!
Para entender melhor o que está acontecendo, você pode rodar um comando bem útil que mostra o log da aplicação em produção:
heroku logs
Repare que encontramos o erro PG:UndefinedTable
dizendo que a relation "questions"
não existe. Basicamente não existe uma tabela da nossa aplicação pois não rodamos as migrations. É interessante notar que não recebemos um erro do tipo ‘Você possui migrações pendentes’. Isso acontece por estarmos executando a aplicação no environment de produção. Muita coisa muda no Rails quando estamos no ‘modo produção’, desde a forma como os arquivos/classes são inicializados até as mensagens de erro exibidas pela aplicação. Isso vale um post mais pra frente ;)
Bem, vamos rodar as migrations da nossa aplicação. Para isso precisamos ‘enviar’ um comando para o Heroku executar em nossa app. O comando heroku run
faz isso, temos então:
heroku run rails db:migrate
Pronto! Agora é só utilizar o comando heroku open
para abrir sua aplicação no Heroku e testar se tudo está correto. Caso tenha um arquivo de seed, não se esqueça de rodá-lo também nos mesmos moldes do migrate
!
Concluindo
As facilidades oferecidas pelo Heroku fizeram da plataforma uma referência para hospedagem de aplicações Web em todo o mundo. Mesmo saindo da versão gratuita e indo para os planos iniciais que custam de US$ 7 a US$ 16, o custo no final do mês ainda é muito vantajoso dados os custos/dificuldades de se manter um servidor inteiro no ar e cuidar de todos os assuntos relacionados a infraestrutura: segurança, disponibilidade etc.