Quando estamos trabalhando com desenvolvimento de sites e aplicações web, sempre vem a dúvida de como hospedar e manter os sistemas disponíveis para os usuários. É muito comum o uso do Apache em aplicações pequenas, mas quando falamos de algo mais robusto, com grande fluxo de dados, o Nginx (leia-se Engine-EX) é o recomendado.

As vantagens de se usar o Nginx como servidor web ao invés dos concorrentes são muitas: o Nginx é muito fácil de instalar e configurar; possui uma ótima performance servindo arquivos estáticos como imagens e vídeos; é otimizado para conexões concorrentes, e; funciona como balanceador de cargas… Se você ainda não se convenceu, vale lembrar que grandes serviços como Yahoo, YouTube e Instagram fazem uso do Nginx para otimizar o tempo de resposta.

Neste post, vamos abordar um cenário onde você tem duas aplicações Rails distintas que são acessíveis por domínios diferentes. Para facilitar as coisas, caso você ainda não tenha dois domínios, crie no hosts de sua máquina domínios fictícios. Aqui, usarei os domínios meuapp.com e dominio.com.

Para fazer essa configuração, edite o arquivo /etc/hosts e adicione as seguintes linhas:

[sourcecode language=”bash”]
127.0.0.1 meuapp.com
127.0.0.1 dominio.com
[/sourcecode]

Antes de colocarmos a mão na massa, você precisa saber de mais algumas coisas:

O condomínio de aplicações

Se você programa em Rails já deve ter tentado subir duas aplicações apenas com o comando rails s. Fazer isso sem definir portas diferentes ocasiona um erro. O servidor do Rails identifica que outra porta já está em uso e não permite subir um outro servidor na mesma porta. Para entender melhor, pense em um condomínio de apartamentos. Cada apartamento tem sua porta de entrada e se você quer entrar no apartamento 302, você não utiliza a porta do apartamento 403. Assim como em um condomínio, não da para acessar uma aplicação através de uma porta que já está criada para outra.

E a porta 80?

Por padrão, a porta 80 é reservada para o http. Quem trabalha com PHP e Apache e não sabia disso pode estar achando um pouco estranho, já que aplicações PHP rodando local com Apache são comumente acessíveis pela porta 80. O que acontece, na verdade, é que os servidores web (tanto o Nginx quanto o Apache) recebem as requisições http por esta porta e repassam para as aplicações rodando em portas diferentes. No caso do Apache, ele executa o PHP através de módulos internos e por tanto não abre uma nova porta, mas através de algumas configurações é possível configurar diferentes portas para diferentes aplicações.

Talk is cheap, show me the code…

Agora que você sabe o básico, podemos iniciar nossos trabalhos configurando duas aplicações em um mesmo servidor. Todos os procedimentos realizados aqui estão sendo feitos em um servidor Cloud Server Pro da Locaweb. O servidor é munido de um Debian 8, então, se você está rodando o Ubuntu, não se preocupe.

Vamos começar instalando o Nginx

[sourcecode language=”bash”]
$ sudo apt-get install nginx
[/sourcecode]

Após a instalação, devemos iniciar a configuração do nosso servidor para rodar dois sites ou aplicações ao mesmo tempo. O Nginx guarda os arquivos de configuração na pasta /etc/nginx. Ao acessar esse diretório, você perceberá a presença de algumas pastas, mas neste post utilizaremos apenas as pastas sites-available e sites-enabled.

A partir de agora você já deve ter suas aplicações rodando em portas diferentes. No meu caso, tenho duas aplicações Rails, uma na porta 3000 e outra na porta 3030. Para subir uma aplicação Rails em uma porta específica, você pode rodar:

[sourcecode language=”bash”]$ rails s -p 3030[/sourcecode]

A configuração começa na pasta sites-available, que é onde você deve guardar um arquivo de configuração para cada aplicação. Se você não vai se aprofundar muito nas configurações, é possível fazer tudo no mesmo arquivo. Porém, o recomendado é que cada aplicação tenha seu próprio arquivo de configuração para facilitar manutenções futuras.

Para a aplicação rodando no domínio meuapp.com, crie o arquivo meuapp dentro de sites-available. Quando o Nginx processa cada requisição, ele busca na configuração por um “virtual server”, que é representado pelo bloco server

[sourcecode language=”bash”]
server {
#configurações
}
[/sourcecode]

Esse bloco, normalmente, contém a diretiva listen que diz qual o IP e a porta em que o servidor está esperando por requisições

[sourcecode language=”bash”]
server {
listen 80;
}
[/sourcecode]

Ao omitir o IP, o Nginx entende que as requisições podem ser recebidas de qualquer endereço. Se vários blocos estão esperando requisições pelo mesmo endereço e porta, o Nginx passa a verificar o cabeçalho das requisições pelo host e compara com o server_name.

[sourcecode language=”bash”]
server {
listen 80;
server_name meuapp.com www.meuapp.com;
}
[/sourcecode]

O Nginx pode repassar a requisição para outro server ou até mesmo servir um arquivo estático, isso é feito atráves do bloco location que fica dentro de server.

[sourcecode language=”bash”]
server {
listen 80;
server_name meuapp.com www.meuapp.com;

location / {

}
}
[/sourcecode]

O bloco location contém diretivas que dizem ao Nginx o que fazer com a requisição. No nosso cenário, vamos redirecionar as requisições ao servidor Rails que está rodando nas portas 3000 e 3030 no nosso ambiente local. Por padrão, o ambiente local (localhost) possui o IP 127.0.0.1.

[sourcecode language=”bash”]
server {
listen 80;
server_name meuapp.com www.meuapp.com;

location / {
proxy_pass http://127.0.0.1:3000;
}
}
[/sourcecode]

A diretiva proxy_pass é responsável por transmitir a requisição a um servidor com proxy e retornar a resposta ao cliente.

Sendo assim, já temos nosso arquivo de configuração para o domínio meuapp.com. Se você entendeu bem o funcionamento do Nginx para essa situação, criar uma configuração para o domínio dominio.com deve ser trivial. Apenas crie o arquivo dominio dentro da pasta sites-available e coloque as configurações assim como foi feito para o arquivo meuapp.

[sourcecode language=”bash”]
server {
listen 80;
server_name dominio.com www.dominio.com;

location / {
proxy_pass http://127.0.0.1:3030;
}
}
[/sourcecode]

Tentar acessar algum dos domínios vai te levar a uma página inicial do Nginx que não é o que você esperava. Para ser direcionado diretamente a sua aplicação, devemos dizer ao Nginx quais sites estão ativados. Faremos isso criando um link simbólico na pasta sites-enabled para os arquivos da pasta sites-available.

Acesse a pasta sites-enabled e, para o domínio dominio.com faça o seguinte:

[sourcecode language=”bash”]$ sudo ln -s ../sites-available/dominio .[/sourcecode]

Agora, para o domínio meuapp.com, faça:

[sourcecode language=”bash”]$ sudo ln -s ../sites-available/meuapp .[/sourcecode]

Recarregue os arquivos de configuração do Nginx com o comando

[sourcecode language=”bash”]$ sudo service nginx reload[/sourcecode]

Agora, se testar cada um dos domínios, você deve ver sua aplicação. Essa é uma configuração simples do Nginx. Se você trabalha com PHP, nos veremos em outro post aqui no Blog da Locaweb que mostrará como configurar o php_fpm para servir aplicações PHP.

Espero que tenham curtido. Nos vemos no próximo post.