Objetivo: padronizar para manter e escalar sem dor
Em pequenos projetos, o maior ganho com Nginx não vem de “mais diretivas”, e sim de padrões repetíveis: uma estrutura de arquivos previsível, trechos reutilizáveis (snippets), nomes consistentes e templates de server que você copia e ajusta com segurança. O resultado é manutenção rápida, menos duplicação e revisões mais confiáveis antes de produção.
Padrão de organização por projeto
A ideia é separar o que muda por projeto (domínios, paths, upstreams) do que é comum (headers, timeouts, cache, segurança básica). Um layout simples e eficiente:
/etc/nginx/ nginx.conf conf.d/ 00-global.conf # ajustes globais pequenos (opcional) sites-available/ projeto-a.conf projeto-b.conf sites-enabled/ projeto-a.conf -> ../sites-available/projeto-a.conf snippets/ common-headers.conf common-timeouts.conf common-static.conf proxy-common.conf proxy-cache.conf letsencrypt-acme.conf upstreams/ projeto-a-upstreams.conf projeto-b-upstreams.conf maps/ projeto-a-maps.conf # variáveis reutilizáveis via map (opcional) logs/ (opcional: se você centraliza logs aqui; muitas distros usam /var/log/nginx)Como usar esse layout na prática
- Um arquivo por projeto em
sites-available/, contendo apenas osserverdaquele projeto e includes. - Upstreams por projeto em
upstreams/para evitar “upstream perdido” dentro de server blocks. - Snippets para blocos repetidos (headers, timeouts, proxy params, cache, ACME).
- Maps para variáveis derivadas (ex.: escolher um valor de cache por tipo de conteúdo, ou normalizar um header).
- Symlink em
sites-enabled/para ativar/desativar projetos sem apagar arquivos.
Convenções de nomes (que ajudam muito)
- Arquivos:
projeto-ambiente.conf(ex.:loja-prod.conf,loja-staging.conf). - Upstreams:
up_<projeto>_api,up_<projeto>_app(ex.:up_site_api). - Snippets: prefixe por função:
common-*.conf,proxy-*.conf,security-*.conf. - Logs: inclua projeto e tipo:
projeto.access.log,projeto.error.log(ou useaccess_logcom caminho em/var/log/nginx). - Comentários: com intenção e contexto (por que existe), não “o que faz” (o que faz já está na diretiva).
Snippets: como evitar duplicação sem perder clareza
Snippets devem ser pequenos, coesos e previsíveis. Evite snippets “gigantes” que misturam headers, proxy, cache e static; isso dificulta ajustes por caso.
Exemplo: headers comuns
# /etc/nginx/snippets/common-headers.conf# Objetivo: padronizar headers de segurança e comportamento em todos os projetos.# Ajuste conforme necessidade do seu ambiente (ex.: CSP).add_header X-Content-Type-Options nosniff always;add_header X-Frame-Options SAMEORIGIN always;add_header Referrer-Policy strict-origin-when-cross-origin always;Exemplo: timeouts e limites comuns (reutilizáveis)
# /etc/nginx/snippets/common-timeouts.conf# Objetivo: reduzir travamentos e conexões penduradas com valores padrão seguros.keepalive_timeout 15s;client_body_timeout 15s;client_header_timeout 15s;send_timeout 30s;Exemplo: proxy “base” (sem cache)
# /etc/nginx/snippets/proxy-common.conf# Objetivo: padronizar encaminhamento e headers para upstreams.proxy_http_version 1.1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_connect_timeout 5s;proxy_send_timeout 30s;proxy_read_timeout 30s;Exemplo: proxy com cache (apenas o que muda)
# /etc/nginx/snippets/proxy-cache.conf# Objetivo: habilitar cache de proxy quando o location decidir usar.proxy_cache my_cache;proxy_cache_valid 200 302 10m;proxy_cache_valid 404 1m;add_header X-Proxy-Cache $upstream_cache_status always;Repare no padrão: proxy-common.conf contém o “mínimo necessário” para proxy consistente; proxy-cache.conf adiciona apenas o que é específico de cache.
Variáveis reutilizáveis com map (quando vale a pena)
Quando você repete lógica condicional (por exemplo, escolher um tempo de cache por extensão), use map para centralizar. Isso reduz if e duplicação em múltiplos location.
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
# /etc/nginx/maps/projeto-a-maps.conf# Objetivo: definir TTL de cache de navegador por tipo de arquivo.map $uri $static_expires { default 1h; ~*\.(css|js)$ 7d; ~*\.(png|jpg|jpeg|gif|svg|ico|webp)$ 30d;}Depois, no location de estáticos, você usa expires $static_expires; sem repetir regras.
Templates de server blocks (para copiar e ajustar)
Templates são “moldes” com placeholders. A recomendação é manter 3 templates: estático, reverse proxy e proxy com cache. Você copia, renomeia e preenche: domínio, paths, upstream e logs.
Template 1: site estático
# TEMPLATE: site estático# Substituir: __DOMAIN__, __ROOT__, __ACCESS_LOG__, __ERROR_LOG__server { listen 80; server_name __DOMAIN__; root __ROOT__; index index.html; access_log __ACCESS_LOG__; error_log __ERROR_LOG__; include /etc/nginx/snippets/common-headers.conf; include /etc/nginx/snippets/common-timeouts.conf; location / { try_files $uri $uri/ /index.html; } location ~* \.(css|js|png|jpg|jpeg|gif|svg|ico|webp)$ { expires 7d; add_header Cache-Control "public"; try_files $uri =404; }}Template 2: reverse proxy para aplicação/API
# TEMPLATE: reverse proxy (sem cache)# Substituir: __DOMAIN__, __UPSTREAM__, __ACCESS_LOG__, __ERROR_LOG__server { listen 80; server_name __DOMAIN__; access_log __ACCESS_LOG__; error_log __ERROR_LOG__; include /etc/nginx/snippets/common-headers.conf; include /etc/nginx/snippets/common-timeouts.conf; location / { include /etc/nginx/snippets/proxy-common.conf; proxy_pass http://__UPSTREAM__; }}Template 3: proxy com cache (para endpoints cacheáveis)
# TEMPLATE: proxy com cache# Substituir: __DOMAIN__, __UPSTREAM__, __ACCESS_LOG__, __ERROR_LOG__server { listen 80; server_name __DOMAIN__; access_log __ACCESS_LOG__; error_log __ERROR_LOG__; include /etc/nginx/snippets/common-headers.conf; include /etc/nginx/snippets/common-timeouts.conf; location / { include /etc/nginx/snippets/proxy-common.conf; include /etc/nginx/snippets/proxy-cache.conf; proxy_pass http://__UPSTREAM__; }}Observação de manutenção: em projetos pequenos, é comum ter um único server que serve estático e faz proxy para /api/. Nesse caso, você combina os templates por location, mantendo snippets para não duplicar.
Checklist de revisão antes de subir para produção
1) Validação de sintaxe e includes
- Rodar teste:
nginx -t - Se houver múltiplos arquivos, confirme que o arquivo do projeto está realmente incluído/ativado (symlink em
sites-enabled).
2) Reload seguro
- Após
nginx -tOK, aplicar:nginx -s reload(ou via service manager do sistema). - Se algo der errado, não “force”: corrija e teste novamente.
3) Permissões e caminhos
- root do site existe e o usuário do Nginx tem permissão de leitura.
- Diretórios de log existem e são graváveis (ou use o padrão do sistema).
- Arquivos referenciados em
includeexistem (snippets, upstreams, maps).
4) Logs: visibilidade mínima para diagnosticar
access_loghabilitado por projeto (facilita filtrar).error_logcom nível apropriado (ex.:warnouerror).- Faça um request de teste e confirme que aparece no access log.
5) Headers e comportamento HTTP
- Headers comuns aplicados (snippets) e sem duplicação conflitante.
- Para proxy: confirme que headers de encaminhamento estão presentes (
X-Forwarded-For,X-Forwarded-Proto).
6) Timeouts e limites coerentes com o serviço
- Time-out de leitura do proxy compatível com sua API (evite infinito).
- Se houver upload, confirme limites e tempo de envio (não deixe padrão implícito sem intenção).
7) Cache (quando usado)
- Cache aplicado apenas onde faz sentido (ex.: GET idempotente).
- Header de debug do cache (ex.:
X-Proxy-Cache) para validar comportamento.
Exemplo completo e limpo: site estático + API atrás de proxy
Cenário: um projeto pequeno com domínio site.local, front-end estático em /var/www/site e API em 127.0.0.1:3000. O Nginx serve o front e encaminha /api/ para a API. A configuração abaixo foca em organização e manutenção.
1) Upstream do projeto
# /etc/nginx/upstreams/site-upstreams.confupstream up_site_api { server 127.0.0.1:3000; keepalive 16;}2) Snippets reutilizáveis (mínimos)
# /etc/nginx/snippets/site-static.conf# Objetivo: regras comuns para conteúdo estático do projeto.location ~* \.(css|js|png|jpg|jpeg|gif|svg|ico|webp)$ { expires 7d; add_header Cache-Control "public"; try_files $uri =404;}3) Arquivo do site (server block do projeto)
# /etc/nginx/sites-available/site.conf# Projeto: site (front estático + API em /api/)# Ativação: ln -s /etc/nginx/sites-available/site.conf /etc/nginx/sites-enabled/site.confinclude /etc/nginx/upstreams/site-upstreams.conf;server { listen 80; server_name site.local; root /var/www/site; index index.html; access_log /var/log/nginx/site.access.log; error_log /var/log/nginx/site.error.log; include /etc/nginx/snippets/common-headers.conf; include /etc/nginx/snippets/common-timeouts.conf; # Front-end (SPA): tenta arquivo; se não existir, cai no index.html location / { try_files $uri $uri/ /index.html; } # Estáticos com cache de navegador include /etc/nginx/snippets/site-static.conf; # API atrás de proxy location /api/ { include /etc/nginx/snippets/proxy-common.conf; proxy_pass http://up_site_api; }}4) Passo a passo para colocar no ar (com esse padrão)
- Criar diretórios e arquivos:
/etc/nginx/upstreams/site-upstreams.conf,/etc/nginx/snippets/site-static.conf,/etc/nginx/sites-available/site.conf. - Ativar o site: criar symlink em
sites-enabled. - Testar:
nginx -t. - Recarregar:
nginx -s reload. - Validar: acessar
/(front) e/api/(API) e conferir/var/log/nginx/site.access.loge/var/log/nginx/site.error.log.