Configure apache2 + mod_mono to run ASP.Net MVC5 application on Ubuntu 14.04

Install binaries

Install mono

Please click here to install mono.

Install mod_mono

sudo apt-get install apache2
sudo apt-get install mono-complete
sudo apt-get install libapache2-mod-mono mono-apache-server4

After above installation, visit http://your-host-name, we should see below default page.

Verify mod_mono.config

cat /etc/apache2/mods-available/mod_mono.conf
AddType application/x-asp-net .aspx .ashx .asmx .ascx .asax .config .ascx
DirectoryIndex index.aspx
# Include the web application definitions generated by mono-server{2,4}-update.
# If you want to use ASP.NET 2.0 (via mono-apache-server2), use:
# Include /etc/mono-server2/mono-server2-hosts.conf
# If you want to use ASP.NET 4.0 (via mono-apache-server4), use:
# Include /etc/mono-server4/mono-server4-hosts.conf
Include /etc/mono-server4/mono-server4-hosts.conf

Prepare you webapp directory

Create folder for your webapp

mkdir /home/azureuser/webapp

Grant permission allow Apache to access your webapp folder

sudo chown -R www-data:www-data /home/azureuser/webapp

Config Apache for your webapp

Generate Apache config

Go to, in this article i will choose “Virtual Host” in “Configuration Type”, but it will be similar if you choose “Application”

Fill in require fields and click preview to generate configuration file, and modify “/usr/bin/mod-mono-server2” to “/usr/bin/mod-mono-server4”.

if you webapp require certain environment variable, you can define with “MonoSetEnv” command within the config file.

Virtual Host:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
MonoAutoApplication disabled
AddHandler mono .aspx ascx .asax .ashx .config .cs .asmx .axd
MonoApplications “/:/home/azureuser/webapp”
MonoServerPath /usr/bin/mod-mono-server4
DocumentRoot /home/azureuser/webapp
<Directory />
Options FollowSymLinks
AllowOverride None
<Directory “/home/azureuser/webapp”>
Options Indexes FollowSymLinks MultiViews
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
SetHandler mono
DirectoryIndex index.aspx index.html Default.cshtml
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory “/usr/lib/cgi-bin”>
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
ErrorLog /var/log/apache2/kudu-error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/kudu-access.log combined


Alias /scm “/home/azureuser/webapp”
# MonoServerPath can be changed to specify which version of ASP.NET is hosted
# mod-mono-server1 = ASP.NET 1.1 / mod-mono-server2 = ASP.NET 2.0
# For SUSE Linux Enterprise Mono Extension, uncomment the line below:
# MonoServerPath scm “/opt/novell/mono/bin/mod-mono-server2”
# For Mono on openSUSE, uncomment the line below instead:
MonoServerPath scm “/usr/bin/mod-mono-server4”
# To obtain line numbers in stack traces you need to do two things: 
# 1) Enable Debug code generation in your page by using the Debug=”true”
# page directive, or by setting <compilation debug=”true” /> in the
# application’s Web.config
# 2) Uncomment the MonoDebug true directive below to enable mod_mono debugging
MonoDebug scm true

# The MONO_IOMAP environment variable can be configured to provide platform abstraction
# for file access in Linux. Valid values for MONO_IOMAP are:
# case
# drive
# all
# Uncomment the line below to alter file access behavior for the configured application
MonoSetEnv scm MONO_IOMAP=all
# Additional environtment variables can be set for this server instance using
# the MonoSetEnv directive. MonoSetEnv takes a string of ‘name=value’ pairs
# separated by semicolons. For instance, to enable platform abstraction *and*
# use Mono’s old regular expression interpreter (which is slower, but has a
# shorter setup time), uncomment the line below instead:
# MonoSetEnv scm MONO_IOMAP=all;MONO_OLD_RX=1
MonoApplications scm “/scm:/home/azureuser/webapp”
<Location “/scm”>
Allow from all
Order allow,deny
MonoSetServerAlias scm
SetHandler mono
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI “\.(?:gif|jpe?g|png)$” no-gzip dont-vary
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript

Register config

Navigate to /etc/apache2/sites-available, copy above content and save into webapp.conf (file name doesn`t matter, but must have suffix “conf”). And register config with a2ensite, we should see below output.

sudo a2ensite webapp.conf
Enabling site webapp.
To activate the new configuration, you need to run:
service apache2 reload

A symlink will be created under /etc/apache2/sites-enabled

├── sites-available
│ ├── 000-default.conf
│ ├── default-ssl.conf
│ └── webapp.conf
└── sites-enabled
├── 000-default.conf -> ../sites-available/000-default.conf
└── webapp.conf -> ../sites-available/webapp.conf

Enable mod_mono module

Enable mod_mono module, navigate to /etc/apache2/mods-available

sudo a2enmod mod_mono

should see below output

Enabling module mod_mono.
To activate the new configuration, you need to run:
service apache2 restart

let restart Apache (which will also reload all the config)

sudo service apache2 restart

Now visit http://your-hostname/scm, (http://your-hostname if you are configuring virtual host). Ooop! 403!!!

We can also see error logs from /var/log/apache2/error.log

[Thu Mar 03 01:16:13.498564 2016] [authz_core:error] [pid 21259:tid 139811025307392] [client] AH01630: client denied by server configuration: /home/azureuser/webapp

Allow request to visit webapp folder

Turn out by default Apache not allow request access any file path other than /var/www/html. Let edit /etc/apache2/apache2.conf

We will see there is an sample code block that commented out in default

#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted

Enable or copy it and update the folder path

<Directory /home/azureuser/webapp>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted

Restart Apache again then you should good to go!

sudo service apache2 restart
Show your support

Clapping shows how much you appreciated shrimpy’s story.