Building mod_fastcgi For Apache 2

May 29th, 2005
 

Something I discovered last night in playing around with Ruby and Rails is that the CGI has a very long startup time, on the order of several seconds. That doesn’t sound like much, but it’s extremely annoying, especially when you’re trying to test changes to your code. I knew that the Fast CGI mod for Apache would help, but I had avoided it to simplify the setup of Rails. Now it was obvious that I needed mod_fastcgi.

Finding and downloading the mod was easy. Getting it built and installed was not. It comes with its own makefiles, one for Apache 1.x, and another for Apache 2. The makefile relies on a makefile fragment called special.mk that is supposed to be distributed with Apache. However, Red Hat 9’s Apache package didn’t have the fragment:

# make -f Makefile.AP2
Makefile.AP2:12: /usr/local/apache2/build/special.mk: No such file or directory
make: *** No rule to make target `/usr/local/apache2/build/special.mk'. Stop.

So I thought Aha! I need the httpd-devel packaged installed. So I fired up RPM and installed the package, but the mod still wouldn’t build. Same error.

Next I went to the Internet. A Google search turned up the fact that other people have had the same error, especially people running Red Hat 9. But I found no clue as to how to locate the missing special.mk file. Eventually, though, I came across a reference to a command called apxs, which is supposed to know how to compile mods for Apache. I typed in the command:

# apxs
Usage: apxs -g [-S <var>=<val>] -n <modname>
       apxs -q [-S <var>=<val>] <query> ...
       apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]
               [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]
               [-Wl,<flags>] <files> ...
       apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
       apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...

Woo hoo! Progress! Next I read the man page, but as tired as I was (this was about 2 AM), I couldn’t make heads nor tails of it. But I saw an example that used the -i -a and -c flags to compile a module. I tried this, but apxs complained that it didn’t know the name to use for the module. Then I remember seeing the -n argument in the man page, to name the module. So I added a -n mod_fastcgi argument. Lo and behold, it not only compiled the module, but installed it too:

# apxs -n mod_fastcgi -i -a -c mod_fastcgi.c fcgi_buf.c fcgi_config.c fcgi_pm.c fcgi_protocol.c fcgi_util.c
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o mod_fastcgi.lo mod_fastcgi.c && touch mod_fastcgi.slo
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o fcgi_buf.lo fcgi_buf.c && touch fcgi_buf.slo
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o fcgi_config.lo fcgi_config.c && touch fcgi_config.slo
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o fcgi_pm.lo fcgi_pm.c && touch fcgi_pm.slo
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o fcgi_protocol.lo fcgi_protocol.c && touch fcgi_protocol.slo
/usr/lib/httpd/build/libtool --silent --mode=compile gcc -prefer-pic -O2 -g -pipe -march=i386 -mcpu=i686 -I/usr/kerberos/include -DAP_HAVE_DESIGNATED_INITIALIZER -DLINUX=2 -D_REENTRANT -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -D_SVID_SOURCE -D_GNU_SOURCE -pthread -DNO_DBM_REWRITEMAP -I/usr/include/httpd -c -o fcgi_util.lo fcgi_util.c && touch fcgi_util.slo
/usr/lib/httpd/build/libtool --silent --mode=link gcc -o mod_fastcgi.la -rpath /usr/lib/httpd/modules -module -avoid-version fcgi_util.lo fcgi_protocol.lo fcgi_pm.lo fcgi_config.lo fcgi_buf.lo mod_fastcgi.lo
/usr/lib/httpd/build/instdso.sh SH_LIBTOOL='/usr/lib/httpd/build/libtool' mod_fastcgi.la /usr/lib/httpd/modules
/usr/lib/httpd/build/libtool --mode=install cp mod_fastcgi.la /usr/lib/httpd/modules/
cp .libs/mod_fastcgi.so /usr/lib/httpd/modules/mod_fastcgi.so
cp .libs/mod_fastcgi.lai /usr/lib/httpd/modules/mod_fastcgi.la
cp .libs/mod_fastcgi.a /usr/lib/httpd/modules/mod_fastcgi.a
ranlib /usr/lib/httpd/modules/mod_fastcgi.a
chmod 644 /usr/lib/httpd/modules/mod_fastcgi.a
PATH="$PATH:/sbin" ldconfig -n /usr/lib/httpd/modules
----------------------------------------------------------------------
Libraries have been installed in:
/usr/lib/httpd/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
chmod 755 /usr/lib/httpd/modules/mod_fastcgi.so
[activating module `mod_fastcgi' in /etc/httpd/conf/httpd.conf]

Note the last line. It also added the configuration line

LoadModule fastcgi_module /usr/lib/httpd/modules/mod_fastcgi.so

to my Apache configuration file. Unfortunately, it added it inside an innappropriate <IfModule> structure. I moved it out, added the additional configuration specified in the Rails howto, and I had a working mod_fastcgi.

I’m happy to report that having fastcgi in the mix makes Rails run very nicely; much faster, much smoother. Now I have to learn enough Rails to build something.

I’m working on it…




9 Responses to “Building mod_fastcgi For Apache 2”

  1. LA Says:

    ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

  2. Contagious Says:

    special.mk lives in where you install apache
    if you install from rpm on redhat/fedora system, it should be in /usr/lib/httpd

  3. Jim Says:

    Thanks for the tip, Contagious, but I don’t have a special.mk anywhere on my system – ‘locate special.mk’ says so. I do have the apache devel package installed. Doesn’t matter, though, because I got the module built without it.

  4. Ryan Says:

    I’m using Fedora Core 4. After I installed httpd-devel, I found special.mk in /usr/lib/httpd/build/

  5. Ryan Says:

    Possibly the reason why “locate special.mk” didn’t find the file is because you didn’t update the locate database after installing httpd-devel. To do that run “updatedb” as root. Cheers!

  6. Ted Says:

    Great writeup. I had the same problems and the same results, but unfortunately when I configtest apache I get the following error:

    [root@pdf1 mod_fastcgi-2.4.2]# /etc/init.d/httpd configtest
    Syntax error on line 219 of /etc/httpd/conf/httpd.conf:
    Can’t locate API module structure `mod_fastcgi_module’ in file /usr/lib/httpd/modules/mod_fastcgi.so: /usr/lib/libapr.so.0: undefined symbol: mod_fastcgi_module

    Did anyone see this problem? Any suggestions?

    Thx in advance, Ted

  7. Jim Says:

    Ryan – No, ‘locate special.mk’ doesn’t find the file because it isn’t there. After I installed httpd-devel, I looked for special.mk where it should been. When I couldn’t find it, I did run updatedb, then used locate to see if it was somewhere else. No dice. It still isn’t there. Just to be 100% sure I did this: ‘find / -name special.mk’. I just don’t have a special.mk. (Did I mention that this is a Redhat 9 system?)

  8. Richard Aspden Says:

    Ted: I just had the exact same issue. Found that it was down the module being called “fastcgi_module”, not “mod_fastcgi_module”. Alter the line in your httpd.conf to say the following:

    LoadModule fastcgi_module /usr/lib/apache/mod_fastcgi.so

    instead of

    LoadModule mod_fastcgi_module /usr/lib/apache/mod_fastcgi.so

    You’ll find it then works.

    Hope that helps!

    Rick

  9. Richard Aspden Says:

    Re earlier comment – easier way of doing it.

    apxs -n fastcgi -i -a -c mod_fastcgi.c fcgi_buf.c fcgi_config.c fcgi_pm.c fcgi_protocol.c fcgi_util.c

    That will install it correctly. Then just restart Apache. Use apxs2 if it’s called that on your system.

    I’ve made a permanant copy of this at http://rick.guysintheknow.com/wiki/Compiling_FastCGI_for_Apache2 – hopefully it’ll help people with this problem in the future.