menu

SHARKLABS

Ruby on Rails + Puma + Nginx: Proxy Reverso com Unix Socket

/
/
Ruby on Rails + Puma + Nginx: Proxy Reverso com Unix Socket
bookmark Ruby on Rails access_time

Puma Server é bom?

O Puma é o servidor HTTP padrão do Ruby on Rails desde a versão 5. Antes desta versão, o Webrick era o servidor HTTP, porém ele deve ser usado somente no ambiente de desenvolvimento.

Por isso muita gente acredita que o Puma não pode ser usado em produção, porém isso não é verdade. O Puma é um servidor HTTP leve, rápido e com ótima integração com o Ruby on Rails. Portando, o Puma pode sim ser usado em produção.

Outra coisa que muitas pessoas confundem, é que o Puma é um Application Server e é recomendável que ele funcione em conjunto com um Web Server.

Web Server ou Application Server?

Embora ambos sejam servidores HTTP, o Web Server é um software voltado a gerir muitas conexões e funciona bem com arquivos estáticos. Por outro lado, o Application Server é um servidor HTTP integrado com seu aplicativo e é responsável por processar as regras de negócio.

Desta forma, Web Server e Application Server são softwares que se complementam. Vou deixar alguns links que explicam detalhadamente esses conceitos:

Puma + Nginx

Para os aplicativos Ruby on Rails, eu particularmente prefiro de usar o Puma como Application Server e o Nginx como Web Server. A comunicação entre os dois softwares normalmente é feita com um Proxy Reverso, ou seja, a requisição que chega no Nginx é redirecionada para o Application Server.

Este Proxy Reverso pode ser feito de várias maneiras, mas neste artigo vou usar um Unix Socket, que é uma forma de comunicação entre processos do Linux.

Outro ponto que gera muita dúvida, é que há uma maneira de usar Nginx com Ruby on Rails e sem usar o Puma. Existe um módulo para Nginx que se chama Passenger e promete fazer essa comunicação sem um proxy reverso. Eu nunca usei o Passenger porque ele é pago e a sua versão gratuita possui limitações de recursos (clique neste link e veja o item "Slow requests") .

Instalação e Configuração do Nginx

A instalação Nginx é muito simples e não vou entrar muito em detalhes. Por isso separei um tutorial da Digital Ocean que mostra como instalar o Nginx no Linux Ubuntu, clique aqui para acessá-lo.

Para configurar o Nginx como um proxy reverso, você deve deixar o arquivo /etc/nginx/sites-available/default da seguinte maneira:

upstream app {
    server unix:/srv/my-app/tmp/sockets/puma.sock fail_timeout=0;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /srv/my-app/public;
    index index.html;

    try_files $uri/index.html $uri @app;

    location @app {
        proxy_pass http://app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }

    error_page 500 502 503 504 /500.html;
    client_max_body_size 4G;
    keepalive_timeout 10;

    listen 443 ssl;
    ssl_certificate     /etc/nginx/ssl/certificate.crt;
    ssl_certificate_key /etc/nginx/ssl/private.key;
    if ($scheme = http) {
        return 301 https://$host$request_uri;
    }
}

Basicamente os arquivos de configuração do Nginx funcionam baseados em diretivas, blocos e contextos. Se você quer ter um entendimento melhor da sintaxe desses arquivos de configuração, veja este tutorial da Linode.

Sobre as funções disponíveis para serem usadas nesses arquivos de configuração, na documentação oficial do Nginx existe uma listagem com todos os módulos (ver item "Modules reference") e dentro de cada módulo há uma descrição de todos blocos e diretivas disponíveis. Por exemplo, as maioria das diretivas que eu usei no arquivo acima estão dentro do Module HTTP ou do Module SSL.

Em relação as variáveis usadas (precedidas pelo caractere $), caso você tenha alguma dúvida sobre como e quando usar, existe uma listagem com todas as variáveis disponíveis na documentação oficial do Nginx.

Veja que no fim do arquivo eu configurei um certificado SSL que é muito importante no ambiente de produção. Mas caso você esteja apenas testando, você tem duas opções:

  • Remover a configuração, ou seja, apagar as linhas 25, 26, 27, 28, 29 e 30 (entre o "listen 443 ssl" até o bloco do "if").
  • Ou gerar um certificado de testes com o OpenSSL. Segue abaixo o comando que eu utilizei.
openssl req -x509 -sha256 -nodes -newkey rsa:2048 -days 365 -keyout private.key -out certificate.crt.

Configurando o Puma

Para que o Puma receba as requisições do Nginx é preciso configurar o diretório e nome do arquivo de Unix Socket.

Para isso, basta adicionar as seguintes linhas no arquivo config/puma.rb :

app_dir = File.expand_path("../..", __FILE__)
bind "unix://#{app_dir}/tmp/sockets/puma.sock"

Pronto, agora o Puma e o Nginx estão configurados para trabalhar em conjunto!

Dúvidas ou sugestões é só entrar em contato. Abraço.

Autor
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." Martin Fowler