Hosting an ASP.NET vNext application from NGINX

Note This entry has been updated and republished to account for the breaking changes which have taken place in the vNext (now DNVM) project and major updates to the post content regarding nginx configuration

ASP.NET vNext includes its own web server, Kestrel, which can be invoked by running dnx kestrel in the root directory of a vNext project as demonstrated in my previous post. This will run the site on port 5004 by default.

At this point, Kestrel is not in a production ready state so a simple solution on non-windows environments is to use nginx as a front end server and reverse proxy to Kestrel.

A sample configuration for seting up this proxy is as follows

server {
    listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6

    server_name YOUR_DOMAIN_HERE;
    location /
    {
        proxy_pass http://127.0.0.1:5004; ## 5004 is the default port
    }
}

This will simply pass all content through and serve it on port 80 allowing access to an ASP.NET vNext application on a production ready server!

Some improvements can be made to the nginx configuration which will dramatically improve performance.

Enabling GZip compression

To begin we need to edit the nginx config file using the One True Editor

(nano|emacs|vi|magneticNeedleWithSteadyHand) /etc/nginx/nginx.conf

Navigate down and uncomment the following lines

##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/javascript  text/xml application/xml application/xml+rss text/javascript;

Restart nginx to load the new configuration to see an instant performance gain

sudo service nginx restart

Enable Browser Caching

To further improve performance we can configure nginx to set caching information in certain headers. This will tell the browser not to download a file again if it has not changed and the age of the cache has not expired.

Open the site config using the editor of your choice

sudo nano /etc/nginx/sites-available/yourdomain.com

Set up the cache by adding the following lines

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:8m max_size=1000m inactive=30d;
proxy_temp_path /var/cache/nginx/tmp;

Note: if the path /var/cache/nginx/tmp does not exist you can create it using the command

sudo mkdir -p /var/cache/nginx/tmp

Set up the following rules in your domain config

server {
    location / {
        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_redirect off;
        location ~*^.+(html|woff|ttf|hubs|swf|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)(\?ver=[0-9.]+)?$ {
        proxy_pass http://127.0.0.1:5004;
        proxy_cache mycache;
        proxy_cache_valid 2d;
        expires max;
    }
    proxy_pass http://127.0.0.1:5004;

    }
}

Once again, restart nginx to load the new configuration

sudo service nginx restart