Nginx as a proxy for tomcat with subdirectory

nginxreverse-proxytomcat

I want to set up a Nginx Proxy for the Tomcat server with my domain name such as

example.com/demo/sample
example.com/demo/manager
example.com/demo/other_apps
...

Here is my Nginx server block configuration

server {
        listen   80;

        server_name example.com;

        location /demo/ {

        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_set_header Host $host;
        proxy_pass http://IP_ADD_TOMCAT_SERVER:8080/;

        }

        location ~ /\.ht {
                deny all;
        }

## Only allow these request methods ##
     if ($request_method !~ ^(GET|HEAD|POST)$ ) {
         return 444;
     }
## Do not accept DELETE, SEARCH and other methods ##

}

I encountered 2 problems here:

The First Problem:

if TOM_CAT_INSTALL_DIR/webapps/sample/ contains a static page hello.jsp, it works with URL:

example.com/demo/app1/

but not works with URL:

example.com/demo/app1

Why I must add a trailing slash / at the end of URL to make the nginx proxy working?


The Second Problem:

If TOM_CAT_INSTALL_DIR/webapps/manager contains a index.jsp file which is a dynamic webpage, it does not work with URL

example.com/demo/manager/

The URL becomes

example.com/manager/….

Followed by a long list of parameters.

if I manually add /demo/ string to the web browser URL, it works again.

How should I make the nginx proxy works with sub-directory /demo/?

Update: I found out the missing rewrite problem for tomcat manager subdirecotry is that in the index.jsp file, the request.getContextPath() will NOT automatically add /demo/ subdirecotry into the URL. It seems we have to manually modify the .jsp file code.

If you don't know how to modify the jsp code as I do, you can work around it by using the below code in Nginx

# Must add the trailing '/' for both location and proxy_pass
 location /demo/ {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_pass http://TOM_CAT_SERVER_IP_ADDR:8080/;
        }

# ONLY work for manager apps, for other apps, 
# You must add more rewrite rules like the below
        location /manager/ {
                rewrite ^/(.*)$ /demo/$1 last;
        }

Best Answer

I think you added something / extra in your config settings...

Look at this line:

proxy_pass http://IP_ADD_TOMCAT_SERVER:8080/;

you need to remove the trailing slash and it should work fine.

like this:

proxy_pass http://IP_ADD_TOMCAT_SERVER:8080;

try it out and see if things go fine!!

Update#1 I just noticed that you have another mistake "same typo" in your location /

remove the 2nd slash and it should work fine!!

like this : location /demo { instead of this location /demo/ {

Update #1: you can test your url using this

$ curl -I http://yoururl.com

and see what result gives you. this way you know if it is working or not.

Update #3:

your setting to work with any .jsp extension should have this code in your vhost:

location ~ \.jsp$ {
    proxy_pass              http://localhost:8080;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        Host $http_host;
  }

also to get /demo to work , you need to add rewrite code below server_name example.com

rewrite ^/(.*)$ /demo/$1;