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!


5 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
  4. They then spent the rest of|the remainder of} the jam making a system that may routinely generate the rest of|the remainder of} the skinning wanted to make this basic virtual slot machinejust unique sufficient to be published as its own smartphone app. Robert Taylor of Arizona received the jackpot Jan. 8 at Treasure Island Hotel & Casino in Las Vegas. However, because of the error, a malfunction occurred "that prevented Mr. Taylor and casino personnel from realizing that a progressive jackpot had been received," the gaming board mentioned in a press release. A malfunctioning slot machine on the 온라인 카지노 Treasure Island hotel and casino in Las Vegas prevented a man from studying he received a jackpot of greater than $200,000. Staff training shall be key when you get slot machines and your Accel Relationship Manager is instrumental in providing you this information.

    ReplyDelete