Nginx configuration to pass site directly to tomca

2019-01-30 02:19发布

问题:

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.

回答1:

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;
  }
}


回答2:

This Work for me:

Environment:

  • Amazon AWS
  • Ubuntu 14.04 TLS / 64 Bits
  • Nginx
  • Tomcat 7
  • Oracle JDK 1.7

Steps:

1) Install Oracle JDK

http://www.webupd8.org/2012/01/install-oracle-java-jdk-7-in-ubuntu-via.html

2) aptitude install tomcat7

3) Configure my context 3.1) - into /etc/tomcat7/Catalina/localhost add mi_context_file.xml

<Context path="/MyContext" docBase="local_path_to_my_context_files" privileged="true" reloadable="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>

3.2) create my site folder and extract my context

3.3) Add this lines to setup my_site:

server {
   listen   80;
   server_name my_site;
   #
   access_log /my_site_log/access-timed-combined.log timed_combined;
   error_log  /my_site_log/error.log;
   #
   root   /my_site_folder;
   index  index.html index.jsp;
   #
   location @MyContext {
      sendfile off;
      proxy_pass         http://127.0.0.1:8080;
      proxy_redirect     default;

      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_max_temp_file_size 0;

      #this is the maximum upload size
      client_max_body_size       10m;
      client_body_buffer_size    128k;

      proxy_connect_timeout      90;
      proxy_send_timeout         90;
      proxy_read_timeout         90;

      proxy_buffer_size          4k;
      proxy_buffers              4 32k;
      proxy_busy_buffers_size    64k;
      proxy_temp_file_write_size 64k;
   }
   #
   location ~ "^/MyContext/*" {
      try_files $uri @MyContext;
   }
}

3.4) Restart nginx and tomcat7. If your context not start enter into Tomcat7 manager and check the tomcat logs or restart your context from tomcat manager url.

3.5) Enter in your tomcat application context:

http://yoursite/MiContext

4) Nginx references:

Running Jenkins behind Nginx
https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Nginx

Load Balancing Apache Tomcat with nginx
http://blogs.mulesoft.org/load-balancing-apache-tomcat-with-nginx/

Nginx + Apache Tomcat Configuration Example
http://www.mkyong.com/nginx/nginx-apache-tomcat-configuration-example/

Configuring Nginx for Apache Tomcat 7
http://blog.rezajp.info/posts/configuring-nginx-for-apache-tomcat-7/

Install Tomcat with Nginx on Ubuntu 13.04 (Server)
http://www.laurii.info/2013/10/install-tomcat-nginx-ubuntu-server-13-04/

Nginx - Java servers like Jetty, GlassFish and Tomcat
http://wiki.nginx.org/JavaServers

Nginx - JavaHandler
http://wiki.nginx.org/JavaHandler

Virtual Host + Nginx + Tomcat
http://www.javacodegeeks.com/2013/02/virtual-host-nginx-tomcat.html


回答3:

I could solve the same issue with some modification, so I leave the record. I use Ubuntu 14.04, I installed tomcat with sudo apt-get install tomcat7.

I already have a war-demo.war file generated with lein (clojure application), and installed (loaded) from tomcat's manager webapp. The war is copied in /usr/lib/tomcat7.

Make conf file for nginx

server {
    listen  80; 
    server_name clojure2.example.com;

    location / { 
        proxy_pass                          http://127.0.0.1:8008/;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;  
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
    }
}

Modify the server.xml in /var/lib/tomcat7/conf

<Host name="clojure2.example.com" appBase="wardemo"                                                                   
    unpackWARS="true" autoDeploy="true">                                                                               
</Host> 

Copy war file

  1. Create a wardemo directory in `/var/lib/tomcat7
  2. Copy the war-demo.war in the wardemo directory as ROOT.war

That's it, I didn't need other configuration. In /var/lib/tomcat7/conf/Catalina, we have clojure2.example.com directory. I may be able to add some more configuration in the directory.



回答4:

My way of tuning this in: similar to others, but with some differences System - Ububtu 14.04

1) Create virtual host for the application. You need to add HOST to the server.xml in /etc/tomcat7

    <Host name="yourapp.com" appBase="webapps/yourapp" unpackWars="true" autoDeploy="true">
          <Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="virtual_log." suffix=".txt" timestamp="true" />
           <Context path="" docBase="path to your war" debug="0" reloadable="true" />
         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="virtual_log." suffix=".txt" pattern="common" />
  </Host>

2) Place your app to the "webapps" folder of /var/lib/tomcat7

3) Start tomcat - after this you will be able to visit your app locally entering yourapp.com:8080 (port is needed assuming that tomcat is working not on 80 port as this port - 80 - is being listened by NGINX)

3) Go to Nginx configuration and place there following lines

server {
  listen  80; 
  server_name yourapp.com;
  root            /var/lib/tomcat7/webapps/yourapp

 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;
 }
}

server {
  listen  80; 
  server_name rootapp.com; # this is app that is ROOT
  root            /var/lib/tomcat7/webapps

 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;
 }
}

4) Restart NGINX



标签: nginx tomcat7