Nginx es el servidor web y proxy inverso más utilizado en arquitecturas de contenedores debido a su arquitectura asíncrona basada en eventos (epoll en Linux), su mínimo consumo de memoria RAM (apenas 4 a 8 MB en una imagen nginx:alpine) y su capacidad para servir decenas de miles de archivos estáticos por segundo. Sin embargo, una configuración incorrecta de apenas tres líneas en /etc/nginx/conf.d/default.conf puede arruinar por completo la indexación de un sitio web en motores de búsqueda como Google.
1. El Peligro Oculto del "Soft 404" al Copiar Configuraciones de SPA
En aplicaciones de página única (SPA) construidas con React Router o Vue Router que manejan rutas en el cliente sin archivos físicos en el servidor, se suele utilizar la directiva:
# ⚠️ PELIGROSO en sitios multipágina o estáticos:
location / {
try_files $uri $uri/ /index.html;
}
Cuando esta regla se aplica a un portal web multipágina o corporativo, ocurre un desastre silencioso para el SEO técnico y los rastreadores de calidad:
- Si un rastreador solicita una URL que no existe (por ejemplo, un enlace antiguo,
/favicon.icofaltante o una ruta exploratoria deGooglebot), Nginx no devuelve un código404 Not Found, sino que responde conHTTP 200 OKentregando el contenido completo de/index.html. - Para el motor de búsqueda, miles de URLs distintas parecen existir y contener exactamente el mismo texto duplicado de la página de inicio, lo que se clasifica como Soft 404 masivo y contenido duplicado.
2. Configuración Correcta con Resolución de Extensiones Limpias y 404 Real
En un sitio multipágina moderno, queremos que tanto /articulos.html como /articulos funcionen limpiamente, pero que cualquier ruta inexistente devuelva un código HTTP 404 semántico acompañado de una página de error útil para el usuario:
server {
listen 80;
server_name inovaxsoft.com;
root /usr/share/nginx/html;
index index.html;
# Redirección canónica 301 de www a dominio raíz
if ($host = 'www.inovaxsoft.com') {
return 301 https://inovaxsoft.com$request_uri;
}
error_page 404 /404.html;
location = /404.html {
internal;
}
location = /sitemap.xml {
default_type application/xml;
try_files $uri =404;
add_header Cache-Control "public, max-age=3600";
}
location / {
try_files $uri $uri.html $uri/ =404;
}
}
3. Políticas de Caché Diferenciadas y Compresión Gzip
Para obtener puntuaciones superiores a 98/100 en Google Lighthouse y Core Web Vitals (LCP, FCP, CLS), la compresión Gzip debe activarse para todos los tipos MIME textuales (HTML, CSS, JS, JSON, XML y SVG) con una longitud mínima de 256 bytes, manteniendo políticas de caché diferenciadas:
- Activos estáticos (CSS, JS, SVG, fuentes WOFF2):
Cache-Control: public, max-age=604800para evitar descargas repetidas al navegar entre artículos. - Documentos HTML y Sitemap:
Cache-Control: public, max-age=0, must-revalidate(validación mediante cabeceraETag), permitiendo que si el documento no ha cambiado, el servidor responda instantáneamente con304 Not Modified(0 bytes de cuerpo), y si se publicó un nuevo artículo, el navegador lo reciba al instante.