Conhecendo e usando o Ngrok em aplicações Rails

Fala, pessoal!

Hoje vamos conhecer uma ferramenta chamada Ngrok que tem por objetivo expor, de forma segura, a sua aplicação local na web.

Antes, uma pergunta... Você já precisou que uma aplicação externa (vindo da Internet) acesse a sua aplicação local? Isso mesmo, por exemplo, você tá testando um determinado gateway de pagamentos (sei que a maioria possuem sandbox pra testes, mas, vamos imaginar essa situação hipotética) e quer que, ainda em desenvolvimento, tal gateway converse com sua aplicação... Como isso seria possível se sua aplicação está apenas em seu computador e não na Internet? É aí que o Ngrok entra em ação.

Em resumo, o Ngrok vai fazer um túnel entre sua aplicação local e o site deles, e lá ele vai disponibilizar um link que pode ser visto por qualquer um na Internet, e dessa forma vc consegue receber qualquer tipo de acesso em sua aplicação local vindo da Internet através do link que eles disponibilizam.

Setup Inicial

Bom, em nosso exemplo temos apenas o objetivo de tornar nossa aplicação local acessível através do Ngrok, então vamos começar criando a aplicação.

# ruby 2.5.3
# rails 6.0.2

/> rails new test-app 
/> cd test-app

Antes de continuar, faça a instalação do Ngrok. Será necessário você se cadastrar no site e após isso será mostrado algo como a imagem abaixo, permitindo você baixar e instalar o app.

enter image description here

Muito bem, já temos uma app rails e o Ngrok instalado, então, a princípio vamos fazer nossa app Rails rodar...

/> rails db:create db:migrate 
/> rails server

Após isso teremos nossa app Rails rodando localmente na porta 3000, conforme o esperado.

enter image description here

Acessando no nosso navegador o endereço http://localhost:3000 vemos a tela de boas-vindas. Até aqui nenhuma novidade, claro.

enter image description here

Usando o Ngrok a primeira vez

Agora que já temos nossa app Rails funcionando, vamos usar o Ngrok.
Deixe sua aplicação Rails rodando e abra um novo terminal, lá rode o comando:

/> ngrok http 3000

Prontinho! Você verá algo assim:

enter image description here

Observe na imagem acima o trecho "Forwarding" onde temos um endereço http e outro https que acessarão sua máquina local.

Acessando qualquer um dos endereços informados pelo Ngrok através do seu navegador, teremos uma surpresa desagradável, conforme imagem.

enter image description here

A mensagem indica que a requisição feita ao seu app foi impedida por sua aplicação Rails, mas a própria mensagem indica como resolver, adicionando o tal host na whitelist da aplicação para que seja permitido o acesso.

Um detalhe aqui é que sempre que levantamos o Ngrok um novo host é gerado, então você já deve ter percebido o problema de ter que alterar esse host na whitelist do Rails toda vez que for rodar o Ngrok.

Mas, pra nossa sorte, podemos informar ao Rails que sempre que estiver em ambiente de desenvolvimento, permitir qualquer endereço se comunicar com a aplicação, para isso, no arquivo config/environments/development.rb adicione as linhas abaixo antes do último end:

...
# Whitelist URLs for Ngrok
Rails.application.configure  do
    config.hosts.clear
end

Observe que usamos config.hosts.clear no intuito de "limpar" qualquer configuração na whitelist dos hosts, permitindo assim qualquer requisição externa seja aceita pela aplicação.

Após parar o servidor do rails e iniciá-lo novamente, acessando o endereço informado pelo Ngrok podemos ver que ele já consegue chegar na aplicação, conforme o esperado.

enter image description here

Super fácil, não é mesmo?

A cereja do bolo

Com o que vimos até agora já conseguimos fazer qualquer tipo de teste usando o Ngrok, mas, a coisa pode ficar ainda melhor.

Imagine que sempre que levantar a aplicação você vai precisar abrir um outro terminal e levantar o Ngrok. Até aí tudo bem, mas e se a gente pudesse fazer o Ngrok funcionar de forma automática quando nossa app é levantada? Seria show, não é mesmo?

A notícia boa é que isso é mais simples do que parece pois existe uma gem que facilita bastante o uso do Ngrok a partir de uma app Rails. Então vamos lá... comece adicionando essas duas gems na app (já já você vai saber o motivo da segunda gem).

# /Gemfile
gem 'ngrok-tunnel'
gem 'tty-box'

Após adicionar, não esqueça de rodar o bundle install para que as gems sejam instaladas.

O próximo passo é ir no arquivo config/puma.rb e adicionar as seguintes linhas:

if  Rails.env.development?
    begin
        options =  {
            addr:  ENV.fetch("PORT")  {  3000  }
        }

        Ngrok::Tunnel.start(options)

        box =  TTY::Box.frame(width:  50,  height:  10,  padding:  2,  title:           {top_left:  "<NGROK>",  bottom_right:  "</NGROK>"},  style:  {fg:  :green,  bg:  :black,  border:  {fg:  :green,  bg:  :black}})  do
            "STATUS: #{Ngrok::Tunnel.status}\nPORT: #{Ngrok::Tunnel.port}\nHTTP: #{Ngrok::Tunnel.ngrok_url}\nHTTPS: #{Ngrok::Tunnel.ngrok_url_https}\n"
        end
    rescue  =>  error
        box =  TTY::Box.frame(width:  50,  height:  5,  align:  :center,  padding:  1,  title:  {top_left:  "<NGROK>",  bottom_right:  "</NGROK>"},  style:  {fg:  :red,  bg:  :black,  border:  {fg:  :red,  bg:  :black}})  do
            "Impossível criar túnel com o Ngrok ;("
        end
    end
    puts  "\n#{box}\n"
end

Prontinho!

Nesse momento, caso ainda esteja rodando o Ngrok em outro terminal pare-o.

Agora é só levantar a aplicação rails server e ver que ela imprime uma mensagem informando o endereço web que você deve usar para ter acesso à sua aplicação local.

enter image description here

Que show, hein?

É claro que você já deve ter percebido que a tem tty-box (aqui no site já falei sobre as gems da família tty) serviu pra montar e mostrar essa caixinha onde aparecem as informações.

Bom, por hoje é isso. Espero que tenham gostado e até a próxima!


Referências: