Monday, July 12, 2010

Slackware with lighttpd, php, and mono (source installations)

This overview of installing the relevant lighttpd and mono software packages from source on Slackware 13.1 is designed as a broad overview. I've been using Apache and PHP for years, but I'm quite novice at lighttpd and mono. Also, despite using GNU/Linux for years at home, I've usually set up servers with stable, upgradeable FreeBSD.

Hopefully this will help others avoid pitfalls (or be of use to me in the future if I ever have to recover). I needed to install a fast web server with PHP and Mono. I've had a lot of trouble getting mono running on FreeBSD, so I decided to go with a GNU/Linux distribution for this server. Being a stickler for things I liked in the past, I went with the one I've always found easiest to use and upgrade: Slackware.

Software packages

As of this writing, the latest Slackware is 13.1, though I assume these techniques should mostly carry over to similar versions. I'm using the 64-bit variety. I was rather liberal about installing most software packages that came with Slackware 13.1, mostly out of laziness. After I was finished installing, I deleted Apache so I could install lighttpd.

The latest mono source files I used were for 2.6.4.

Step 1: Basic lighttpd install

I did a pretty vanilla install of lighttpd 1.4.26. Basically just did:
  1. downloaded, untar'd
  2. ./configure
  3. make
  4. make install
Simple, right? After this, I took some cues from the lighttpd documentation and set up a simple config file in /etc/lighttpd/lighttpd.conf (you have to manually create the directory). It looks like this:
server.document-root = "/var/www/servers/[site]/pages"

server.port = 80
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www"
server.groupname = "www"

mimetype.assign = (
".html" => "text/html",
".txt" => "text/plain",
".jpg" => "image/jpeg",
".png" => "image/png"
)

static-file.exclude-extensions = ( ".fcgi", ".php", ".rb", "~", ".inc" )
index-file.names = ( "index.html" )
Make sure to modify the document root to wherever you keep your HTML files. You'll want to create the www user and www group or change these to an existing user.

Next up things got a little tricky because there wasn't a readily available Slackware init.d script to start and stop this monster. No problem; I just borrowed one from the slackbuilds.com's pre-compiled repository. I slightly modified it to match the configuration I made:
#!/bin/sh
# Copyright (c) 2007, Daniel de Kok
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

LIGHTTPD=/usr/local/sbin/lighttpd
PIDFILE=/var/run/lighttpd.pid
LIGHTTPD_OPTIONS="-f /etc/lighttpd/lighttpd.conf"

is_pidof() {
local STATE=$(ps -p $1 -o cmd= | grep "$2" > /dev/null ; echo $?)
return $STATE
}

lighttpd_start() {
echo "Starting lighttpd: $LIGHTTPD"
if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
echo "Already running!"
return
fi
$LIGHTTPD $LIGHTTPD_OPTIONS
}

lighttpd_stop() {
echo "Stopping lighttpd: $LIGHTTPD"
if [ -r $PIDFILE ] && is_pidof $(cat $PIDFILE) lighttpd ; then
kill $(cat $PIDFILE)
rm -f $PIDFILE
else
echo "Not running!"
fi
}

lighttpd_restart() {
lighttpd_stop
sleep 1
lighttpd_start
}

lighttpd_reload() {
kill -s HUP $(cat $PIDFILE)
}

case "$1" in
'start')
lighttpd_start
;;
'stop')
lighttpd_stop
;;
restart)
lighttpd_restart
;;
reload)
lighttpd_reload
;;
*)
echo "usage $0 start|stop|restart"
esac
Save the above to /etc/rc.d/rc.lighttpd and change the permissions to allow execution (chmod u+x /etc/rc.d/rc.lighttpd).

Put an index.html file in your HTML root directory. Test your configuration by running /etc/rc.d/rc.lighttpd start and pointing your web browser to http://localhost to see that your index file loads. Next try to stop the server: /etc/rc.d/rc.lighttpd stop.

If you just want a basic lighttpd install on Slackware, you can more or less stop here.

Start on boot and stopping on shutdown

To make lighttpd start on boot simply add the following you your /etc/rc.d/rc.local file:
if [ -x /etc/rc.d/rc.lighttpd ]; then
/etc/rc.d/rc.lighttpd start
fi
Likewise, to make it stop on shutdown, add this to /etc/rc.d/rc.local_shutdown (usually empty by default):
if [ -x /etc/rc.d/rc.lighttpd ]; then
/etc/rc.d/rc.lighttpd stop
fi

Mono 2.6.4 install

This is the first time I've seen mono install flawlessly on Slackware without using the sources made available by the SlackBuilds. I basically followed the directions exactly as they appeared in the README.
  1. ./configure --prefix=/usr/local
  2. make
  3. make install

xsp 2.6.4

To use ASP.NET with lighttpd, xsp needs to be installed. xsp is the package that contains the fastcgi components that allow mono to interface with lighttpd. Once again, I mostly followed the accompanying documentation. I used the config prefix /usr/local rather than the one suggested in the documentation.

The steps I followed to install were:
  1. ./configure --prefix=/usr/local
  2. make
  3. make install
A little note about step 2: I had a slight hitch following the standard installation instructions. Using the installation parameters from the above mono install, I needed to specify where the directory holding the file dotnet.pc in order to make the xsp package. Using the find command:
find /usr -name dotnet.pc
I determined it was in /usr/local/lib/pkgconfig and simply added the path to the existing PKG_CONFIG_PATH environmental variable.

To find your list of environmental variables, type the env command and hit enter.

Locate get the relevant variable from the list. In my case, it was PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig

Reassign the variable by typing
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/local/lib64/pkgconfig:/usr/lib64/pkgconfig
into your shell prompt.

It's quite likely a reboot would have solved this problem as well.

libgdi installation

I didn't realize this wasn't installed. It probably should have been installed first! This is necessary to run mono on fastcgi. Anyway, the problem is an easy one to rectify.

Once again, I did:
  1. ./configure --prefix=/usr/local
  2. make
  3. make install

Modifying lighttpd configuration to use mono

This part gets a little tricky, but it's doable. Much of my information for this area comes from a document, also linked below, on interfacing FastCGI and lighttpd to use mono.

First of all, create a new directory in your /etc/lighttpd directory called conf.d.

Save the following to /etc/lighttpd/conf.d
# Add index.aspx and default.aspx to the list of files to check when a
# directory is requested.
index-file.names += ( "index.aspx", "default.aspx" )

### The directory that contains your Mono installation.
var.mono_dir = "/usr/local/"

### A directory that is writable by the lighttpd process.
# This is where the log file, communication socket, and Mono's .wapi folder
# will be created.
# For a typical system-wide installation on Linux, use:
var.mono_shared_dir = "/tmp/"

### The path to the server to launch to handle FASTCGI requests.
# For ASP.NET 1.1 support use:
#var.mono_fastcgi_server = mono_dir + "bin/" + "fastcgi-mono-server"
# For ASP.NET 2.0 support use:
var.mono_fastcgi_server = mono_dir + "bin/" + "fastcgi-mono-server2"

### The root of your applications
# For apps installed under the lighttpd document root, use:
var.mono_fcgi_root = server.document-root

### Application map
# A comma separated list of virtual directory and real directory
# for all the applications we want to manage with this server. The
# virtual and real dirs. are separated by a colon.
var.mono_fcgi_applications = "/:."
Next up, the configuration file needs some additions and alterations.

Open /etc/lighttpd/lighttpd.conf and add the following to your configuration under the server.document-root = "/var/www/servers/[your web root]/pages" line:
server.modules = (
# "mod_rewrite",
# "mod_redirect",
# "mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
"mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
# "mod_cgi",
# "mod_compress",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
"mod_accesslog" )
This is a list of modules. I kept the ones not relevant commented out for now. Of course, many people will want to use some of them, particular rewrite, redirect, and alias. Either way, I prefer to keep things simple for now. Next change the line
index-file.names = ( "index.html" )
to
index-file.names = (
"index.xhtml", "index.html", "index.htm", "default.htm",
"index.php", "default.aspx", "index.aspx"
)
Beneath your new index file list, add the following:
include "conf.d/mono.conf"

fastcgi.server = (
".aspx" => ((
"socket" => mono_shared_dir + "fastcgi-mono-server",
"bin-path" => mono_fastcgi_server,
"bin-environment" => (
"PATH" => "/bin:/usr/bin:" + mono_dir + "bin",
"LD_LIBRARY_PATH" => mono_dir + "lib:",
"MONO_SHARED_DIR" => mono_shared_dir,
"MONO_FCGI_LOGLEVELS" => "Standard",
"MONO_FCGI_LOGFILE" => mono_shared_dir + "fastcgi.log",
"MONO_FCGI_ROOT" => mono_fcgi_root,
"MONO_FCGI_APPLICATIONS" => mono_fcgi_applications
),
"max-procs" => 1,
"check-local" => "disable"
))
)

fastcgi.map-extensions = (
".asmx" => ".aspx",
".ashx" => ".aspx",
".asax" => ".aspx",
".ascx" => ".aspx",
".soap" => ".aspx",
".rem" => ".aspx",
".axd" => ".aspx",
".cs" => ".aspx",
".config" => ".aspx",
".dll" => ".aspx"
)

Appendix: links and more

lighttpd homepage.The mono project site:Google code information on the install (I found this very helpful, as it was simpler than the mono documentation).

1 comment:

Anonymous said...

I would like to exchange links with your site soonerorlateryouwillknow.blogspot.com
Is this possible?