Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx configuration to pass site directly to tomcat webapp with context

Tags:

nginx

tomcat7

tl;dr version

How do you setup nginx as a reverse proxy for example.com to a locally running tomcat webapp at http://127.0.0.1:8080/blah/ without breaking the pageContext?


Tomcat Setup

There exists a tomcat 7 webapp, blah, deployed with a .war file and sitting in /var/lib/tomcat7/webapps/blah/.

tomcat is running locally and accessible at http://127.0.0.1:8080. Multiple webapps are running and can be accessed at:

  • http://127.0.0.1:8080/blah/
  • http://127.0.0.1:8080/foo/
  • http://127.0.0.1:8080/bar/

Port 8080 is blocked externally by the firewall.

Nginx Setup

nginx is running on the server as the gatekeeper. One site is enabled to access all of the local tomcat webapps mentioned above. This works fine for example.com:

server { listen  80;  server_name example.com; root /var/lib/tomcat/webapps/ROOT/;    location / {      proxy_set_header X-Forwarded-Host $host;     proxy_set_header X-Forwarded-Server $host;     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;     proxy_pass http://127.0.0.1:8080/;   } } 

Question: how to configure an additional site to access blah directly?

Under /etc/nginx/sites-enabled/ an additional site file is setup to route http://blah.com to http://127.0.0.1:8080/blah/ but there are issues.

server {   listen  80;    server_name blah.com *.blah.com;   root /var/lib/tomcat/webapps/blah/;    location / {      proxy_set_header X-Forwarded-Host   $host;     proxy_set_header X-Real-IP          $remote_addr;       proxy_set_header X-Forwarded-Server $host;     proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;     proxy_pass                          http://127.0.0.1:8080/blah/;   } } 

This setup adds an extra blah to the context path, creating a 404 page because path /blah/blah/ doesn't exist, which makes sense. Is there a simple way within nginx to pass blah.com to the webapp root?

Within the webapp, I'm using ${pageContext.request.contextPath}/path for relative paths to webapp resource. I thought this was the correct way to handle internal tomcat paths but could this be part of the problem? I believe this is why I'm getting the extra blah in the route, creating the 404 page.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head>   <meta charset="UTF-8">   <meta http-equiv="refresh" content="0; url=${pageContext.request.contextPath}/form">   <script type="text/javascript">     window.location.href = "${pageContext.request.contextPath}/form"   </script>   <title>Load BLAH</title> </head> <body>   <p>If you are not redirected automatically, follow this <a href="${pageContext.request.contextPath}/form">link</a>.</p> </body> </html> 

This page is hit alright but the redirect goes to /blah/blah/form instead of /blah/form where the servlet actually exists.


I've also tried other approaches including pointing blah.com to the tomcat root itself. This works in the sense that you can get to blah via blah.com/blah/ but that's not really what we want.

Additionally, it is completely acceptable (and desired) to still be able to access blah via example.com/blah/.

Obviously, this is for an nginx novice but help me (and future novices) clear this up because the clear solution is eluding me and the nginx docs use the help too.

like image 367
bnjmn Avatar asked Nov 08 '13 18:11

bnjmn


People also ask

Can nginx and Tomcat run together?

By default, Tomcat is configured to run on port 8080, so you will need to configure Nginx as a reverse proxy to forward the request coming on port 8080 to the Nginx port 80. Once installed, create a new virtual host configuration file for Tomcat.

How will you configure a nginx or Apache server as a reverse proxy in front of Apache Tomcat Application?

Configure Nginx as a Reverse Proxy So Nginx will accept all requests over port 80 instead of the Tomcat server. Once installed, create a new virtual host configuration file for Tomcat. Congratulations! You can now access your Tomcat server using the URL http://your-domain.com without specifying the Tomcat port 8080.

What is $scheme in nginx?

The rewritten URL uses two NGINX variables to capture and replicate values from the original request URL: $scheme is the protocol (http or https) and $request_uri is the full URI including arguments. For a code in the 3xx series, the url parameter defines the new (rewritten) URL.


1 Answers

One possible solution is to create a virtual host within tomcat and set blah as the ROOT app on the new host. nginx will pass still pass requests to tomcat on localhost including the requested host header and tomcat will handle the rest with the correct context.

Setup the Virtual host

  1. Add a Host entry to the Engine portion of $CATALINA_HOME/conf/server.xml

    <Engine name="Catalina" defaultHost="localhost">   <Host name="localhost"  appBase="webapps"         unpackWARs="true" autoDeploy="true">   </Host>   <Host name="blah.com" appBase="blahApps"        unpackWARS="true" autoDeploy="true">       <Alias>www.blah.com</Alias>   </Host> </Engine> 
  2. Create the appBase directory $CATALINA_HOME/blahApps/

  3. Configure the context with $CATALINA_HOME/blahApps/ROOT/META-INF/context.xml

    <Context path="/"      antiResourceLocking="false" /> 
  4. Deploy blah to $CATALINA_HOME/blahApps/ROOT. This may be as simple as changing blah.war to ROOT.war.

Make sure nginx is still copacetic

Just proxy requests for blah.com to localhost and tomcat will take care of the rest:

server {   listen  80;    server_name blah.com www.blah.com;    location / {      proxy_pass                          http://127.0.0.1:8080/;     proxy_set_header Host               $host;     proxy_set_header X-Real-IP          $remote_addr;       proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;   } } 
like image 112
bnjmn Avatar answered Oct 20 '22 19:10

bnjmn