Arquitectura de referencia
El entorno implementado utiliza un servidor web como punto de entrada único para servir recursos estáticos y redirigir tráfico hacia un servidor de aplicaciones:
Cliente Web
│
▼
Nginx (Puerto 80)
│
├─────────────► Activos frontend (Vue.js)
│
└─────────────► API Backend (Puerto 3000)
El servidor web asume dos responsabilidades críticas: servir la interfaz de usuario y gestionar el enrutamiento de las llamadas a la API mediante proxy inverso.
Síntomas en entorno de producción
Tras realizar el despliegue, la carga inicial de la aplicación funciona correctamente. No obstante, al ejecutar una petición a un endpoint como GET /v1/reportes, el navegador intercepta una respuesta 404 Not Found.
La inspección en la pestaña de Red de las herramientas de desarrollo confirma:
- URL solicitada:
http://servidor-produccion/v1/reportes - Código de estado: 404
Para descartar fallos en la lógica del servidor de aplicaciones, se ejecutó una petición directa desde la máquina:
curl http://localhost:3000/v1/reportes
La respuesta fue exitosa (200 OK), lo que evidencia que el problema se origina exclusivamente en la capa de enrutamiento de Nginx.
Análisis del mecanismo de reescritura de rutas
El bloque de configuración responsable del proxy contenía el siguiente fragmento:
server {
listen 80;
server_name aplicacion.local;
location /static/ {
root /var/www/frontend/build;
index index.html;
}
location /v1/ {
proxy_pass http://servicio-app:3000/;
}
}
Existe un comportamiento técnico crítico en Nginx respecto al uso del carácter de barra final (/) en la directiva proxy_pass. Su presencia o ausencia determina si el motor de proxy reescribe o conserva la URI original.
Comportamiento con barra final en proxy_pass
location /v1/ {
proxy_pass http://servicio-app:3000/;
}
Si el cliente solicita /v1/reportes, Nginx elimina el prefijo coincidente y lo reemplaza por la ruta definida en la directiva. La petición reenviada al backend será:
http://servicio-app:3000/reportes
Dado que el servidor de aplicaciones espera la ruta completa con el prefijo /v1/, no encunetra el controlador y devuelve 404.
Comportamiento sin barra final
location /v1/ {
proxy_pass http://servicio-app:3000;
}
Al omitir la barra, Nginx preserva la URI solicitada. La misma petición /v1/reportes se transforma en:
http://servicio-app:3000/v1/reportes
Esta coincidencia permite que el backend procese la solicitud sin modificaciones.
Configuración corregida
Para resolver el conflicto, se eliminó la barra inclinada al final de la directiva de proxy:
location /v1/ {
proxy_pass http://servicio-app:3000;
}
Tras aplicar el cambio, se validó la sintaxis y se recargó el servicio:
sudo nginx -t
sudo systemctl reload nginx
Las llamadas a la API comenzaron a retornar respuestas 200 OK sin necesidad de alterar el código fuente del servidor de aplicaciones.
Factores que ocultaron el fallo en desarrollo
Durante las etapas locales, los entornos de construcción (como Vite o Webpack) incluyen servidores de desarrollo con proxy integrado. Esta configuración maneja automáticamente las rutas de la API, evitando problemas de CORS y ocultando la configuración real de Nginx. Solo al migrar a un entorno de producción, donde Nginx actúa como puerta de entrada única, se manifestó la discrepancia en el enrutamiento de URLs.
Pautas para configuraciones robustas
- Verificar el mecanismo de coincidencia: No asumir que
locationactúa como un reenviador ciego. Comprender cómo Nginx procesa los prefijos y la expresión regular asociada. - Controlar la sintaxis de
proxy_pass: La diferencia entrehttp://backend:8080yhttp://backend:8080/altera drásticamente la ruta destino. Mantener un documento de referencia interno sobre este comportamiento. - Validación previa a la aplicación: Ejecutar siempre
nginx -tantes de realizar unreload. Utilizar entornos de staging que repliquen la topología exacta de producción. - Pruebas de extremo a extremo: Validar los endpoints críticos mediante herramientas como
curlo HTTPie contra el dominio público, no solo contralocalhost.