ASP.NET/C# on Linux (CentOS 6.5, Apache 2.2, ISPConfig 3 and Mono 3)

Mono project

I would like to share my experience of making a virtual Linux server to serve ASP.NET websites. The procedures aren’t new, but it was somewhat tricky to use multiple information sources and my own experience to achieve this goal. Anyway, this article will serve as a little how-to for myself and hopefully you will find it useful too.

System that has been used: VirtualBox, CentOS 6.5 (x86_64), Apache 2.2, Mono 3.4.0 and ISPConfig 3.0.5.4

Table of contents:

  1. Installing the hosting system (optional)
  2. Setting up installation environment
  3. Downloading required packages
  4. Installation
  5. Configuring ISPConfig3
  6. Testing
  7. References

Installing the hosting system (optional)


The Perfect Server – CentOS 6.4 x86_64 (Apache2, Dovecot, ISPConfig 3) OR Installing and configuring CentOS 6.3 XFCE mini server
Back to Top

Setting up installation environment


Install all dependencies:
yum install bison gettext glib2 freetype fontconfig libpng libpng-devel libX11 libX11-devel glib2-devel libgdi* libexif glibc-devel urw-fonts java unzip gcc gcc-c++ automake autoconf libtool make bzip2 wget libungif-devel freetype-devel libtiff-devel libjpeg-devel xulrunner-devel perl-TimeDate.noarch expect

Go to root’s directory, make mono folder there, and jump into it:
cd /root
mkdir mono
cd mono
Back to Top

Downloading required packages


Download latest Mono release and extract it:
wget http://origin-download.mono-project.com/sources/mono-1.1.16/mono-3.4.0.tar.bz2
tar xjf mono-3.4.0.tar.bz2
Download and extract XSP package:
wget http://origin-download.mono-project.com/sources/xsp/xsp-2.10.2.tar.bz2
tar xjf xsp-2.10.2.tar.bz2
Download and extract libgdiplus package:
wget http://origin-download.mono-project.com/sources/libgdiplus/libgdiplus-2.10.9.tar.bz2
tar xjf libgdiplus-2.10.9.tar.bz2
Download and extract mod_mono package:
wget http://origin-download.mono-project.com/sources/mod_mono/mod_mono-2.10.tar.bz2
tar xjf mod_mono-2.10.tar.bz2
Back to Top

Installation

Installing mod_mono


cd ~/mono/mod_mono-2.10
./configure --prefix=/usr
Output:

Configuration summary for mod_mono

   * Installation prefix = /usr
   * Apache version = 2.2
   * Apache modules directory = /usr/lib64/httpd/modules
   * apxs = /usr/sbin/apxs
   * apr-config = /usr/bin/apr-1-config
   * apu-config = /usr/bin/apu-1-config
   * CFLAGS = -g -O2 -I/usr/include/httpd -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wformat-security -fno-strict-aliasing -pthread  -I/usr/include/apr-1   -pthread  -I/usr/include/apr-1
   * Verbose logging (debug) = no
   * GCOV options used = no
   * Profiling enabled = no
   * mono prefix = /usr/lib/pkgconfig/../..
   * Default MonoApplicationsConfigDir = /etc/httpd/conf/mod-mono-applications

make
make install
ldconfig

Back to Top

Installing libgdiplus


cd ~/mono/libgdiplus-2.10.9
./configure --prefix=/usr
[showMiddleOfPostAdd]
Output:

Configuration summary

   * Installation prefix = /usr
   * Cairo = 1.8.8 (system)
   * Text = cairo
   * EXIF tags = No. Get it from http://libexif.sourceforge.net/
   * Codecs supported:

      - TIFF: yes
      - JPEG: yes
      - GIF: yes
      - PNG: yes

      NOTE: if any of the above say 'no' you may install the
            corresponding development packages for them, rerun
            autogen.sh to include them in the build.

make
make install
Back to Top

Installing mono


Switch to extracted mono folder:
cd ~/mono/mono-3.4.0
Run following commands to configure and install mono:
./autogen.sh --prefix=/usr OR ./configure --prefix=/usr
The output you should see:

        mcs source:    mcs

   Engine:
        GC:            sgen and bundled Boehm GC with typed GC and parallel mark
        TLS:           __thread
        SIGALTSTACK:   yes
        Engine:        Building and using the JIT
        oprofile:      no
        BigArrays:     no
        DTrace:        no
        LLVM Back End: no (dynamically loaded: no)

   Libraries:
        .NET 2.0/3.5:  yes
        .NET 4.0:      yes
        .NET 4.5:      yes
        MonoDroid:     no
        MonoTouch:     no
        JNI support:   IKVM Native
        libgdiplus:    assumed to be installed
        zlib:          system zlib

Continue with setup:
perl -pi -e 's/HAVE_LOCALCHARSET_H 1/HAVE_LOCALCHARSET_H 0/' eglib/config.h
Get the latest version of the monolite distribution, which contains just enough to run the mcs compiler:
make get-monolite-latest OR make monolite_url=http://storage.bos.xamarin.com/mono-dist-master/bf/bf17a43b31a2be16f462ffdf1ae3d9801b846e90/monolite-110-latest.tar.gz get-monolite-latest OR make monolite_url=http://storage.bos.xamarin.com/mono-dist-master/latest/monolite-111-latest.tar.gz get-monolite-latest if previous command doesn’t work.

You may want to run the mono and mcs tests. All tests should pass.
make check

And finally installation:
make -j 8 (may take a while)
make install
Check if you got mono installed successfully:
mono -V
The output:

Mono JIT compiler version 3.4.0 (tarball Thu Apr 24 03:05:33 GMT 2014)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen

Add the path to your ~/.bash_profile
echo export PKG_CONFIG_PATH=/usr/lib/pkgconfig:$PKG_CONFIG_PATH>>~/.bash_profile
echo export PATH=/usr/bin:$PATH>>~/.bash_profile
source ~/.bash_profile

Should you wish to access mod_mono control panel, add these lines to /etc/httpd/conf/httpd.conf:

<Location /mono>
  SetHandler mono-ctrl
  Order deny,allow
  Deny from all
  Allow from 192.168.0.2
</Location>

Replace 192.168.0.2 (or add more Allow lines) with the IP address of your own computer so that you can access the control panel.
Restart Apache and now you will be able to access mono control panel via http://yourdomainoripaddress/mono/.
service httpd restart


Back to Top

Installing XSP


Go to xsp folder, configure and install it:
cd ~/mono/xsp-2.10.2
./configure --prefix=/usr
Output:

xsp-2.10.2

  Build Environment
    Install prefix:          /usr
    Datadir:                 /usr/share
    Libdir:                  /usr/lib
    Build documentation:     yes
    Mono 2.0 compiler:       /usr/bin/gmcs
    Mono 4.0 compiler:       /usr/bin/dmcs
    Target frameworks:       .NET 2.0, .NET 4.0
    Build SQLite samples:    yes

export PKG_CONFIG_PATH=`whereis pkgconfig | awk '{print $2}'`
make
make install
Back to Top

Configuring ISPConfig 3 (optional)


Add line Include /etc/httpd/conf/mod_mono.conf to /etc/httpd/conf/httpd.conf:
vi /etc/httpd/conf/httpd.conf
Here is how it should look like:

[..]
Include /etc/httpd/conf/mod_mono.conf
# ISPConfig stuff
NameVirtualHost *:80
NameVirtualHost *:443
Include /etc/httpd/conf/sites-enabled/

Restart Apache:
service httpd restart

Now in your ISPConfig control panel pick a website that you want to run as ASP.NET and change its settings similar to these (no changes needed in Options tab):

Once you’ve done this, you will have to change the ownership of website’s root directory and subdirectories to apache user/group or otherwise you will get this error “System.UnauthorizedAccessException: Access to the path “/var/www/www.yourdomain.com/web” is denied.“. Please let me know if you found a workaround for this issue.
chown -R apache:apache /var/www/clients/client1/web1/web
Restart Apache:
service httpd restart
Back to Top

Testing


In order to test if Apache serves ASP.NET files, add default.aspx file to your websites root directory with following lines:

Unfortunately, you will have to change the permissions of newly added files every time you upload them…
chown -R apache:apache /var/www/clients/client1/web1/web
Now go to your browser and type the address of your website to see the lovely “Hello, World!” ๐Ÿ™‚

If all went fine, that’s all you should see in your /var/log/httpd/error.log:

[Thu Apr 24 04:52:00 2014] [notice] caught SIGTERM, shutting down
mod-mono-server received a shutdown message
[Thu Apr 24 04:52:03 2014] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Thu Apr 24 04:52:03 2014] [warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Thu Apr 24 04:52:03 2014] [notice] Digest: generating secret for digest authentication ...
[Thu Apr 24 04:52:03 2014] [notice] Digest: done
[Thu Apr 24 04:52:03 2014] [notice] mod_python: Creating 4 session mutexes based on 256 max processes and 0 max threads.
[Thu Apr 24 04:52:03 2014] [notice] mod_python: using mutex_directory /tmp 
[Thu Apr 24 04:52:04 2014] [warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)
[Thu Apr 24 04:52:04 2014] [notice] Apache/2.2.15 (Unix) DAV/2 mod_fcgid/2.3.9 PHP/5.3.3 mod_python/3.3.1 Python/2.6.6 mod_ruby/1.3.0 Ruby/1.8.7(2011-06-30) mod_ssl/2.2.15 OpenSSL/1.0.1e-fips mod_mono/2.10 configured -- resuming normal operations
Listening on: /tmp/mod_mono_server_global
Root directory: /

Back to Top

References

Back to Top


Related Images:

,

20 responses to “ASP.NET/C# on Linux (CentOS 6.5, Apache 2.2, ISPConfig 3 and Mono 3)”

  1. Greetings,

    Great tutorial i am in need of help.

    Syntax error on line 1025 of /etc/httpd/conf/httpd.conf: Could not open configuration file /etc/htt pd/conf/sites-enabled/: No such file or directory

    I couldn’t proceed with the Configuring ISPConfig 3 (optional) step.

    Please suggest some advice

    Thanks in advance

  2. I had problem compiling mono, particularly mod_mono.c. It seems that the following structure have been renamed as per Apache API change log.

    unixd_config => ap_unixd_config

  3. Hi,
    I have tried all steps Unable to access mod_mono Control panel. Also After adding ISPConfig 3 Config line to Httpd.conf file its unable to find “Starting httpd: httpd: Syntax error on line 1014 of /etc/httpd/conf/httpd.conf: Could not open configuration file /etc/httpd/conf/sites-enabled/: No such file or directory

    Please suggest unbale to move.

  4. sed -e ‘s/@ASM_VERSION@/2.0.0.0/g’ data/xbuild.exe.config.in > /usr/lib/mono/2.0/xbuild.exe.config
    /bin/sh ./../../mkinstalldirs /usr/lib/mono/xbuild-frameworks/.NETFramework/v2.0/RedistList
    /usr/bin/install -c -c -m 644 frameworks/net_2.0.xml /usr/lib/mono/xbuild-frameworks/.NETFramework/v2.0/RedistList/FrameworkList.xml
    /bin/sh ./../../mkinstalldirs /usr/lib/mono/xbuild-frameworks/.NETFramework/v3.0/RedistList
    /usr/bin/install -c -c -m 644 frameworks/net_3.0.xml /usr/lib/mono/xbuild-frameworks/.NETFramework/v3.0/RedistList/FrameworkList.xml
    /bin/sh ./../../mkinstalldirs /usr/lib/mono/xbuild-frameworks/.NETFramework/v4.0/RedistList
    /usr/bin/install -c -c -m 644 frameworks/net_4.0.xml /usr/lib/mono/xbuild-frameworks/.NETFramework/v4.0/RedistList/FrameworkList.xml
    /bin/sh ./../../mkinstalldirs /usr/lib/mono/xbuild-frameworks/.NETFramework/v4.0/Profile/Client/RedistList
    /usr/bin/install -c -c -m 644 frameworks/net_4.0_client.xml /usr/lib/mono/xbuild-frameworks/.NETFramework/v4.0/Profile/Client/RedistList/FrameworkList.xml
    /bin/sh ./../../mkinstalldirs /usr/lib/mono/xbuild/Microsoft/Portable/v4.0
    /usr/bin/install -c -c -m 644 targets/Microsoft.Portable.Common.targets /usr/lib/mono/xbuild/Microsoft/Portable/v4.0/Microsoft.Portable.Common.targets
    /usr/bin/install: cannot stat `targets/Microsoft.Portable.Common.targets’: No such file or directory
    make[7]: *** [install-pcl-targets] Error 1
    make[7]: Leaving directory `/root/mono/mono-3.4.0/mcs/tools/xbuild’
    make[6]: *** [do-install] Error 2
    make[6]: Leaving directory `/root/mono/mono-3.4.0/mcs/tools/xbuild’
    make[5]: *** [install-recursive] Error 1
    make[5]: Leaving directory `/root/mono/mono-3.4.0/mcs/tools’
    make[4]: *** [install-recursive] Error 1
    make[4]: Leaving directory `/root/mono/mono-3.4.0/mcs’
    make[3]: *** [profile-do–net_2_0–install] Error 2
    make[3]: Leaving directory `/root/mono/mono-3.4.0/mcs’
    make[2]: *** [profiles-do–install] Error 2
    make[2]: Leaving directory `/root/mono/mono-3.4.0/mcs’
    make[1]: *** [install-exec] Error 2
    make[1]: Leaving directory `/root/mono/mono-3.4.0/runtime’
    make: *** [install-recursive] Error 1

  5. Hello I’m having problems with my installation I get this message:

    checking for dmcs... no
    configure: error: You need to install 'dmcs'
    

    Could you help me with this error?

    Thanks

  6. Thank you so much for this write up.. was pulling my hair out trying to make centos be able to run .net app.
    Saves my company having to pay for a windows host.

  7. hi Donatas,
    I have a problem with dmcs

    [root@centos xsp-2.10.2]# ./configure -prefix=/usr
    checking build system type... x86_64-unknown-linux-gnu
    checking host system type... x86_64-unknown-linux-gnu
    checking target system type... x86_64-unknown-linux-gnu
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... gawk
    checking whether make sets $(MAKE)... yes
    checking whether to enable maintainer-specific portions of Makefiles... no
    checking for a BSD-compatible install... /usr/bin/install -c
    checking for gawk... (cached) gawk
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for pkg-config... /usr/bin/pkg-config
    checking pkg-config is at least version 0.9.0... yes
    checking for MONO_MODULE... yes
    checking for gmcs... /usr/bin/gmcs
    checking for dmcs... no
    configure: error: You need to install 'dmcs'
    
    [root@centos xsp-2.10.2]# locate dmcs
    /root/mono/mono-3.4.0/runtime/_tmpinst/bin/dmcs
    /root/mono/mono-3.4.0/scripts/dmcs
    /root/mono/mono-3.4.0/scripts/dmcs.in
    [root@centos xsp-2.10.2]#
    
  8. Hello,

    I have followed this guide, but mod_mono is looking for mono at /usr/local/bin/mono (at runtime). However, /usr/local/bin/mono does not exist. The correct bin directory appears to be: /usr/local/mono/bin.

    How can I fix this?

    • OOPS!

      I meant to write: “The correct bin directory appears to be: /usr/bin/mono.”

      $which mono
      /usr/bin/mono
      

      Does it matter that I installed everything as the root user?

      • GAH!

        It looks like someone else in this comment thread had the same problem, so I tried his fix:

        ln -s /usr/bin/mono usr/local/bin/mono

        However, now I get this!

        Cannot open assembly '/opt/mono/lib/mono/2.0/mod-mono-server2.exe': No such file or directory.

        Now I just feel bad inside. ๐Ÿ™

        • Fixed! I deleted everything “mono” i could find via “find” command. then, I started from step 1. Everything works now. (My issue had to do with old mono installations, and possibly a lack of installing XSP.)

          Thank you for making the only CentOS 6 mod-mono tutorial that seems to work!

  9. Hi,
    I have an issue to install mono on my centos6.5. After downloading monolite using he command wget http://download.mono-project.com/sources/mono/mono-2.10.8.tar.gz
    in my mono-3.2.8 directory and using the command make check. It fails and giving the error of missing library. Will you help me to resolve this issue. I completely stuck at this point. I am getting below error:

    make[4]: Entering directory `/mono/mono-3.2.8/mono/mini'
    MONO_PATH=/mono/mono-3.2.8/mcs/class/lib/net_4_5 ../../runtime/mono-wrapper /mono/mono-3.2.8/mcs/class/lib/build/mcs.exe -unsafe -nowarn:0162 -out:TestDriver.dll -target:library TestDriver.cs
    Cannot open assembly '/mono/mono-3.2.8/mcs/class/lib/build/mcs.exe': No such file or directory.
    

    Any luck!!!

    Thanks in advance..

    • Sorry, the link i mentioned in the above comment is wrong. I tried to download monolite- latest.

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

      • Hi,
        I am able to resolve my above issues but stuck in the next while installing xsp-2.10.2.

        Error:
        
        GMCS  /out:2.0/Mono.WebServer2.dll
        /usr/local/bin/gmcs: line 2: /usr/local/bin/mono: No such file or directory
        /usr/local/bin/gmcs: line 2: exec: /usr/local/bin/mono: cannot execute: No such file or directory
        make[2]: *** [2.0/Mono.WebServer2.dll] Error 126
        make[1]: *** [all-recursive] Error 1
        make: *** [all-recursive] Error 1
        

        Please help…. ๐Ÿ™

    • Hello buddy,

      I also run into similar sort of problems last time Iโ€™ve tried to setup Mono on a little bit different server configuration, but they happened due to the download error of the latest monolite. Iโ€™ll try to repeat the setup again and see what happens.

      However, XSP and mod_mono installations worked fine with Mono version 3.2.6.

      • Hi Donatas,

        Thanks for your quick reply. Dont waste your time to reproduce the above error… ๐Ÿ™‚
        I am able to resolve the above error by linking with below command
        ln -s /usr/bin/mono /usr/local/bin/mono
        But again I stuck in another error:

        mdoc: Could not load file or assembly 'Mono.Cecil, Version=0.9.4.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' or one of its dependencies.
        See `mdoc help' for more information.
        make[2]: *** [Mono.WebServer.tree] Error 1
        make[1]: *** [all-recursive] Error 1
        make: *** [all-recursive] Error 1
        

        Searching a lot I found similar error post but no satisfied solution to overcome with this.

        Any luck…!!!
        Thanks in advance.

Leave a Reply

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