Hosting ASP.NET 5 web application on GNU / Linux
The brand new version ASP.NET 5 (a.k.a ASP.NET vNext) can be developed and hosted on all three major platform - Windows, Linux and MacOS.
Getting started with ASP.NET 5 (TODO: Link to be updated with new Post for .NET tools) is not so hard after all and is definitely fun to play early. The biggest break through that comes to .NET and ASP.NET world is the capability to write and host anywhere.
Yes you can now develop and host a ASP.NET Web application - MVC or WebAPI even SignalR on any platform - Windows, Linux and MacOS. This has always been the de-facto standard for windows since long using Visual Studio (prior VS2015) but it can be fun on Linux and MacOS also using your favourite editors or Visual Studio Code.
Following step needs to be performed on a brand new spinning Linux box to develop or host a ASP.NET 5 (vNext) web application:
Note: For the sake of writing I am using a Ubuntu 14.04 Trusty x64 - DigitalOcean droplet (highly recommended for Linux based hosting).
SSH into your Linux box and lets get started...
Step (optional, but recommended): Let us first update / upgrade the Linux
sudo apt-get update
sudo apt-get upgrade
Step: Install some pre-requisite packages that will be required for the following setup to work
sudo apt-get install make -y
sudo apt-get install zip unzip curl git libtool autoconf automake build-essential zsh gyp -y
Step: ASP.NET 5 runs on top of Mono Framework (.NET equivalent for non-windows platform) using .NET tools (DNVM, DNU and DNX.
First, let us install Mono Framework
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
Update / Upgrade apt-get
package manager references:
sudo apt-get update
Install Mono Framework:
sudo apt-get install mono-complete -y
Once the installation completes you can check the Mono version that was installed:
mono --version
output should be similar to following (version number might vary)
Mono JIT compiler version 4.0.3 (Stable 4.0.3.20/d6946b4 Tue Aug 4 09:43:57 UTC 2015)
Step: Import few certificates to CERT manager for URL(s) that the .NET tools (DNVM / DNU / DNX) and your application may connect and need SSL trust to work properly (may not work in all cases):
sudo yes | certmgr -ssl -m -v https://go.microsoft.com
sudo yes | certmgr -ssl -m -v https://nugetgallery.blob.core.windows.net
sudo yes | certmgr -ssl -m -v https://myget.org
sudo yes | certmgr -ssl -m -v https://nuget.org
sudo yes | certmgr -ssl -m -v https://www.myget.org/F/aspnetvnext/
sudo mozroots --import --sync --quiet
IMP note: There is no IIS on Linux (you awll know that aay) so ASP.NET 5 uses webserver package Kestrel to run the application and serve request.
This is a development ready / internal self host web server that initiates from the application and host the ASP.NET 5 web application. If you follow this article step-by-step completely then Kestrel will be proxy hosted with Nignx to serve request publically (general practice followed by other frameworks on Linux like node)
Kestrel
package uses Libuv cross-platform asynchronous I/O library to self host ASP.NET 5 web application. This package may or may not be present or setup on your machine
Step: (Optional if Libuv is already present) Setup Libuv package on Linux [Reference ASP.NET github home repo docs]:
curl -sSL https://github.com/libuv/libuv/archive/v1.7.0.tar.gz | sudo tar zxfv - -C /usr/local/src
cd /usr/local/src/libuv-1.7.0
sudo sh autogen.sh
sudo ./configure
sudo make
sudo make install
sudo rm -rf /usr/local/src/libuv-1.7.0 && cd ~/
sudo ldconfig
At the time of this writing the latest version of Libuv was 1.7.0. Above command should be updated for the version of Libuv you are installing.
You can find your currently installed Libuv version installed in /usr/lib/libuv.so.x.x.x
location.
Step: Install and setup .NET tools (DNVM, DNU, DNX), you can follow the instructions on ASP.NET Home github repo or continue here. (Remember K tools are older versions of .NET tools before the big rename)
sudo apt-get install unzip
curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh
Get latest version of .NET execution environment (DNX) for MONO / Linux:
dnvm upgrade
At the time of writing dnvm upgrade
installed dnx-mono.1.0.0-beta6
. On dnvm list
shows following output:
Active Version Runtime Arch OperatingSystem Alias
------ ------- ------- -------- ----- -----
* 1.0.0-beta6 mono linux/darwin default
Step: (Optional if do not want to publically host ASP.NET 5 web application) - Install Nignx and configure to proxy host - ASP.NET 5 web application which runs using Kestrel, .NET Tools (DNVM, DNX, DNU), Mono Framework.
sudo apt-get update
sudo apt-get install nginx -y
This should install Nignx web server. To start / stop Nginx web server following command can be used:
sudo service nginx start
sudo service nginx stop
This command helps to check if currently Nignx is running or not:
ifconfig eth0 | grep inet | awk '{ print $2}'
Configure Nginx to start on machine start or reboot:
update-rc.d nginx defaults
Create a Nginx specific configuration for your ASP.NET 5 application:
sudo nano /etc/nginx/conf.d/<domain-name>.conf
Replace <domain-name>
with your public domain name on which you want your ASP.NET 5 web application to be hosted.
In the NANO editor paste / write following code:
server {
listen 80;
server_name <domain-name> www.<domain.name>;
client_max_body_size 10M;
location / {
proxy_pass http://localhost:5004/;
proxy_redirect off;
proxy_set_header HOST $host;
proxy_buffering off;
}
}
Note: Replace <domain-name>
with your actual domain name
Create cache directory for Nignx webserver:
sudo mkdir /var/cache/nginx
sudo chown www-data:www-data /var/cache/nginx
Create a web root directory for your ASP.NET 5 web application to reside:
sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo mkdir /var/www/<domain-name>
sudo chown www-data:www-data /var/www/<domain-name>
Note: Replace <domain-name>
with your actual domain name. This is the folder where your application will reside.
Should also remove default
file if found in any of the following directories: /etc/nginx/conf.d/
, /etc/nginx/sites-available/
or /etc/nginx/sites-enabled/
using sudo rm -rf <directory or filename>
Also do not forget to restart Nginx after the changes made using sudo service nginx restart
to take effect.
Step: Create the simplest form of ASP.NET web application to get started - will display brand new ASP.NET 5 vNext welcome page
cd /var/www/<domain-name>/
sudo nano project.json
Paste the following code in the newly created project.json file:
{
"dependencies": {
"Kestrel": "1.0.0-beta6",
"Microsoft.AspNet.Diagnostics": "1.0.0-beta6",
"Microsoft.AspNet.Hosting": "1.0.0-beta6",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta6",
"Microsoft.AspNet.StaticFiles": "1.0.0-beta6"
},
"frameworks": {
"dnx451": { },
"dnxcore50": { },
},
"commands": {
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://localhost:5004"
}
}
This should do the minimal required for the web application to run. Currently at the time of writing ASP.NET 5 is in BETA-6 (most stable beta), should update the package version accordingly if required.
Next create Startup.cs file:
sudo nano Startup.cs
Paste following code in newly created Startup.cs file and save the file with Ctrl + x
=> Yes
=> Enter
:
using Microsoft.AspNet.Builder;
namespace HostKWebOnLinux
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseStaticFiles();
app.UseWelcomePage();
}
}
}
Run dnu restore
to download and restore all packages mentioned in the project.json
file.
Last and the final step to BOOM start it all dnx . kestrel
- hit your <domain-name>
and wallah, you see the default ASP.NET 5 vNext Welcome page.
Updates [18th March, 2015] - Article updated to use Mono 3.12.1, ASP.NET beta-3 and libuv-v1.4.2 (thanks to JUNSUI - for reaching out - refer comments).
Updates [19th March, 2015] - For Linux VM user on Azure, who wish to make their ASP.NET application publically accessible, need to enable or add entry of specific endpoints in Azure management portal.
Following screenshot explains this part while creating VM:
Things to understand here:
-
The cloud service DNS name (configuration [1]): example
junsui-test.cloudapp.net
is a default domain name assigned to this VM by Azure DNS service and can be used as your so called domain name to access anything hosting on this VM -
To make anything accessible from public (on Azure), you need to enable ENDPOINTS for it.
-
If you followed the NGINX path from the above walkthrough then you should enable configuration [2] marked red in above screenshot. Considering that your
/etc/nginx/conf.d/<domain-name>.conf
haslisten:80
. In this case our project.jsonlocalhost:5004
should remain the same. -
If you do not want to use the NGINX server as public webserver or proxy host your application, then you should try using configuration [3] in above screenshot: use PUBLIC PORT as whatever you wish to access with and the
PRIVATE PORT
as5004
as mentioned in your application's project.json file. In this case you need to use public IP Address provided by Azure instead oflocalhost
at following line in project.json
"kestrel": "Microsoft.AspNet.Hosting --server Kestrel --server.urls http://<azure-public-ipaddress>:5004"
You can find the Public (Virtual) IP Address of your VM in that VM's dashboard page in Microsoft Azure Management Portal:
Umm:
-
Why do I need Nignx and Kestrel, that is two webserver, right? Can't I just host the application using
dnx . kestrel
and point to public URL?Yes you can, but Kestrel is ASP.NET 5 specific in-place self hosting web server. This may or may not contain ways to configure many of the generic web server configuration. Even if it does then you need to change / set them in your application or somewhere in your
project.json
.Nginx play the role of middleman and takes care of the generic webserver request serving stuffs. Also enables to host more than one web application (any other web application - node.js, aspnet 5, php or wordpress) along side of your ASP.NET 5 web application.
Kestrel takes care of the ASP.NET specific and application specific stuffs in that case. This is much similar to hosting CoreCLR based application (web command) in IIS / IIS Express using IIS Helios hook.
-
Where is the
frameworks
node inproject.json
file?As noted on Github ASP.NET Home repository:
NOTE: There is no Core CLR currently available on OSX/Linux. There is only a single platform (mono45) and a single architecture (x86).
I removed the
frameworks
node and it still works, sue me.Update [11th May, 2015] - Sorry don't sue me, framework node was optional on Linux / MONO till
beta-3
but now its mandatory or else you would encounter error similar to following when youdnx . kestrel
:System.InvalidOperationException: Failed to resolve the following dependencies for target framework 'DNX,Version=v4.5.1':
-
There is so much commands to just get up and running, arrggh
Yes there is. Most of them are pretty straight forward. There is also a shell script created by Punit Ganshani (Unfortunately not updated since 6th Dec, 2014 - try or modify at your own risk) to do most of the stuffs automatically for your. Use it with few modification / update if you feeling lazy or big fan of Automation. Also should give a look at Chef, Puppet and Docker if you feel automation is your way. There is ASP.NET 5 Preview Docker Image and way to configure it which you can use to run ASP.NET 5 vNext application in Microsoft Azure Linux Docker Image.
-
Anything else Mr. Umm?
Yes, use
DNX_TRACE
environment variable if anything related to .NET tools (DNVM, DNU, DNX) / Kestrel has gone bananas. Export environment variable on Linux usingexport DNX_TRACE=1
. Also look fordnu pack
/dnu help pack
to create deployment packages for your ASP.NET 5 web application and then you can x-copy / FTP your package where you wish to host your application.
Updates [11th May, 2015] - Article updated to use Mono 4.0.1, ASP.NET 5 beta-4 and libuv-v1.5.0.
Updates [17th August, 2015] - Article updated to use Mono 4.0.3, ASP.NET 5 beta-6 and libuv-v1.7.0.
Request to come up with suggestion, improvements, questions, critics or throw eggs, will appreciate it except for eggs (comments below).
Happy coding !!