DEV Community

Cover image for Série Nginx #1: Instalando e Configurando
Valdeir S.
Valdeir S.

Posted on • Edited on

3 1

Série Nginx #1: Instalando e Configurando

O que é o Nginx

Ele é um servidor web de código aberto, de alto desempenho e que conta com suporte a proxy reverso, sistema de cache e load balancer. Ele foi criado por Igor Sysoev por volta de 2004 para resolver o problema conhecido como C10K.


O problema

Parte dos servidores web utiliza o modelo de uma conexão por thread ou processo. Ao fazer dessa forma, quando a ação Y é gerada, ela esperará até uma ação X, criada antes, ser finalizada. Durante todo o tempo, essa ação Y ficará bloqueada, esperando ser liberada.


Como o Nginx o resolveu

O Nginx funciona como uma simultaneous exhibition. Ele utiliza, normalmente, um processo mestre para cada núcleo do processador. Esse processo é responsável por ouvir os eventos e atender a todas as requisições de forma simultânea.

Diferente de outros servidores web, o Nginx não espera a ação ser realizada para prosseguir com as outras ações.


simultaneous exhibition (grandmaster)

Isso acontece porque o NGINX utiliza estratégias de I/O (Input/Output) não-bloqueantes disponibilizadas pelo sistema, que podem variar de acordo com o sistema operacional. Algumas delas são: /dev/poll, epoll, kqueue para FreeBSD ou poll para Windows e outras.


Como o Nginx funciona

Arquitetura do Processo do Nginx

Page Master Process

  • O processo mestre executa as operações privilegiadas como configuração de leitura e vinculação de portas e então cria um pequeno número de processos filhos (os próximos três tipos).

  • O processo do cache loader é executado na inicialização para carregar o cache baseado em disco na memória e, em seguida, é encerrado. Ele é planejado de forma moderada, portanto, suas demandas de recursos são baixas.

  • O processo do gerenciador de cache é executado periodicamente e remove entradas dos caches de disco para mantê-las dentro dos tamanhos configurados.

  • Os services workers fazem todo o trabalho. Eles lidam com conexões de rede, lêem e gravam conteúdo em disco e se comunicam com serviços upstream/proxy e interfaces CGI (PHP, Node, Python, Go etc).

Processo de Trabalho

Detalhes do Processo de Trabalho do NGINX

  • Realiza as estratégias I/O não bloqueante para a comunicação com os serviços upstream/proxy e interfaces CGI.

  • Integra o servidor web com as aplicações, utilizando as interfaces FastCGI, WSGI, SCGI; o gateway memcached, os streams, as sub-requisições e o protocolo TCP.

  • Lê os conteúdos estáticos (imagens, css, js etc); lê, cria e atualiza os caches dos arquivos ou as respostas da aplicação.

  • Grava os logs de acesso e erro de acordo com a configuração do Nginx.

Vale lembrar que — nativamente — a escrita de arquivo funciona de forma síncrona. O arquivo é criado e bloqueado para novos acessos até ser liberado pelo sistema. A partir do NGINX 1.9.13, tornou-se possível configurar a escrita de arquivos temporários de forma assíncrona com o aio_write.

Ciclo de vida de uma requisição no NGINX

Ciclo de vida de uma requisição no NGINX

  • Recebe a requisição e descriptografa as informações caso ela esteja utilizando HTTPS.

  • Identifica a configuração das diretivas em bloco server (Servidor Virtual) e location, que é carregada conforme URI da requisição.

  • Aplica limites (Rate Limit) para requisição (opcional).

  • Executa autenticação interna e/ou externa como HTTP Basic Authentication. A autenticação pode ser feita com módulos nativos ou de de terceiros (opcional).

  • Acessa a aplicação através de interfaces de comunicação ou serviços upstreams para obter a resposta que será retornada para o cliente.

  • Realiza verificações da saúde da aplicação (se ela está ativa), controle de requisições simultâneas, load balancer, resposta de cache etc.

  • Recebe a resposta da aplicação, filtra-a utilizando compressores como gzip, brotli ou optimiza-a com filtros (por exemplo, em imagens) etc. É possível usar módulos nativos ou de terceiros para realizar o filtro (opcional).

  • Registra o log de acesso e o de sessão.

  • Retorna a resposta filtrada para o cliente.


Instalação

Vamos mostrar como instalar nos sistemas operacionais mais conhecidos. Posteriormente, veremos como compilar o código fonte. Este passo é importante para configuração dos módulos de terceiro (será estudado em outra parte da série).

Linux

No exemplo, o processo de instalação será mostrado com os sitemas Ubuntu, Alpine e CentOs. Posteriormente, como compilar o código no Ubuntu.

Ubuntu

# Adiciona suporte à instalação da versão mais recente
echo "deb https://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" | sudo tee -a /etc/apt/sources.list
# Adiciona chave de assinatura
curl -sSLo- https://nginx.org/keys/nginx_signing.key | sudo apt-key add
# Instala o Nginx
sudo apt update; sudo apt install -y nginx
Enter fullscreen mode Exit fullscreen mode

Alpine

sudo apk add nginx
Enter fullscreen mode Exit fullscreen mode

CentOS

sudo yum install epel-release
sudo yum install nginx
Enter fullscreen mode Exit fullscreen mode

Mac

1. É necessário utilizar o Homebrew, que permitirá a instalação de pacotes que o Mac não fornece. Para instalá-lo, utilize o código abaixo:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Enter fullscreen mode Exit fullscreen mode

2. Instale o Nginx:

brew install nginx
Enter fullscreen mode Exit fullscreen mode

Windows

  1. Acesse a página http://nginx.org/en/download.html
  2. Escolha a versão que você deseja baixar (recomendo a stable)
  3. Após baixá-la, extraia o arquivo zip e mova a pasta extraída para *C:*
  4. Inicie o executável nginx.exe para iniciar o serviço do servidor web.

Dica: para encerrar o Nginx, abra o prompt de comando e execute o comando tasklist /fi "imagename eq nginx.exe".


Estrutura de arquivos

Após baixar e instalar o Nginx, é criada uma pasta com todos os arquivos de configuração.

O local de instalação e a estrutura de arquivos podem variar conforme o método de instalação e o sistema operacional. Para esta postagem, utilizei o Nginx instalado via apt no Ubuntu 20.04.

Ao acessar o local de instalação (/etc/nginx), veremos uma estrutura parecida com esta:

tree /etc/nginx

/etc/nginx
├── conf.d
├── fastcgi.conf
├── fastcgi_params
├── mime.types
├── modules-available
├── modules-enabled
├── nginx.conf
├── proxy_params
├── sites-available
│   ├── default
├── sites-enabled
│   ├── default -> /etc/nginx/sites-available/default
├── snippets
│   ├── fastcgi-php.conf
Enter fullscreen mode Exit fullscreen mode

Vamos descobrir para que serve cada um dos arquivos/pastas:

Arquivo/Pasta Descrição
conf.d/ Pasta com as configurações extras do Nginx. Nela, é possível criar um arquivo de configuração que será incluído automaticamente nas configurações gerais.
fastcgi.conf, fastcgi_params Configurações do fastcgi. Com eles, é possível incluir, excluir ou remover parâmetros usado pela interface entre o servidor da web e os aplicativos.
mime.types Funciona como um map para identificar o mimetype dos arquivos conforme a extensão dele.
modules-available/ Configuração dos módulos disponíveis. (Veremos sobre os módulos mais adiante)
modules-enabled/ Através de um symlink, indica quais módulos o Nginx deverá carregar e executar.
nginx.conf Configuração geral do Nginx. Nele, contém configuração básica de formatação de log, SSL, upload, gzip, pid (Process Identifier, no Unix), número de conexões simultâneas por processo.
proxy_params Configurações usada com o recurso de proxy reverso. (Veremos um pouco ao configurar o ExpressJs com o NodeJs).
sites-available/ Nesta pasta, ficam as configurações dos servidores virtuais.
sites-enabled/ Nesta pasta, ficam os servidores virtuais ativos. Caso o arquivo de configuração esteja em sites-available, mas não esteja em sites-enabled, o Nginx não irá carregá-lo.
snippets/ Configurações extras.

Sabendo disso, vamos continuar.


Configurando

Nesta etapa, configuraremos o Nginx para servir o WordPress e com o NodeJS (ExpressJS). Portanto, presume-se que você os conheças e os tenha instalados em seu sistema.

Removeremos os arquivos de configuração padrão. Ele não será necessário.

sudo rm /etc/nginx/sites-available/default
sudo rm /etc/nginx/sites-enabled/default
Enter fullscreen mode Exit fullscreen mode

PHP 8.x (WordPress)

Vamos criar um arquivo de configuração específico para esse site; dessa forma, deixaremos os arquivos mais organizados.

# Cria o arquivo de configuração
sudo touch /etc/nginx/sites-available/php.valdeir.dev.conf

# Habilita o servidor virtual
sudo ln -s /etc/nginx/sites-available/php.valdeir.dev.conf /etc/nginx/sites-enabled/php.valdeir.dev.conf
Enter fullscreen mode Exit fullscreen mode

Agora, vamos escrever nossas regras. No arquivo /etc/nginx/sites-available/node.valdeir.dev, utilize o código abaixo.

A explicação está no arquivo para facilitar o entendimento

# Default server configuration
#
server {
listen 80;
listen [::]:80;
# Informa onde a aplicação está instalada.
# Utilize a pasta onde está o arquivo *index.php*
#
root /var/www/html/devto/php;
# Indica os arquivos que o Nginx deve pesquisar quando o usuário
# não informar na URL. Isso significa que se o usuário acessar "https://example.com"
# o Nginx deverá procurar o arquivo "https://example.com/index.php" e, caso não o
# encontre, ele irá buscar "https://example.com/index.html" e assim por diante
#
index index.php index.html index.htm;
# Define o domínio do site
# http://php.valdeir.dev
#
server_name php.valdeir.dev php.valdeirsantana.com.br;
# Informa o arquivo de log. Por padrão, ele registrará todos os acesso
#
access_log /var/www/html/devto/wordpress.log;
# Habilita configurações para envio de arquivos e permite o envio de arquivos com até 512MB
#
sendfile on;
client_max_body_size 512m;
# Define o bloco de configuração para site. Todo o acesse passará
# por este bloco.
#
location / {
# Verifica a existência dos arquivos acessados na ordem especificada.
# Usa o primeiro arquivo encontrado para o processamento da solicitação.
# Se o usuário acessar "http://php.valdeirpsr.com.br/wp-admin/setup-config.php",
# o Nginx irá verificar se ele existe ($uri); se não existe, verifica se é uma pasta
# ($uri/); se não for, redireciona para o arquivo "index.php"
#
try_files $uri $uri/ /index.php$is_args$args;
}
# Define o bloco de configuração para os arquivos da pasta "wp-includes"
# e o arquivo *xmlrpc.php*
#
location ~* /(wp-includes|xmlrpc)/.*.php$ {
deny all; # Bloqueia todos os acessos direto pelo navegador ou cliente
access_log off; # Desabilita logs de acesso
log_not_found off; # Desabilita logs do tipo 404
}
# Define o bloco de configuração para os arquivos da pasta "wp-content/*"
# Evita que alguém envie um arquivo malicioso e acesse-o diretamente, abrindo
# brechas no site.
#
location ~* /wp-content/(plugins|languages|uploads|upgrade|themes)/.*.php$ {
deny all;
}
# Configuração do PHP
#
location ~ \.php$ {
# Inclui o arquivo com as configurações do fastcgi para PHP
include snippets/fastcgi-php.conf;
# Informa o PID do PHP 8.0. Isso permite ao FastCGI integrar com o PHP
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
# Caso utilize php-cgi
#fastcgi_pass 127.0.0.1:9000;
}
# Define o bloco de configuração para os arquivos estáticos como imagens, css e js
#
location ~* \.(jpg|jpeg|gif|css|js|png|ico|woff|woff2|ttf|ttc|otf|eot)$ {
access_log off; # Desabilita log de acesso
expires 30d; # Informa o tempo de expiração do cache (30 dias)
}
}

Reinicie o Nginx para ele carregar as novas configurações.

sudo nginx -s reload
Enter fullscreen mode Exit fullscreen mode

NodeJS

Para começar, vamos criar um arquivo de configuração e um link simbólico para ele.

# Cria o arquivo de configuração
sudo touch /etc/nginx/sites-available/node.conf

# Habilita o servidor virtual
sudo ln -s /etc/nginx/sites-available/node.conf /etc/nginx/sites-enabled/node.conf
Enter fullscreen mode Exit fullscreen mode

Agora, escreveremos nossas regras. No arquivo /etc/nginx/sites-available/node, utilize o código abaixo.

A explicação está no arquivo para facilitar o entendimento

# Default server configuration
#
server {
# Define a porta que o Nginx deverá ouvir no IPV4 e IPV6
#
listen 80;
listen [::]:80;
# Define o domínio do site.
# http://node.valdeir.dev
#
server_name node.valdeir.dev;
# Define o bloco de configuração para site. Todo o acesso passará
# por este bloco.
#
# As demais configurações de proxy estão no arquivo `/etc/nginx/proxy_params`
# como mostrado acima
#
location / {
# Inclui o arquivo com as configurações do fastcgi para PHP
include proxy_params;
# O `proxy_set_header` permite enviar "headers" para o servidor de origem
#
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Servidor de origem. Toda a requisição será repassada para ele
#
proxy_pass http://127.0.0.1:3000;
}
}

Para criação do servidor, utilizaremos a API Http do NodeJS, que retornará um "Olá, mundo".

/* filename: server.js */
const http = require('http');
const PORT = process.env.PORT || 3000;
const server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('Hello World!');
res.end();
});
server.listen(PORT, () => {
console.log(`Servidor iniciado http://127.0.0.1:${PORT}`)
});
view raw server.js hosted with ❤ by GitHub

Reinicie o Nginx para ele carregar as novas configurações.

sudo nginx -s reload
Enter fullscreen mode Exit fullscreen mode

Feito isso, basta iniciar o servidor com o node node server.js


Finalizado

É isso, finalizamos a primeira parte. Aprendemos o que é o Nginx, como ele funciona e como configurar uma aplicação com ele.

Nas próximas partes, falaremos sobre os módulos e como usá-los para obter mais segurança e melhor performance no site. Ademais, falaremos sobre métricas e análise de logs.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay