Run Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono – LAMA and LAMP

An ASP.Net MVC 4.0 Web Application on Ubuntu Linux? What is the purpose ?

Lamas
Lamas are cuter than Lamps!

Obviously there are many different answers for this question, so I will give you mine. First, I am far more familiar with C# than I am with PHP, even if i wrote a few applications with it, more specifically with the MVC framework “Cake”. MVC pattern is for me the most logical way to deal with a Web application, make future extensions and maintenance easier. As it happens, ASP.Net implementation of this pattern is very clean and logical.  BUT, normally .Net and C# needs Windows as OS. Problem is, most web applications I am writing are going to be hosted on external virtual servers, not in house. Hosting providers are able to offer great Linux packages, where you have full control for a very good price, but for Windows based solutions, its generally not that flexible, you can’t always install what you need, and the deals are not as good. Moreover, in my personal case, it seems logical to avoid to multiply servers. My blog use WordPress, hosted on a Ubuntu server, and I would like (quite a few of my clients, too) to be able to host on the same server some ASP.NET MVC 4.0 applications. This is doable, thank you to Mono, which is improving at a fast pace and is now compatible with MVC 4.0 and Entity Framework 6.0 (RC1 for now..)

In this post, we are going to see, step by step, how to run Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono. The same steps would apply to any other Linux distribution, and to PostgreSql as well.

To start, I am going to assume you have access to a Ubuntu Server 12.04 LTS or newer, available here: http://www.ubuntu.com/download/server , and a PuTTY terminal to manage it. If you don’t have a remote host, you can easily create a local virtual machine with Windows 8 and Hyper-V. In fact, even if you have a real remote server, it might be a good idea to create a local virtual machine to experiment with.

Let’s see how to build our LAMA stack, in replacement to, or association with, LAMP. Lamp being an acroym for Linux, Apache, MySql, PHP and Lama being an acronym for Linux, Apache, MySQL, ASP.NET.

Preparation

Ubuntu distribs already contains Mono, but the lag behind current Mono evolution is significant, as installed version is 2.10.8, MVC 3 compatible, while the current version, while I am writing this, is 3.2.3 and is .Net 4.5 and MVC 4.0 compatible. As we want to run MVC 4.0 applications, we have no other choice but to download, compile and run mono directly from source code. This takes a little bit of time and precision, but there is nothing difficult if you follow step by step.

After connecting via SSH/PuTTY, the very first thing to do is to check that we are up to date on everything already installed:

(If you are using PuTTY, select the text of the commands here, copy it into the clipboard with CTRL-C, put the mouse cursor inside PuTTY and right-click, the text will be inserted where PuTTY cursor is.)

Then we install the minimum set of tools needed to compile:

It is usefull to create, from our home directory, a directory to contain sources we are going to download and compile:

libgdiplus

The first library we need to install is libgdiplus. She provide a GDI+ compatible library for non windows systems, and is used par System.Drawing library.

We begin by cloning Git repository, then extract the version we want:

(It’s very important  to rextract the last version shown on the release tab in Git, which you can check by simply copying the URL, https://github.com/mono/libgdiplus.git here, in your browser. The repository could very well be in a pre-version, unreleased unstable state)

Now that our directory has the correct version, we load dependancies needed for many images formats:

We setup our compile script, specifying we want programs and libraries built from source in /usr/local (as per standard linux recommandations):

Now, if you are used to Linux builds you are used to those commands, otherwise you will, quickly:

Once the build is done, we simply need to install into /usr/local, then go back to sources root for the next package:

 

Mono

The 2nd of the 4 packages to build and install is Mono itself. As I am writing this post, the last release is 3.2.3, so this is the one we are going to install. As described above, we start by cloning Git repository before extracting our version:

We configure the build as we did for libgdiplus:

MonoSetupCompileOK

Once the setup is done, you should see something like shown in the above picture. Even if the utility tells us we can start make now, we need one more step, specific to Mono. As we are going to compile Mono from scratch, and because Mono is written in C#, we need a mini compiler. This compiler exists in Mono project, and is named “monolite”. To install it, we run the command:

Once this “lite” compiler installed, it’s time to build Mono itself. The difference with a standard build is that we have to tell the process where to find Monolite, using the EXTERNAL_MCS variable. Note this is a Make variable, not an environnement one:

We install all this as we did before:

 

XSP

To install Mono hosting modules, we need to install XSP, which also is a mini server. We are going to be able to test what we did so far with it, even if we are not done yet, as for now, Apache and mod-mono are not installed.

We are going to type the following sequence of commands, which you must be started to get used to:

 

Run XSP

We have now installed Mono version 3.2.3 (to check, you type the command “mono –V”), and a server, not usable for production work, but working. To test we are going to deploy (file system) a small test application, with FTP or Samba, depending on your configuration. The project and source code for this test application are available on GitHub: https://github.com/BernardG/AspInfoMvc

To start the server, just type xsp4 INSIDE THE DIRECTORY WHERE YOUR APPLICATION IS, and you should see something like this below:

Point your browser on your url, port 8080, and you should see something like this:

AspMvcInfoUbuntuXSP

 

Install Apache, MySql and PHP

We already made good progresses, Mono is now working on our Linux server and able to render properly a small MVC 4 Web application. We are not done yet, as our goal is to be able to run simultaneously PHP and ASP.NET applications side by side (Lamp could have been installed first. If this is the case, jump directly to mod_mono installation.)

First we install the LAMP stack as usual, which is very easy with Ubuntu. You can install Samba in the same step. We will talk about it in a future post.

If tasksel is not installed, type

first.

You will see a menu reminder of old Dos times. Don’t unselect what is already selected (star showing selection, switch by pressing space bar) as this would uninstall a previously installed application…

AspUbuntuInstallLamp

You can see I did select Lamp, and about to select Samba, the other applications were installed when building the virtual machine. What we are looking at here is an Azure Virtual machine built with Ubuntu Server.

During install, you will be asked for a root password for MySql server:

aspinstalllampmysql

Once you are done installing all those different packages, if you point your browser to your server URL, you should see the default Apache page:

AspInstallApacheUbuntu

 

While we are at it, we can also test PHP. For this purpose, go to the default site directory:

write a single line:

CTRL-X, Y then Enter to save the file. Add /test.php at the end of the previously used URL, you should see something like this:

AspInstallTestPhp

 

mod_mono

So, now we have Mono on one side, which we tested with XSP, and Apache on the other side, with PHP. Our task now is to join the two together, which is mod_mono job, this module making Apache able to serve Asp.net and MVC, in lieu of XSP.

As before, we download the sources, build and install:

We need to link to Apache libraries, so we install Apache devloppement packages, before setup:

and now, as you are starting to get used to:

 

Setting up Apache with mod_mono

As we did with XSP, we are going to test running mod_mono with Apache, with the same little test application, but it’s not exactly as simple……..

The Mono project created an autoconfiguration system for mod_mono, perfect for “classical” Web forms applications, but, as there is no “default” file for MVC in the usual way, this is not going to work for us. We also want to setup Virtual Hosts (in the Apache context), which means we want to be able to host differents domains on the same server, some running PHP, others running ASP.NET

First, we need to let Apache now we need Mono configuration:

At the very end of the file, I add the line:

CTRL X, Y, Enter, to save modification.

Then we create a new directory, as we would for any other Apache Virtual Host:

Give internet user rights on this directory

Now we are going to copy Apache default site configuration for our new site, and change it:

Here is what your mvctest file should be after editing it:

We still have to enable the site, and restart Apache

Very well, but for now we don’t have any application to check that everything is working fine. So I copy files I have been using to test XSP into Apache test site:

If you are on a virtual machine on your local network, you just need to modify your host file (in C:WindowsSystem32Driversetc ) to set the alias for your machine IP address, for example

192.168.1.60    mvctest

For a remote server, you have to make sure your DNS server will be able to find your Apache server.

Navigating to the proper URL, you should see something like this:

AspMvcInfoUbuntuApache

and the assemblies list below:

AspMvcInfoAssembliesLoaded

Apache is now able to serve our MVC 4 test application. Note that we did not touch PHP in any way, so its ability to run applications for other Virtual Hosts is 100% available.

MySql with Entity Framework and Code First

The last step in building our LAMA stack is MySql. So we are going to create a small MVC application with basic CRUD abilities, using EntityFramework, Code First and MySql, as it is installed as part of the LAMP stack, and availble on most hosting providers, to not say all.

The very first thing to do is to create a user with all rights on your MySql server, in addition to “root”. Keeping root as user in your applications is too much of  as security hazard, even with a strong password, but it’s alos a way to make your developer life easier. I find simple and handy to create the same user, with the same password, for your local, windows MySql server, which I recommend to install on your Visual Studio station. This way, you will not have to change anything in your connection string between Windows and Linux. The steps for this are alos the same between Windows and Linux. First, start MySql console:

Enter your password. Then:

I create the same user twice, with the same password, once for localhost, the other time with my local IP address. This way, I will be able to login remotely with MySql Workbench with the same user name and password than in my config file. One way to eliminate errors. Note that I could create a user valid for any IP, but I see this as a security risk. I still have to give rights to these users:

In a previous post, I already explained how to get Code First to work with MySql. In this article, I talk about installing MySql with Workbench. We are going to use the same tools, and most of the same code for our MVC 4 test application. To create it, I made a new MVC 4 project in Visual Studio 2012, with the Internet template. Then I removed everything about membership and security to keep it as simple as possible, and copied model classes from the previous console application.

I added a controler, with Person as Model, and MyContext as context. Scaffolding generated all methods and views needed for CRUD operations (Create, Remove, Update, Delete). Still to jkeep things simple and avoid adding elements to the menu, I then copied all methods into the HomeController, modified the Index method  to pass the list to the view, copied views into the Home directory, then deleted what was generated by the scaffolding. I did not minute my time, but this takes a lot longer to write than to do!

I simply added a table to Index.cshtml (as generated by the scaffolding) to show the list on the main page, to check my application was working as expected on my developpement station:

Asp-Windows-HomePage

Getting the same result on Ubuntu with Mono and Apache took more time than I thought, but it’s not Mono’s fault, if I may say so… Sourire

In fact, and I discovered this while writing this paper, Mono work only with EntityFramework 6 (which for now is Release candidate 1), and not any previous version. This is because EntityFramework is now open source, which was not the case before. BUT, the last MySql .net connector is compatible up to version 5.0. Promise, I tried everything I could think of, no way with EF6, be it on Windows .Net or with Mono. I knew Devart was selling .Net connectors for MySql, so I had to try it, as it was said to be compatible with EF6. It’s a bit of a paradox, as the only connector able to work with EntityFramework Open Source is commercial. At least for now…

So, as there is no other way, I download Devart connector trial version, replace EF5 with EF6 in my project, do the same for mySql DLLs. Once rebuilt, no problems, working as before. Time to see what happens on Ubuntu. As I expected, a number of errors, who can be all (but one, of which I am going to talk later) be summed up to the fact that a number of DLLs/Assemblies are in the Gac on Mono side, and create conflicts with the one copied in the bin directory when deploying. this is the case for EntityFramework. To identify those “Mono” assemblies which were conflicting with .Net assemblies, I run this command on Ubuntu (It’s the same in Windows):

which list all assemblies in the Gac, and compared this list with the one in the MVC application bin directory. I found

  • EntityFramework.dll
  • Microsoft.Web.Infrastructure.dll
  • System.Web.Http.dll
  • System.Web.Http.WebHost.dll
  • System.Web.Razor.dll

in both lists. To check errors were actually coming from this, I simply renamed them (in the bin directory) from .dll to .dll-old, then pressed F5 in the browser to refresh the page. I got a new error, telling me I was on the right track:

Asp_Devart_License_Error

Devart connector being commercial, reference to a license told me that EntityFramework was able to detect Devart.Data.MySql as data provider, but it triggered an error as he was unable to load it due to the missing license. A Google search led me to a page about Devart Oracle connector. I did exactly as explained, which is in fact simpler than it looks like.

In Visual Studio solution explorer, with the project (where your MySql assemblies are linked to) selected, add a text file, named licenses.licx. The only line in that file must be:

Build action for that file must be “embedded ressource”. After deploying once again, I finally got this:
runnig Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono
running Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono

So, with Mono as with .Net, EntityFramework generated tables and columns. Only drawback, Devart connector is unable to create a new database if it does not already exists, while Oracle/MySql connector does this perfectly with .Net.

Conclusion: Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono works!

To conclude, it’s totally doable to build an MVC 4 application to be hosted on a Linux server, with Mono and Apache, using MySql as database with EntityFramework and CodeFirst. I have no doubts the next version of MySql connector will be EF 6 compatible. Meanwhile, there is the Devart connector. By the way, you may prefer PostgreSql, which .Net connector is supposed to be EF6 compatible, but I have not (yet) tested it.

If you want to try this test application yourself, sources are available on GitHub: https://github.com/BernardG/MvcMySqlUbuntu

If you have been reading so far, I wishes you great success with your own LAMA stack.

Acknowledgements

This post as well as the success with installing this LAMA stack would not have been possible without the work and writings of many people, bloging and answering questions in numerous forums, particularly StackOverflow. I cannot name them all here, but I want to thank especially:

Please do not hesitate to let me know about your success or problems with comments below this post. I hope this will be of use to you if you want to do the same. To be aware of new posts here, please subscribe to email updates.

This work is licensed under a Creative Commons license.

10 thoughts on “Run Asp.Net MVC 4 with MySql on Linux Ubuntu with Mono – LAMA and LAMP

  1. Bernard,
    This is a really helpful post especially for someone like me who is new to Linux. I have a small request for you to show me the process of setting up mono and MVC with nginx server if you can. I tried to google articles but none of them seem to explain baby steps like you did. Thanks a bunch!

  2. An example of my apache site config file: (/etc/apache2/sites-available/default)

    ServerAdmin webmaster@localhost
    ServerName default
    DocumentRoot /var/www/mvctest/public_html

    MonoServerPath default “/usr/local/bin/mod-mono-server4″
    MonoDebug default true
    MonoSetEnv default MONO_IOMAP=all
    MonoApplications default “/:/var/www/mvctest/public_html”

    Allow from all
    Order allow,deny
    MonoSetServerAlias default
    SetHandler mono
    SetOutputFilter DEFLATE
    SetEnvIfNoCase Request_URI “.(?:gif|jpe?g|png)$” no-gzip dont-vary

    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript

  3. Just in case “make get-monolite-latest” does not work, please use this command instead:

    make monolite_url=http://storage.bos.xamarin.com/mono-dist-master/bf/bf17a43b31a2be16f462ffdf1ae3d9801b846e90/monolite-110-latest.tar.gz get-monolite-latest

    make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/basic.exe

  4. When i entered “make get-monolite-latest”

    I got error message:
    rm -fr /home/avalon/monobuild/mono/mcs/class/lib/monolite-* mkdir -p
    /home/avalon/monobuild/mono/mcs/class/lib test ! -d
    /home/avalon/monobuild/mono/mcs/class/lib/monolite || test ! -d
    /home/avalon/monobuild/mono/mcs/class/lib/monolite.old || rm -fr
    /home/avalon/monobuild/mono/mcs/class/lib/monolite.old test ! -d
    /home/avalon/monobuild/mono/mcs/class/lib/monolite || mv -f
    /home/avalon/monobuild/mono/mcs/class/lib/monolite
    /home/avalon/monobuild/mono/mcs/class/lib/monolite.old cd
    /home/avalon/monobuild/mono/mcs/class/lib &–2014-01-07 07:51:57– http://storage.bos.xamarin.com/mono-dist-master/latest/monolite-110-latest.tar.gz
    Resolving storage.bos.xamarin.com (storage.bos.xamarin.com)…
    198.0.162.157 Connecting to storage.bos.xamarin.com (storage.bos.xamarin.com)|198.0.162.157|:80… connected. HTTP
    request sent, awaiting response… 404 Not Found 2014-01-07 07:51:59
    ERROR 404: Not Found.

    /bin/bash: curl: command not found

    gzip: stdin: unexpected end of file tar: This does not look like a tar archive tar: Exiting with failure status due to previous
    errors make:
    *** [get-monolite-latest] Error 2

  5. I’ve got an error during mono compilation
    “* No rule to make target ../../external/ikvm/reflect/*.cs’, needed by../class/lib/basic/basic.exe’. Stop.”

    Solve it by update submodules:
    git submodule init
    git submodule update

    • Thanks for the feedback, Rob. Did not saw that, as I did not do a mono compilation. BTW, there is a MySql .Net beta connector working with EF6. I tested it, but the beta seems OK with .Net, not with Mono. I’ll make a paper as soons as I get a version working properly woth Mono.

  6. Regularly I don’t set up on weblogs, even so i would like to point out that this put up truly pressured me to do this! severely fantastic publish

Add Comment Register



Leave a Comment Yourself

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">