Instalando e configurando NGINX no Ubuntu

# Breve introdução ao NGINX

O NGINX é um servidor web muito poderoso, com a capacidade de servir arquivos estáticos como HTML, CSS e Javascript, realizar balanceamento de carga, atuar como proxy para servidores de email e outros servidores web. O NGINX possui como vantagens a capacidade de lidar tranquilamente com milhares de conexões simultâneas e uma configuração inicial fácil, além de ser bastante extensível, contando com uma grande gama de configurações que podem ser utilizadas para adequar o servidor a diversas necessidades, servindo tanto para aplicações simples quanto para aplicações complexas e ambientes de alto tráfego de dados.

# Instalando o NGINX em distribuições baseadas no Ubuntu

Para escrita desse tutorial foi utilizada uma máquina com o sistema PopOS! 20.04 LTS 64 Bits, mas como é uma distribuição baseada no Ubuntu, os passos a serem seguidos aqui provavelmente funcionarão nele.

sudo apt install nginx

# Iniciando o NGINX

Se o NGINX não iniciar sozinho, o que pode ser conferido usando o comando:

sudo systemctl status nginx

Você pode iniciá-lo assim:

sudo systemctl start nginx

O resultado esperado no terminal é esse: Nginx funcionando no terminal

E ao abrir o navegador no endereço localhost deverá ser exibida essa página, se a instalação tiver funcionado corretamente: Nginx funcionando no navegador

# Possíveis problemas

  • Pode ocorrer algum conflito com o firewall que não permita o NGINX escutar as portas, se isso ocorrer, adicione o NGINX como exceção no firewall:
sudo ufw allow 'Nginx HTTP'
  • Na etapa de acessar a aplicação pelo server_name pode ser necessário utilizar o navegador Chromium ou o Chrome, no Firefox pode ser que não funcione.

# Diretórios importantes para o NGINX

Lembrando que as localizações desses diretórios podem mudar de sistema para sistema.

/etc/nginx: É onde se encontra toda a configuração do servidor.

/var/www: É onde ficam os projetos que serão servidos.

/etc/nginx/sites-available: Local onde devem ser adicionados os arquivos de configuração de cada projeto.

/etc/nginx/sites-enabled: Local onde devem ser criados links para os arquivos disponíveis no diretório sites-available que pertencem a projetos que serão executados.

# Servindo uma página html simples com NGINX

# Criando projeto

No diretório /var/www crie uma nova pasta com o nome "testando". Dentro dessa nova pasta adicione um arquivo index.html. Insira esse código dentro do arquivo:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello, World!</title>
    <link rel="stylesheet" href="stylesheet.css">
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

Dica: se não possuir muita habilidade com a criação de diretórios e arquivos no terminal, é possível rodar o comando:

sudo nautilus .

Assim, será aberto o gerenciador de arquivos em modo root e todas as operações necessárias poderão realizadas mais facilmente.

# Configurando permissões

É necessário transferir a propriedade do diretório do projeto do root para o usuário:

sudo chown -R $USER:$USER /var/www/testando

E adicionar permissões:

sudo chmod -R 755 /var/www/testando

# Configurando o NGINX para servir o projeto

Crie um novo arquivo com o nome "testando" dentro da pasta /etc/nginx/sites-available com o código:

server {
   listen 81;
   listen [::]:81;

   server_name testando.com;

   root /var/www/testando;
   index index.html;

   location / {
	    try_files $uri $uri/ =404;
   }  
}

Depois disso, crie um link simbólico desse arquivo dentro da pasta /etc/nginx/sites-enabled/:

sudo ln -s /etc/nginx/sites-available/testando /etc/nginx/sites-enabled/

Reinicie o NGINX:

sudo systemctl restart nginx

Se tudo correu bem, ao final desse processo, você poderá abrir o navegador no endereço localhost:81 e deverá ver a seguinte página: Novo projeto aberto no navegador

# Configurando hosts

Perceba que no arquivo de configuração do projeto, adicionamos a diretiva server_name, que serve para poder acessar o projeto por meio de uma url amigável. Isso é alcançado por meio de uma funcionalidade do NGINX chamada Server Blocks.

server_name testando.com;

É uma funcionalidade muito interessante pois permite que por meio de um único endereço IP de um servidor seja possível acessar múltiplas aplicações, pois o NGINX sabe identificar pelo nome o recurso que o cliente deseja e direcioná-lo para a aplicação correta.

Para se usar essa funcionalidade é preciso realizar uma configuração adicional no arquivo hosts do sistema operacional localizado geralmente no diretório etc. Ele deve ficar da seguinte maneira: Configuração do arquivo /etc/host

Ainda temos um problema pois ao entrar no endereço "testando.com" será feito um redirecionamento para a página padrão do NGINX. Para corrigir, é necessário voltar no arquivo /etc/nginx/sites-available/testando e alterar o listen para a porta 80, ficando assim a configuração final:

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

   server_name testando.com;

   root /var/www/testando;
   index index.html;

   location / {
	    try_files $uri $uri/ =404;
   }  
}

Reinicie o NGINX:

sudo systemctl restart nginx

Agora ao abrir o navegador no endereço "testando.com" esse deverá ser o resultado final: Nginx server block configurado

# Configurando proxy reverso

Uma interessante funcionalidade do NGINX é poder redirecionar as requisições que recebe para outra uma aplicação externa. Isso pode ser feito por meio de proxy reverso. Pode-se usar essa funcionalidade caso se possua, por exemplo, uma aplicação backend em NodeJS, .Net, PHP ou outra tecnologia e se deseje usar o mesmo IP do servidor para elas. Com essa funcionalidade podemos obter vantagens como balanceamento de carga, menor consumo de recursos do servidor e maior segurança por meio da configuração de políticas de acesso no NGINX.

Podemos configurar um proxy reverso no mesmo arquivo de configuração do nosso projeto "testando". O objetivo aqui será servir a página html no endereço "testando.com" e acessar o servidor externo, que estará rodando na porta 5000, no endereço "testando.com/api". Para isso basta abrir o arquivo /etc/nginx/sites-available/testando e configurá-lo da seguinte maneira:

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

   server_name testando.com;

   root /var/www/testando;
   index index.html;

   location / {
	    try_files $uri $uri/ =404;
   }  
   
   # testando.com/api redirecionará as requisições para http://127.0.0.1:5000
   location /api/ {
   	    proxy_pass http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
 	      proxy_pass_request_headers      on;
   }
}

Reinicie o NGINX:

sudo systemctl restart nginx

Pronto, agora as requisições realizadas para o endereço "http://testando.com/api/" serão repassadas ao servidor externo corretamente.

# Configurando balanceamento de carga

Fazer o balanceamento de carga com o NGINX também não é uma tarefa complexa. Supondo que temos três servidores idênticos, um rodando na porta 5000, outro na 5001 e o terceiro na 5002, basta editarmos o arquivo de configuração do projeto da seguinte maneira:

# Declaração dos endereços dos servidores
upstream backend {
  server 127.0.0.1:5000;
  server 127.0.0.1:5001;
  server 127.0.0.1:5002;
}

# Configuração do servidor
server {
   listen 80;
   listen [::]:80;

   server_name testando.com;

   root /var/www/testando;
   index index.html;

   location / {
	    try_files $uri $uri/ =404;
   }  
   
   # Configuração do proxy reverso
   location /api/ {
   	    proxy_pass http://backend; # o proxy_pass será feito para os três servidores
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
 	      proxy_pass_request_headers      on;
   }
}

Salve o arquivo e depois reinicie o NGINX:

sudo systemctl restart nginx

Tudo certo, agora as requisições vão ser distríbuidas pelos três servidores. Existem outras configurações possíveis para o balanceamento de carga, mas o básico é isso.