Configuring an ASP.NET Web Server on Linux

Overview

This tutorial describes how to setup a Linux computer as a web server for ASP.NET web applications.  Following the steps in this tutorial, you will be able to host web services written in C# ASP.NET on a Linux machine.

This tutorial is intended for ‘novice experts’ users of Linux. You should be familiar with the command line and you should be able to use samba or ftp to deploy your ASP.NET project to the file system on the Linux machine. You should also have the Mono runtime framework for Linux installed, as well as the XSP server, which performs the same task as IIS on a Microsoft server.  Setting up Mono and XSP is described in our tutorial here.

In this tutorial you will learn:

  • How to setup a CentOS Linux server with the LEMP stack (Linux with Nginx, MySql, and PHP), and how to configure FastCGI so PHP can interact with the Nginx web server.
  • How to configure FastCGI so the XSP server can interact with the Mono runtime framework and the Nginx web server.
  • How to deploy an ASP.NET web project from Visual Studio to the Linux server machine.

Install LEMP Stack

Serving an ASP.NET web site from a Linux machine requires the XSP server. You must configure this server to work with the Linux web server. It is possible to do this with Apache, but it requires an additional component and the configuration is more complex.

The Nginx web server is used for this project because it is relatively simple to configure. If your web service will need a database, you should also install MySQL. You can optionally install PHP in order to use PhPMyAdmin to administer your database.

The following instructions were adapted from this good tutorial on DigitalOcean.

Install Nginx Web Server

1.  Install Nginx from the repository

$ sudo yum install nginx

2.  Start the nginx web server

$ sudo service nginx start

3.  Test to see if it works by opening up a web browser to the computer’s address, and you should see a page that says “Welcome to nginx…”.

You will find the default root location for the Nginx server on port 80 at /usr/share/nginx/html.

Install MySQL Database

  1. Add the required repositories
$ sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

2.  Install MySQL.

Note: MySQL is already installed on the stock CentOS distribution.

$ sudo yum install mysql mysql-server

3.  Restart SQL so you can launch the configuration utility

$ sudo /etc/init.d/mysqld restart
$ sudo /usr/bin/mysql_secure_installation

4.  You will be prompted for a root password, leave it blank for now and hit enter.

5.  At the next prompt, enter your root user password for SQL.

6.  A series of questions will complete the configuration. It is OK to answer yes to everything, although you should read it carefully to catch the question about external access if you need other machines to connect to this SQL server.

Install PHP

Even if you will not use PHP for your web service, it is useful to install it here. Getting PHP to work is an easy way to test FastCGI.  Because FastCGI is also used to serve your ASP.NET applications, it is useful to determine that you can configure it correctly for PHP.

  1. Enable the repository and install php
$ sudo yum --enablerepo=remi install php-fpm php-mysql

2.  Modify the configuration for better security profile. This change will force the php interpreter to use only the exact file paths.

$ sudo nano /etc/php.ini

Change the “cgi.fix_pathinfo=1” to be “cgi.fix_pathinfo=0”.

3.  Configure PHP to use nginx web server instead of the default Apache server.

$ sudo nano /etc/php-fpm.d/www.conf

Change the user and group from apache to nginx.

; Unix user/group of processes
; …
; find the user = line, and change apache to nginx
user = nginx
; find the group = line, and change apache to nginx
group = nginx

4.  Restart the php service

$ sudo service php-fpm restart

5.  Configure nginx to use PHP. The configuration file for each virtual host is in the /etc/nginx/conf.d directory. One virtual host was created when you set up Nginx, defined in the default.conf file.

$ sudo nano /etc/nginx/conf.d/default.conf

6.  Add “index.php” to the list of possible landing pages in the root folder.  Then enable the location for php, and set the FastCGI configuration so PHP can communicate with the web server.

Your file should look like this:

#
# The default server
#

server {

  listen       80;
  server_name yourServerName.com;

  location / {
    root   /usr/share/nginx/html;
    #added index.php to the index line
    index index.php  index.html index.htm;
  }

  error_page  404              /404.html;
  location = /404.html {
    root   /usr/share/nginx/html;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }

  # uncommented and changed the location for php
  #  to pass the PHP scripts to FastCGI server
  #  server is listening on port 9000 = 127.0.0.1:9000
  #
  location ~ \.php$ {
    root           /usr/share/nginx/html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME   $document_root$fastcgi_script_name;
    include        fastcgi_params;
  }
}

Save the file and exit back to the command line.

7.  Restart the Nginx web server

$ sudo service nginx restart

8.  To test the installation, create a php file in the web host root directory:

$ sudo nano /usr/share/nginx/html/info.php

Paste this content into the file:

<!--?php phpinfo(); ?-->;

9.  Save the file, then point your web browser to the host address/info.php.  If you see a web page with a table of php settings, then everything worked.

You have now setup the LEMP stack, and Nginx, MySQL, and PHP are ready to go.  The final step is to configure all three of these services to start on boot.

$ sudo chkconfig --levels 235 mysqld on
$ sudo chkconfig --levels 235 nginx on
$ sudo chkconfig --levels 235 php-fpm on

Setup FastCGI for XSP Server

For this project, we keept the default web host at port 80, and we setup a new root for our ASP.NET service on a different port.

  1. Create a new configuration file.
$ cd /etc/nginx/conf.d
$ nano aspNetService.conf

2.  Paste in these contents. Change the server name, listening port, and root directory that you will use for your web host.

#
# The ASP.NET website listening on port 31080
#

server {
  listen 31080;
  server_name  littlebytesofpi.net;
  root /usr/share/nginx/aspNetWebsite;

  #redirecting errors back to 404 page at default web host
  error_page  404              /404.html;
  location = /404.html {
    root   /usr/share/nginx/html;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }

  # pass  XSP  to FastCGI server listening on 127.0.0.1:9001
  # note, port 9000 is used for PHP on the default web site
  # use a different port for each ASP.NET site you create
  #

  location / {
    root           /usr/share/nginx/aspNetWebsite;
    fastcgi_pass   127.0.0.1:9001;
    fastcgi_index  /;
    fastcgi_param PATH_INFO "";
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
  }
}

3.  Start the XSP server on the required port for your ASP.NET web application root folder.  In a terminal window, enter:

$ fastcgi-mono-server4 /applications=/:/usr/share/nginx/aspNetWebsite /socket=tcp:127.0.0.1:9001

Where:  /usr/share/nginx/aspNetWebsite is the root folder for your website and 9001 is the port you specified for the FastCGI server at this location.

Note:  The process that launched this command must remain running as long as the server is alive. Therefore, you have three choices:

  1. Open a new terminal window, type the command in there, and leave the terminal window open indefinitely
  2. Execute the command above with a ‘&’ at the end to fork the process.
  3. Configure a script to run at startup to launch the XSP server.

For our server, we started with option 1. This is advantageous for two reasons.  First, the open terminal window will trace out exceptions thrown by the web application, which is useful for debugging.  Second, you can tell when the XSP server has crashed. You do not get this feedback when you start XSP in a forked process.

Once things were working, we created a startup script.  This procedure is described in the appendix.

You are now ready to deploy your ASP.NET web application.

Deploy your ASP.NET Web Application

An ASP.NET web application works like any other website.  That is, the files in the web root folder will be served up when a browser makes a request to connect to the location.  The easiset way to deploy your ASP.NET web project is to:

  1. Develop and debug your solution in Visual Studio on your PC.
  2. When it is ready, publish a release build of your application to a location on disk.
  3. Copy the entire contents of the publish directory into the web root directory on the Linux server.

Of course, software programming is rarely easy.  For some types of ASP.NET web applications, you have to make small adjustments to the default Visual Studio templates.  In other cases, your web application works on Windows but crashes on your Linux server, so you will need to debug it in the Linux environment.

You can use the MonoDevelop IDE on the Linux Machine to debug your solution on the target server. Some of the tips and tricks required to get a Visual Studio solution to work on Linux are described in the Beginner’s Guide to ASP.NET on Mono.

Appendix

Once you have your system running smoothly, chances are you will want to create a script to automatically start the XSP server when the system boots.

1. As a super user, create a file in the /etc/init.d directory called xsp

$ sudo su
$ nano /etc/init.d/xsp

2. Paste this text into the file.  This script will check to see if the fastcgi server is running already, and if not it will start it for your web application in “/usr/share/nginx/aspNet” on port 9001

#!/bin/sh
# chkconfig: 2345 95 20
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/mono
NAME=mono-fastcgi
DESC=mono-fastcgi
MONOSERVER_PID=$(ps auxf | grep fastcgi-mono-server4.exe | grep -v grep | awk '{print $2}')
WEBAPPS="/usr/share/nginx/aspNet"
case "$1" in
start)
if [ -z "${MONOSERVER_PID}" ]; then
echo "starting mono server"
fastcgi-mono-server4 /applications=/:/usr/share/nginx/aspNet /socket=tcp:127.0.0.1:9001 &
echo "mono server started"
else
echo ${WEBAPPS}
echo "mono server is running"
fi
;;
stop)
if [ -n "${MONOSERVER_PID}" ]; then
kill ${MONOSERVER_PID}
echo "mono server stopped"
else
echo "mono server is not running"
fi
;;
esac
exit 0

3. Make the script runnable

$ chmod +x /etc/init.d/xsp

4. Add the script to chkconfig

chkconfig --add xsp

5. Tell the script to run at startup

chkconfig --level 345 xsp on