# Nginx as reverse proxy for Jetty

**URL:** <https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339>\
**Category:** NGINX\
**Created:** [November 18, 2010, 11:48pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339 "2010-11-18T23:48:14Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![okkezSS](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/85f322/32.png) [@okkezSS](https://www.ruby-forum.com/u/okkezSS)\
**Post date:** [November 18, 2010, 11:48pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/1 "2010-11-18T23:48:14Z")

</div>

Hi -

I need some help configuring nginx as a proxy in front of Jetty (on  
Debian).

Jetty is serving my Java web app correctly, because if I test it with  
this lengthier alternate notation (which I also used before setting up  
the nginx proxy), the Java web app login page appears and I can log in:

[http://myhost.com:8080/testapp001.com](http://myhost.com:8080/testapp001.com)

But when I do the following:

[http://testapp001.com](http://testapp001.com)

I get the error message:

403 Forbidden  
nginx/0.8.53

Here’s my nginx.conf and testapp001.com.xml files

# This file is /etc/nginx/sites-available/testapp001.com

# Source: [Java servers like Jetty, GlassFish and Tomcat | NGINX](http://wiki.nginx.org/JavaServers)

server {  
listen 80;  
server\_name .testapp001.com;  
access\_log /var/log/www/testapp001.com/access.log;  
error\_log /var/log/www/testapp001.com/error.log;

root /opt/jetty/webapps/testapp001.com;

location / {  
index index.jsp;  
}

location ~ .do$ {  
proxy\_pass [http://localhost:8080](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;  
}  
location ~ .jsp$ {  
proxy\_pass [http://localhost:8080](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;  
}  
location ^~/servlets/\* {  
proxy\_pass [http://localhost:8080](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;  
}  
}

The Java web app’s WAR file has been decompressed to create this  
directory:

/opt/jetty/webapps/testapp001.com

Here is file /opt/jetty/etc/testapp001.com.xml:

# Source: [Java servers like Jetty, GlassFish and Tomcat | NGINX](http://wiki.nginx.org/JavaServers)
\<?xml version="1.0"?\> org.mortbay.jetty.webapp.WebInfConfiguration org.mortbay.jetty.plus.webapp.EnvConfiguration org.mortbay.jetty.plus.webapp.Configuration org.mortbay.jetty.webapp.JettyWebXmlConfiguration org.mortbay.jetty.webapp.TagLibConfiguration / /webapps/testapp001.com testapp001.com 

This file is /opt/nginx/conf/nginx.conf - the correct symlink was also  
created previously by doing:

sudo ln -s /etc/nginx/sites-available/testapp001.com  
/etc/nginx/sites-enabled

worker\_processes 1;

events {  
worker\_connections 1024;  
}

http {  
include mime.types;  
default\_type application/octet-stream;  
sendfile on;  
keepalive\_timeout 65;  
include /etc/nginx/sites-enabled/\*;  
}

Here are last the 2 lines of the nginx log files:

#This is file /var/log/www/testapp001.com/access.log

999.999.999.999 - - [18/Nov/2010:19:17:23 -0200] “GET / HTTP/1.1” 403  
571 “-” “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)  
AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7”

999.999.999.999 - - [18/Nov/2010:19:17:32 -0200] “GET /favicon.ico  
HTTP/1.1” 404 571 “-” “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US)  
AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7”

#This is file /var/log/www/testapp001.com/error.log

2010/11/18 19:17:23 [error] 13319#0: \*3 directory index of  
“/opt/jetty/webapps/testapp001.com/” is forbidden, client:  
999.999.999.999, server: [testapp001.com](http://testapp001.com), request: “GET / HTTP/1.1”,  
host: “[testapp001.com](http://testapp001.com)”

2010/11/18 19:17:32 [error] 13319#0: \*3 open()  
“/opt/jetty/webapps/testapp001.com/favicon.ico” failed (2: No such file  
or directory), client: 999.999.999.999, server: [testapp001.com](http://testapp001.com), request:  
“GET /favicon.ico HTTP/1.1”, host: “[testapp001.com](http://testapp001.com)”

(I have substituted “999.999.999.999” above instead of my client  
machine’s IP address. 🙂

I have also tested setting the owner:group of directory

/opt/jetty/www/webapps/testapp001.com

three different ways:

cd /opt/jetty/www/webapps  
sudo chown -R jetty:jetty [testapp001.com](http://testapp001.com)  
sudo chown -R root:root [testapp001.com](http://testapp001.com)  
sudo chown -R www-data:root [testapp001.com](http://testapp001.com)

But navigating to ‘[http://testapp001.com](http://testapp001.com)’ still gives the error message  
“403 - Forbidden”

Navigating to ‘[http://myhost.com:8080/testapp001.com](http://myhost.com:8080/testapp001.com)’ correctly displays  
the login page of the Java web app and lets me log in successfully - so  
Jetty and the web app are working - I just can’t get the nginx reverse  
proxy configured properly.

Thanks for any help!

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 23, 2010, 11:18am UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/2 "2010-11-23T11:18:59Z")

</div>

Hi,

I have to report I am experiencing very similar behavior using nginx as  
reverse proxy to Apache.

What I consider weird is output from logs.

Result from apache is:

\*1 http proxy status 200 “200 OK”  
\*1 http proxy header: “Date: Tue, 23 Nov 2010 10:11:28 GMT”  
\*1 http proxy header: “Server: Apache”  
\*1 http proxy header: “Cache-Control: max-age=0, no-cache,  
must-revalidate, transform”  
\*1 http proxy header: “Expires: Tue, 23 Nov 2010 10:11:28 GMT”  
\*1 http proxy header: “Pragma: no-cache”  
\*1 http proxy header: “Connection: close”  
\*1 http proxy header: “Content-Type: text/plain; charset=UTF-8”  
\*1 http proxy header: “X-Pad: avoid browser bug”  
\*1 http proxy header done

But what nginx sends to client is this:

HTTP/1.1 403 Forbidden  
Date: Tue, 23 Nov 2010 10:11:28 GMT  
Content-Type: text/plain; charset=UTF-8  
Transfer-Encoding: chunked  
Connection: keep-alive  
Server: Apache  
Cache-Control: max-age=0, no-cache, must-revalidate, no-transform  
Expires: Tue, 23 Nov 2010 10:11:28 GMT  
Pragma: no-cache

Why the hell he rewrites result code 200 to 403?  
Does anybody experience this kind of behaviour, do you have tips?

Thanks, Martin

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 23, 2010, 12:49pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/3 "2010-11-23T12:49:48Z")

</div>

Hello!

On Tue, Nov 23, 2010 at 11:18:59AM +0100, Martin wrote:

> \*1 http proxy header: “Date: Tue, 23 Nov 2010 10:11:28 GMT”  
> But what nginx sends to client is this:
> 
> Why the hell he rewrites result code 200 to 403?  
> Does anybody experience this kind of behaviour, do you have tips?

nginx never sends responses with “Server: Apache”, so it looks  
like your client isn’t talking to nginx.

Maxim D.

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 23, 2010, 2:05pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/4 "2010-11-23T14:05:45Z")

</div>

No, I have set:  
proxy\_pass\_header Server;

so I could know which server handled request.

I realized, that in version 0.7.67 this problem is real, and with the  
latest stable build 0.8.53 this problem has gone.

Anyway, I also find a workaround for this bug. It is necessary to set  
index directive to some existing file, even if the request is  
proxy-passed. Then the requests to root of the domain are handled  
correctly.

Martin

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 23, 2010, 4:38pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/5 "2010-11-23T16:38:36Z")

</div>

Hello!

On Tue, Nov 23, 2010 at 02:05:45PM +0100, Martin wrote:

> I realized, that in version 0.7.67 this problem is real, and with the  
> latest stable build 0.8.53 this problem has gone.
> 
> Anyway, I also find a workaround for this bug. It is necessary to set  
> index directive to some existing file, even if the request is  
> proxy-passed. Then the requests to root of the domain are handled  
> correctly.

Most likely this is something screwed up in your configuration  
which results in the problem. Plain proxy\_pass like this

```
location / {
    proxy_pass http://backend;
}

```

won’t even know you’ve defined indexes somewhere and won’t care at  
all if there are any files. Though there is more than one way to  
screw it up, e.g. by using if[1] directive. There is a reason why  
[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/Debugging) suggests showing config when  
asking for help.

[1] [GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com · GitHub](http://wiki.nginx.org/IfIsEvil)

Maxim D.

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 23, 2010, 2:09pm UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/6 "2010-11-23T14:09:14Z")

</div>

One small note:

this issue appears only in some particular configurations, I don’t know  
exactly which. We use nginx to proxy-pass also our other servers, and  
there it works okay…

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 24, 2010, 9:05am UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/7 "2010-11-24T09:05:35Z")

</div>

Okay,

here it is.

Martin

---

<div class="post-metadata">

**Author:** ![stefans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/9d8465/32.png) [@stefans](https://www.ruby-forum.com/u/stefans)\
**Post date:** [November 24, 2010, 11:38am UTC](https://www.ruby-forum.com/t/nginx-as-reverse-proxy-for-jetty/199339/8 "2010-11-24T11:38:52Z")

</div>

Hello!

On Wed, Nov 24, 2010 at 09:05:35AM +0100, Martin wrote:

> Okay,
> 
> here it is.
> 
> Martin
> 
> Attachments:  
> [http://www.ruby-forum.com/attachment/5445/bigserver.conf](http://www.ruby-forum.com/attachment/5445/bigserver.conf)

This location:

```
    # bigserver.cz/username -> 

```

profile.bigserver.cz/username/profile/  
location / {  
rewrite ^/([^/]+) [http://profile.bigserver.cz/$1/profile/](http://profile.bigserver.cz/$1/profile/)  
redirect;  
}

matches requests to “/” exactly and stopped matching. But it  
doesn’t redirect “/” itself. Without index set this  
obviously results in 403.

One simple solution is to define exact location = /, i.e.

```
location = / {
    ...
}

```

with appropriate proxy\_pass’es.

In 0.8.42 behaviour has been changed to be a bit more  
intuitive:

```
*) Change: now nginx tests locations given by regular expressions, 

```

if  
request was matched exactly by a location given by a prefix  
string.  
The previous behavior has been introduced in 0.7.1.

and your location / no longer prevents your regexp location with  
proxy\_pass from working. That’s why you don’t see “problem” in  
0.8.53.

Maxim D.
