Diretivas do Nginx
Olá, galerinha, pronto para mais uma postagem? 🥳
Vamos conhecer e aprender como utilizar algumas das diretivas mais importantes do Nginx.
De acordo com a documentação oficial, o nginx consiste em módulos controlados por diretivas especificadas nos arquivos de configuração. Elas são divididas em diretivas simples e diretivas em bloco.
Uma diretiva simples consiste no nome e nos parâmetros separados por espaços e com um ponto e vírgula (;
) no final.
Uma diretiva de bloco permite que o desenvolvedor utilize outras diretivas dentro de chaves ({
e }
). Quando isso ocorre, essa diretiva de bloco é chamada de contexto (exemplos: events
, http
, server
e location
).
Vamos conhecer as diretivas.
add_header (fonte)
Como o nome deixa claro, essa diretiva serve para definir headers direto do Nginx. Isso é útil para definir os cabeçalhos de CORS, por exemplo.
# Syntax: add_header name value [always];
# Default: —
# Context: http, server, location, if in location
#
location /upload {
add_header "Access-Control-Allow-Origin" "https://*.valdeir.dev";
add_header "Access-Control-Allow-Methods" "GET, OPTIONS";
add_header X-Dev "Valdeir Psr" always;
}
O cabeçalho da requisição acima será:
http http://php.valdeirpsr.com.br/upload/foto.jpg
HTTP/1.1 200 OK
Content-Length: 1333425
Content-Type: image/jpeg
Date: Fri, 27 Aug 2021 15:28:23 GMT
access-control-allow-methods: GET, OPTIONS
access-control-allow-origin: https://*.valdeir.dev
x-dev: Valdeir Psr
+-----------------------------------------+
| NOTE: binary data not shown in terminal |
+-----------------------------------------+
alias (fonte)
Com a diretiva alias
, podemos substituir a localização da pasta definida na diretiva root
.
root /var/www/html;
location /css {
# Syntax: alias path;
# Default: —
# Context: location
#
alias /dev/vda2/css/;
}
Isso significa que a requisição https://valdeir.psr/css/global.css
carregará os arquivos da pasta /dev/vda2/css
.
HTTP | File |
---|---|
https://valdeir.psr/css/global.css | /dev/vda2/css/global.css |
https://valdeir.psr/images/logo.svg | /var/www/html/images/logo.svg |
client_max_body_size (fonte)
Você pode usar essa diretiva para configurar o tamanho máximo do corpo da requisição. Útil para limitar o tamanho de arquivos em formulários de upload. Caso o valor definido seja 0
, desabilita a verificação do tamanho dos dados enviados.
# Syntax: client_max_body_size size;
# Default: client_max_body_size 1m;
# Context: http, server, location
#
client_max_body_size 1G;
error_page (fonte)
A diretiva permite a customização de uma página de erro. Quando a página retornar o erro 404, por exemplo, então o Nginx irá retornar para o usuário o arquivo /not_found.html
.
# Syntax: error_page code ... [=[response]] uri;
# Default: —
# Context: http, server, location
#
error_page 404 /not_found.html
error_page 500 502 503 504 /50x.html;
Também é possível redirecionar o usuário para outra página ou domínio com um novo status code
server_name valdeir.dev;
error_page 401 =200 https://auth.$server_name;
Observação: O parâmetro
code
não pode ser igual a 499, menor que 300 ou maior que 599.
listen (fonte)
Essa diretiva permite definir qual o endereço e/ou porta o Nginx deverá "ouvir" as requisições. Por padrão, o servidor usará as portas 80 e 8000.
# Syntax address: listen address[:port] [default_server] [ssl] [http2];
#
# Syntax port: listen port [default_server] [ssl] [http2];
#
# Syntax PID: listen unix:path [default_server] [ssl] [http2];
#
# Default: listen *:80 | *:8000;
# Context: server
#
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
Parâmetros adicionais
- default_server
- Informa se o servidor virtual é o padrão. Caso o parâmetro não seja informado, o primeiro servidor localizado será definido como padrão. Você pode utilizar esse parâmetro apenas em um servidor virtual.
- ssl
- Esse parâmetro informa se o servidor deve receber conexões criptografadas. Lembrando que, ao utilizar esse parâmetro, é importante configurar as diretivas
ssl_certificate
essl_certificate_key
com as chaves para que o Nginx consiga descritografar as informações e repassá-las à aplicação. - http2
- Indica que o Nginx deve aceitar conexões com o protocolo HTTP/2. Lembrando que o SSL é obrigatório para o uso desse protocolo.
location (fonte)
A diretiva mais utilizada. Ela serve para aplicar configurações de acordo com a URI da requisição, que pode ser identificada com o uso de expressões regulares ou correspondência exata.
# Syntax: location [ = | ~ | ~* | ^~ ] uri { ... }
# location @name { ... }
# Default: —
# Context: server, location
#
Utilizando os modificadores
O uso do modificador =
indica que as configurações deverão ser aplicadas apenas quando a URI for exatamente igual ao valor informado no parâmetro URI
. No exemplo abaixo, as configurações serão aplicadas na URI /upload
, porém não serão aplicadas na URI /upload/avatar.svg
, por exemplo.
location = /upload {
...
}
O uso do modificador ~
indica que as configurações deverão ser aplicadas quando a URI for correspondente à expressão regular definida na diretiva. No exemplo abaixo, as configurações serão aplicadas nas URI /upload/avatar.jpeg
, /upload/avatar.jpg
, /upload/avatar.gif
e /upload/avatar.webp
, porém não serão aplicadas nas URI /upload/avatar.mp4
, /upload/avatar.jpg.avif
ou /UPLOAD/avatar.jpg
.
location ~ /upload/.*\.(jpe?g|gif|webp)$ {
...
}
O modificador ~*
funciona da mesma forma que ~
. A diferença é que essa é case-insensitive e esta, não; ou seja, utilizando o modificador ~*
, a URI /upload/avatar.jpg
e /UPLOAD/avatar.jpg
serão processadas igualmente.
location ~* /upload/.*\.(jpe?g|gif|webp)$ {
...
}
O modificador ^~
determina que o NGINX deverá parar de pesquisar correspondências mais específicas e utilizar essa diretiva.
location ^~ /upload/.*\.(jpe?g|gif|webp)$ {
# Para aqui e não continua
}
location ~* \.(jpe?g|gif|webp)$ {
...
}
Caso nenhum modificador seja utilizado, o Nginx comparará o início da URI com parte da URL. No exemplo abaixo, as configurações da diretiva location
serão aplicadas em /upload
, /upload/avatar.jpg
e /uploadsssss/avatar.jpg
, por exemplo. Esse modo diferencia maiúscula de minúscula.
location /upload {
...
}
Capturando grupos de RegEx
Na diretiva location
, você pode capturar os grupos definidos em sua RegEx. Isso é útil para tornar as configurações dinâmicas.
root /var/www/html;
location ~* /profile/([^/]+).jpg {
alias /dev/vda2/users/$1/avatar.jpg;
}
No exemplo acima, informamos que requisições com a URI /profile/qualquer-coisa.jpg
será apontada para o arquivo /dev/vda2/users/qualquer-coisa/avatar.jpg
.
Nomeando location
Nomear a diretiva location
é importante para reutilizá-la em outras partes do código ou quebrar as regras em pedaços para facilitar a manutenção e/ou leitura dos arquivos de configuração. A sintaxe é semelhante as que já foram mostradas. A diferença está no parâmetro @
.
location / {
try_files $uri $uri/ @opencart;
}
location ~ ^/sitemap.xml$ {
try_files $uri @opencart;
}
location @opencart {
rewrite ^/sitemap.xml$ /index.php?route=extension/feed/google_sitemap last;
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
map (fonte)
A diretiva map
permite criar variáveis de acordo com um mapeamento feito através de valores key:value definidos nela. É útil para tornar as configurações dinâmicas.
No exemplo abaixo, utilizamos a variável $http_user_agent
, que é nativa do Nginx, para capturar o User Agent do usuário e comparar com as chaves. Se a variável do Nginx for igual à chave, então define um valor na variável a ser criada.
# Syntax: map $variable_nginx $variable_name { ... }
# Default: —
# Context: http
#
map $http_user_agent $ua_blocked {
default 0; # Parâmetro
~Jorgee 1; # Block "Jorgee", "One Jorgee Two"
~ZmEu 1;
~*Spam 1; # Block "SPAM", "One spam Two"
~*Scan 1;
Scanner 1; # Block "Scanner", but not "PSR-Scanner"
Wget 1;
curl 1;
}
server {
if ($ua_blocked) {
return 403;
}
}
No exemplo acima, se a variável $http_user_agent
for igual à Jorgee
, ZmEu
, Spam
etc., define o valor 1 à variável $ua_blocked
. Caso valor nenhum coincida, utiliza o valor do parâmetro default
.
Ao usar ~
ou ~*
, você indica que o Nginx deve tratar a chave como expressão regular case-sensitive e case-insensitive, respectivamente. Não usá-las, indica que a correspondência deve ser exata.
Parâmetros do map
- default <valor>
- Define um valor padrão que retornará quando as regras não corresponderem às chaves definidas.
- include <arquivo>
- Inclui um arquivo com valores. Pode haver várias inclusões.
- volatile
- Indica que a variável não pode ser armazenada em cache.
- hostnames
- Indica que os valores de origem podem ser nomes de host com um prefixo ou máscara de sufixo.
Funcionamento do map
Se houver mais de uma correspondência, o Nginx seguirá a ordem abaixo:
- Valor string sem máscara;
- Valor da string mais longa com uma máscara de prefixo, por exemplo: *.example.com;
- Valor da string mais longa com uma máscara de sufixo, por exemplo, mail.*;
- Primeiro valor encontrado com a expressão regular;
- Valor do parâmetro
default
.
return (fonte)
Ao utilizar essa diretiva, o Nginx irá parar o processamento e retornará um valor definido ou um redirecionamento de página.
No exemplo abaixo, ao utilizar o código de status 301 ou 302 ou apenas uma URL, o Nginx informará ao navegador que o cliente deve ser redirecionado para a URL informada.
Ao utilizar o código de status 444, o Nginx fechará a conexão e não retornará uma resposta.
Em qualquer outro código de status, o Nginx retornará o texto como o corpo da resposta.
# Syntax: return code [text];
# return [301|302] URL;
# Default: —
# Context: server, location, if
#
location /retorna {
return 200 "Corpo da Mensagem";
}
location /movido-permanente {
return 301 https://another-url.com;
}
location /movido-temporario {
return $scheme://auth.$server_name; # Equivale a https://auth.valdeir.dev
}
location /fechado {
return 444;
}
rewrite (fonte)
A diretiva permite reescrever a URI internamente ou redirecionar o usuário para outra página utilizando o status code 301 ou 302. Caso haja mais de uma diretiva rewrite
, a URI poderá ser substituída/processada até a última diretiva ou conforme o uso das flags.
# Syntax: rewrite regex replacement [flag];
# Default: —
# Context: server, location, if
#
rewrite ^/sitemap.xml$ /index.php?route=extension/feed/google_sitemap last;
Flag (opcional)
- last
- Para o processamento atual e busca um bloco
location
que corresponda à nova URI. - break
- Para o processamento atual e retorna a resposta para o usuário.
- redirect
- Informa ao navegador que o usuário deverá ser redirecionado se o parâmetro
replacement
iniciar com https://, http:// ou a variável$scheme
. O redirecionamento deverá ser feito com o status code 302 - permanent
- Informa ao navegador que o usuário deverá ser redirecionado se o parâmetro
replacement
iniciar com https://, http:// ou a variável$scheme
. O redirecionamento deverá ser feito com o status code 301
Quando usar last
ou break
?
Como explicado, o last
buscará um novo bloco location
para tratar a URI substituída. Caso utilize essa flag dentro do contexto location
, o Nginx poderá entrar em um loop infinito e gerar o erro 500. Portanto, quando possível, opte por break
quando estiver no contexto do location
; e, last
, server
.
server {
rewrite ^/upload/(.*)$ /upload/foto/$1 last;
}
location /static/(.*) {
rewrite ^/static/(.*)$ /static/foto/$1 break; # O `break` evita o erro 500
}
Atenção! O grupo capturado na RegExp pode ser substituído ao usar
map
. Para resolver, você pode usar um nome para o grupo ou criar uma variável antes de usar a diretivarewrite
.
# Permite que o Nginx retorne uma imagem otimizada de acordo com o navegador
# Para saber mais, acesse o link <link-do-próximo-artigo>
#
map $uri $file_ext {
...
}
location /upload {
set $file_extension $file_ext;
rewrite ^/upload/(.*)\..+$ "/static/$1$file_extension" break;
}
root (fonte)
Define o diretório para as requisições. No exemplo abaixo, ao acessar a URI /css
, o Nginx carregará o arquivo da pasta /dev/vda2/css/
em vez do diretório /var/www/html
.
Caso a diretiva root
não seja definida no escopo location
, o Nginx buscará na diretiva server
e caso não encontre, buscará na diretiva http
.
server {
# Syntax: root path;
# Default: root html;
# Context: http, server, location, if in location
#
root /var/www/html;
location /css {
root /dev/vda2/css;
}
}
Quando usar alias
e root
?
O root
adiciona a URI ao construir o caminho do arquivo, enquanto o alias
modifica a URI. Além disso, o alias
não pode estar dentro do contexto location
nomeado e não pode usar a variável $realpath_root
.
# Na requisição `/foto/luisa.jpg`, o Nginx carregará o arquivo
# /var/www/html/static/foto/luisa.jpg
#
location /foto {
root /var/www/html/static;
}
# Na requisição `/imagem/sonza.jpg`, o Nginx carregará o arquivo
# /var/www/html/static/sonza.jpg
#
location /imagem {
alias /var/www/html/static/;
}
server (fonte)
Essa diretiva em bloco serve para criar um servidor virtual.
# Syntax: server { ... }
# Default: —
# Context: http
#
server {
server_name valdeir.dev www.valdeir.dev;
}
server_name (fonte)
Define o nome/URL do servidor virtual criado. É possível definir mais de um nome quando separados por espaços. A diretiva, assim como rewrite
e location
, permite o uso de expressões regulares.
Criaremos abaixo um servidor virtual que receberá as requisições das URLS:
- valdeir.dev
- cdn.valdeir.dev
- assets.valdeir.dev
- qualquer-coisa.valdeir.cdn
server {
# Syntax: server_name name ...;
# Default: server_name "";
# Context: server
#
server_name valdeir.dev ~(cdn|assets)\.valdeir\.dev$ *.valdeir.cdn;
}
Atenção! Para utilizar RegExp, é necessário que o Nginx tenha sido compilado com suporte à biblioteca
PCRE
.
Através da diretiva server_name
, você pode criar variáveis de acordo com os grupos capturados na sua expressão regular.
server {
server_name ~^(www\.)?(?<domain>.+)$;
location / {
root /sites/$domain;
}
}
server {
server_name _;
location / {
root /sites/default;
}
}
Ordem na busca pelos servidor
Quando há mais de um nome de servidor, o Nginx seguirá a seguinte ordem:
- Procurar pelo nome exato (valdeir.dev);
- Procurar pelo nome mais longo com o wildcard (
*
) como prefixo (*.valdeir.dev); - Procurar pelo nome mais longo com o wildcard (
*
) como sufixo (valdeir.*); - Procurar pela primeira ocorrência usando expressão regular.
Observação! Você, obviamente, deve cadastrar corretamente os dados de CDN que redirecione o site para seu servidor.
try_files (fonte)
Essa diretiva verificará se um arquivo existe seguindo a ordem pré-definida pelo administrador. O processamento é feito semelhante ao das diretivas alias
e root
. Ela permite também que o cliente possa acessar uma pasta quando o valor terminar com uma barra (/
). Isso é útil quando o desenvolvedor utiliza a diretiva autoindex
. Se arquivo nenhum for encontrado, o o usuário será redirecionado para outra página, URL ou bloco location
nomeado.
root /var/www/html;
autoindex on;
location /upload {
# Syntax: try_files file ... uri;
# try_files file ... =code;
# Default: —
# Context: server, location
#
try_files $uri $uri/ /empty.gif =444;
}
No exemplo acima, ao acessar a requisição /upload/avatar.webp
, o Nginx seguirá a seguinte ordem:
- Verifica se o arquivo
/var/www/html/upload/avatar.webp
existe; se não existir, - Verifica se a pasta
/var/www/html/upload/avatar.webp/
existe; se não existir, - Verifica se o arquivo
/var/www/html/empty.gif
existe; se não existir, - Fecha a conexão sem uma resposta (usando o
=444
).
É possível também utilizar bloco location
nomeado.
location / {
try_files $uri $uri/ @opencart;
}
location @opencart {
rewrite ^/sitemap.xml$ /index.php?route=extension/feed/google_sitemap last;
rewrite ^/googlebase.xml$ /index.php?route=extension/feed/google_base last;
rewrite ^/system/storage/(.*) /index.php?route=error/not_found last;
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
location ~* (\.twig|\.tpl|\.ini|\.log|(?<!robots)\.txt)$ {
deny all;
}
Conclusão
Essas foram as diretivas mais utilizadas no Nginx. Nas próximas postagens, aprenderemos como aumentar a segurança e a performance do nosso site. Beleza? 👍
Top comments (3)
Oii!
Se sabe me dizer se é um bug ou erro meu em configuração do Nginx.
Tenho um VPS com 4 sites apenas!
2 com PHP já antigos e funcionando desde sempre com Nginx.
2 novos em node.
Mas acontece algo interessante.
Quando coloco o arquivo de configuração
siteEmNode.com.br
E dentro coloco todas as info corretas
Uso o Nginx como proxy no caso do Node.
Testo a config. Não tem erro.
Crio o link simbolico e restarto o nginx.
Ai vou acessar a URL siteEmNode.com.br
E aparece outro site que esta no meu server.
segundositeEMphp.com.br
A URL esta correta. E o site não!
Não tem erros. Ta tudo 100% correto.
E não aparece o site correto.
Então eu, vou lá e mudo siteEmNode.com.br para
default, crio o link simbólico, acesso o site siteEmNode.com.br
E aparece corretamente! Perfeito.
Ai eu fui lá e mudei o arquivo de default para > siteEmNode.com.br, criei o link simbólico.
E magicamente funcionou
Tive que por mais um site em node.
Deu o mesmo problema. Mas agora ainda não mudei default o nome do arquivo para o nome do site(por organização)
Se sabe me dizer se pode ser um erro de configuração
ou algum problema no nginx.
Pq uso PHP(servidor normal) e node(proxy)?
Abraços
Olá!!
É necessário verificar se o link simbólico foi criado no lugar correto na primeira vez (acontece).
Se você utilizar
listen 80 default_server;
em um dos arquivos de configuração, o Nginx considerará que todas as URL que apontem para o IP do servidor carreguem-no caso a URL não seja encontrada em outro servidor virtual.Acho que fica mais fácil explicar o passo a passo.
default_server
na diretivalisten
."Tenho certeza que o symlink foi criado corretamente"
Neste caso, pode ser problema com cache do navegador ou CDN (CloudFlare, Akamai, Sucuri etc)
"Não é. Limpei os caches, habilitei o modo de desenvolvimento e estou no modo anônimo/privado do navegador"
Aí é um pouco mais complexo. Recomendo configurar o log de erro para o modo debug e verificar como o Nginx está carregando os arquivos de configuração.
nginx -T
;error_log /var/log/nginx/debug.log debug;
no contextohttp
;Só uso a porta 443. Nunca a 80.
Ma irei ver melhor tudo que vc falou.
Obrigado!