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!


4 comments:

  1. Thanks for the tip! Did you investigate Nginx upstream? And add multiple contexts?

    ReplyDelete
  2. No, I didn't use upstreams so far...

    ReplyDelete
  3. Hi, I have the same problem, but I resolved it simply focusing on Jetty, not Nginx as follows;

    I put following file (for example camel.xml) under $JETTY_HOME/contexts (for example /opt/jetty/contexts)





    /
    /opt/jetty/webme/camel.war


    I force the only camel.war to run under "/" root path of this web server. Nginx config will remain the same. (for example) as follows.


    server {
    listen 80;
    server_name xxx.com;

    location / {
    root html;
    index index.html index.htm;
    proxy_pass 127.0.0.1:5984
    }


    Thanks for your POST, it help!

    ReplyDelete
    Replies
    1. https://raw.github.com/gist/3225705/a19d491c9f13ad4df77437f905c83d5290d8cbab/gistfile1.txt (you can see the camel.xml here on my gist)

      Delete