Are you a full-stack developer and having to fireup nodejs while not using the container for anything else? Are you a front-end developer that doesn't want to be burdened with setting up complex back-end systems? Are you a dev/ops guru that wants to streamline your deployments to decouple back-end web services from the front-end deployment and leverage cloudfront tactics? nginx can help you with that. nginx is lightweight, it is a webcontainer that allows for

  • robust SSL support
  • is lightwieght - if you come from the RoR development ecosystem then you probably already know that it has a lighter footprint than apache
  • simple config - especially compared to apache with all the caching/compression modules and nice rewrite rules you'd like, even LUA support for some dynamic behavior
  • fast - much faster implementation for serving those static assets than tomcat or nodejs could serve on its own

Ok, lets identify how we can help all 3 of these individuals...

Front-end Developer

If you are a front-end developer and by that I mean that you enjoy spending your time styling in LESS, implementing Backbone MVC apps and building slick animations then there is a chance you dont have the time or desire to fill out the back-end skillset. Maybe you want to work with a stable platform and not get bogged down with deployment or just like using a staging environment for a lighter footprint on your development machine then nginx can really help you.

In the diagram below the front-end developer is running nginx locally and using grunt to watch/build the static assets. meanwhile a nginx proxy is setup to make use of a staging back-end environment not running locally. This means that the Macbook Air is more than hefty enough to handle the processing and no longer are development cycles needed to repackage, deploy and setup the 3rd party integrations.

here's a sample nginx config to make that happen where the ec2 instance is running on host "ec2.makeandbuild.com"

upstream tomcatrest  {
    server ec2.makeandbuild.com:8080;
}

server {
    listen       80;
    server_name  localhost;
    location /rest {
        proxy_pass  http://tomcatrest/myapplication/rest;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cookie_path /myapplication/ /;
    }
    location / {
        root   /Users/azuercher/workspace/myapplication/app;
        index  index.html index.htm index.php;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

Full-stack Developer

If you are a full stack developer then the same benefits exist. You now can use nginx to run your local web container seperate from your static assets to independently test back and front-end development. The added value here is that you wont require a redeployment of your app server (ex: tomcat) to see changes. Editing the deployed assets and then moving them back into your deployment can be a pain for java devs, this is no longer an issue.

here's a sample nginx config to make that happen:

upstream tomcatrest  {
    server localhost:8080;
}

server {
    listen       80;
    server_name  localhost;
    location /rest {
        proxy_pass  http://tomcatrest/myapplication/rest;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cookie_path /myapplication/ /;
    }
    location / {
        root   /Users/azuercher/workspace/myapplication/app;
        index  index.html index.htm index.php;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

heck if you want to, you could even isolate the deployment so that you use the pushed assets to s3 instead of serving the front-end locally. here's the config for that:

upstream tomcatrest  {
    server localhost:8080;
}
upstream s3  {
    server myapp.s3-website-us-east-1.amazonaws.com:80;
}
server {
    listen       80;
    server_name  localhost;
    location /rest {
        proxy_pass  http://tomcatrest/myapplication/rest;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            $host;
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_cookie_path /myapplication/ /;
    }
    location / {
        resolver 8.8.8.8;
        proxy_pass  http://s3;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header        Host            'myapp.s3-website-us-east-1.amazonaws.com';
        proxy_method GET;
        proxy_pass_request_body off;
        proxy_set_header Content-Length '';
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

Dev/ops Guru

Now for some fun stuff. Using a cloudfront deployment is really cool - you can break the deployments to be isolated from the front-end and the back-end. It allows you to move those assets closer to the end user, and is essential when you've gone global. In this case we've identified that nginx serves a potentially different asset for a ie7 based User-Agent - you can use LUA for that.

happy coding