Cómo crear un proxy inverso entre el servidor web Nginx y un servidor de aplicaciones Java

Escrito por el , actualizado el .
planeta-codigo software software-libre web
Enlace permanente Comentarios

Continuando la serie de artículos sobre varios aspectos realizados muy comúnmente en las aplicaciones y servidores web en este artículo explicaré como hacer que un servidor web nginx haga de proxy inverso para un servidor de aplicaciones Java en este caso Tomcat.

Nginx

Tomcat

Las aplicaciones web dinámicas Java se despliegan en un contenedor de servlets o un servidor de aplicaciones como WildFly que implementa las especificaciones de los estándares de Java EE pero es habitual que los usuarios no accedan directamente al contenedor de aplicaciones Java sino que se ponga delante un servidor web como Apache o Nginx con la tarea de que realice algunas tareas. Las tareas que puede realizar un servidor web son varias como:

Esquema de un proxy inverso

Un proxy inverso recibe las peticiones de internet y las reenvía a los servidores de una red interna sin necesidad de que los clientes conozcan la red interna

Para que un servidor web como Nginx actúe como proxy inverso o reverse proxy para un servidor de aplicaciones debemos añadir unas pocas directivas al archivo de configuración del servidor web. En el caso de Nginx usando la directiva proxy_pass donde indicamos para una localización la URL del servidor de aplicaciones a la que se le solicitará el contenido, en el ejemplo usando un servidor Tomcat.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
server {
	listen 80;

	location / {
		proxy_pass http://tomcat:8080;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-Proto https;
	}
}
nginx.conf

Una forma fácil de probarlo es usando Docker y Docker Compose que en varios artículos introductorios siendo el primero el inicio básico de Docker comento como empezar a usarlo y en que consiste esta nueva forma de ejecución para las aplicaciones. Con el siguiente archivo de Docker Compose creamos dos contenedores uno para Nginx en el que proporcionamos su configuración personalizada y otro contenedor para Tomcat.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
tomcat:
  image: tomcat

nginx:
  image: nginx:alpine
  volumes:
    - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
  links:
    - tomcat
  ports:
    - "80:80"
docker-compose.yml

Al hacer un proxy inverso debemos tener en cuenta que el servidor Tomcat si devuelve URL absolutas las haga siendo las del servidor web por las que se accede a la aplicación, si únicamente genera URL relativas no deberemos hacer nada pero en el caso de absolutas el servidor Tomcat deberá conocer el protocolo usado en el servidor web (HTTP o HTTPS) y el puerto del servidor web que suele ser 80 para HTTP y 443 para HTTPS pero que en el servidor Tomcat suele ser 8080 para HTTP y 8443 para HTTPS. Si el protocolo y puerto usado en el servidor web y servidor de aplicaciones es diferente y una aplicación genera URL absolutas el servidor de aplicaciones deberá tener esto en cuenta que es lo que se usa el en servidor web.

En la documentación se comentan varios parámetros de configuración de Tomcat como proxyPort y scheme que ajustan la información devuelta por los métodos request.getServerPort() y request.getScheme() y que nos servirá en caso de tener que generar URLs absolutas.

Arrancado los contenedores con el comando docker-compose up accediendo al servidor web veremos que el contenido proporcionado es el ofrecido por Tomcat, que con la configuración del ejemplo es la página de inicio de Tomcat. En las cabeceras de respuesta Nginx añade una, Server, indicando su versión.

Nginx configurado como proxy inverso de un servidor de aplicaciones Tomcat

Nginx configurado como proxy inverso de un servidor de aplicaciones Tomcat

En la documentación sobre reverse proxy de Nginx se explican algunas directivas más para pasar al servidor Tomcat la dirección IP del usuario usando cabeceras HTTP, en la configuración de Nginx usando proxy_set_header.

Nginx y Apache como proxys inversos cubren algunos casos en los que son suficientes, aquellos en los que la configuración como proxys no es reducida y estática ya que requieren reiniciar el servidor web. Para la computación en la nube y arquitecturas de microservicios el proxy inverso Traefik está mejor adaptado ya que su configuración de enrutado es dinámica al tomarse de diferentes proveedores como Consul, Docker o Kubernetes.

Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando siguiente comando:
docker-compose up


Comparte el artículo: