Wednesday, February 9, 2011

Nginx + Jetty 7 + Multiple Contexts



Running multiple contexts withing a Jetty Server and having a nginx as frontend seems to be a common usage but after some hours of googling and not finding any answer to my problem I startetd trying myself.

Here is the situation

You are runnning a vServer with a nginx as frontend for load balancing etc. Next is a Jetty 7 Server running your web applications in different contexts.

The Problem

Using nginx to reverse proxy all the traffic in the normal way does not work, i.e. Form submitting and page linking does not work anymore.

Old nginx.conf NOT working:

server {
listen 80;
server_name mysub.example.com;
access_log /opt/log/
mysub.example.com.access.log main;
error_log /opt/log/
mysub.example.com.error.log;
location / {
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;
proxy_pass http://localhost:8080/mysub;
}
}

Here we will soon see that the browser address gets appended a "mysub" after the domain name leading to incorrect paths.

The Solution

Tell Jetty to make use of virtual hosts and send the whole traffic coming from nginx directly to our root context jetty instance.

New working nginx.conf:

server {
listen 80;
server_name mysub.example.com;
root /opt/server/jetty-distribution-7.1.6.v20100715/webapps/mysub.war;
access_log /opt/log/
mysub.example.com.access.log main;
error_log /opt/log/
mysub.example.com.error.log;
location / {
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;
proxy_pass http://localhost:8080/;
}
}

Additionally we have to create some contexts for every virtual host. This will look something like this:

NOTE: This works only for Jetty 7.X

vhostsmysub.xml

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war"><SystemProperty name="jetty.home"/>/webapps/mysub.war</Set>
<Set name="contextPath">/</Set>
<Set name="virtualHosts">
<Array type="java.lang.String">
<Item>mysub.example.com</Item>
</Array>
</Set>
</Configure>




Thats's it!