Project

General

Profile

Actions

HowTo configure Apache to run Redmine » History » Revision 18

« Previous | Revision 18/26 (diff) | Next »
Matt Brown, 2011-06-03 22:34


HowTo configure Apache to run Redmine

These notes assume you already have Redmine running via the webrick server and are looking to get Redmine running via your existing Apache installation. Most of the commands assume you are in the root installation directory of redmine, so be sure to change directory there before starting.

For CentOS 5

Assumptions

  • OS is CentOS 5
  • Web server is Apache 2
    • mod_cgi is enabled
    • name based virtual servers are being used
    • the web server runs under the user apache, group apache

Myths

  • You do not need to run mod_fcgid
  • You do not need to run mod_fastcgi

This section needs work. I can't tell if these are the myths or the corrections to the myths.
(note: if someone were so generous to post working, known good, HOWTO steps here for enabling FastCGI, that would be highly valuable to the entire community.
It is reported that www.redmine.org itself runs FastCGI, so it is obviously a valid, worthwhile, stable, performing way to run this great great web app'.)

I have added sections detailing the installation and configuration of mod_fastcgi and mod_fcgid below. --wmbaum, (2009-08-30)

We had problems with getting Rails 2.3.5 working with cgi and fastcgi. fcgid on Apache2 worked great for 9.3. We tweaked some of the notes based on the recent fcgid updates. -- cybersprocket, (2010-04-25)

Basic Steps

  • Kill the webrick session
  • Copy the public/dispatch.cgi.example to public/dispatch.cgi
  • Edit public/dispatch.cgi to fix the shell script invocation to point to the ruby executable:
    #!/usr/local/bin/ruby
    or
    #!/usr/bin/ruby
    or
    #!c:/ruby_root/bin/ruby.exe
  • Also in public/dispatch.cgi, you may need to change the require line to an absolute path as stated in the comment to something like
    require "/usr/lib/ruby/gems/1.8/gems/rails-2.1.2/lib/dispatcher.rb"
  • Make sure public/dispatch.cgi has execute permissions via:
    # chmod 755 public/dispatch.cgi
  • Update the config/environment.rb file to force the rails environment to production, simply uncomment this line at the start of the file:
    ENV['RAILS_ENV'] ||= 'production'
  • Add your virtual host entry to the apache configuration file (/etc/httpd/conf/httpd.conf). We installed redmine into the /live/redmine folder on our server. Note: be sure to point your DocumentRoot to the public sub-folder!
    <VirtualHost *:80>
        ServerName redmine.<YOUR-DOMAIN>.com
        ServerAdmin webmaster@<YOUR-DOMAIN>.com
        DocumentRoot /live/redmine/public/
        ErrorLog logs/redmine_error_log

        <Directory "/live/redmine/public/">
                Options Indexes ExecCGI FollowSymLinks
                Order allow,deny
                Allow from all
                AllowOverride all
        </Directory>
    </VirtualHost>
  • Make sure your files, log, tmp, and vendor directories are all accessible (read/write) by user apache, group apache. We did that via a change of ownership:
    # chown -R apache:apache files log tmp vendor

Error Messages and Resolutions

  • Rails requires RubyGems >= 0.9.4. Please install RubyGems
    Look for rogue versions of ruby binaries. We had an older version in /usr/bin/ruby as well as /usr/local/bin/ruby.
  • Premature script headers
    This is the generic "got something before the Content-Type: header in a CGI script" error from Apache. Run dispatch.cgi (see below) and see what comes out BEFORE the Content-Type: directive.

Helpful Commands

  • # which ruby
    tells you which ruby binary is being run when the fully-qualified-filename has not been specified.
  • # find / -name ruby
    searches your entire system for any file named ruby, warning: can take a while on large filesystems.
  • # ruby -v
    tell you what version of ruby you are running by default
  • #public/dispatch.cgi
    runs the dispatch CGI script. It should spit out HTML that start with Content-Type: text/html; charset=utf-8, if ANYTHING precedes the Content-Type text you will get a "premature script headers" error in the Apache log files.

mod_fastcgi

I suggest getting redmine running with mod_cgi above, not only to verify your basic redmine and apache configuration, but also so you can appreciate the perfomance gains you'll get from mod_fastcgi or mod_fcgid.

We'll start with mod_fastcgi.

Install prerequisites:

yum install libtool httpd-devel apr-devel apr

Download and Install mod_fastcgi

cd /usr/local/src/
wget http://www.fastcgi.com/dist/mod_fastcgi-current.tar.gz

tar -zxvf mod_fastcgi-current.tar.gz
cd mod_fastcgi-2.4.6/
cp Makefile.AP2 Makefile 
make top_dir=/usr/lib/httpd
make install top_dir=/usr/lib/httpd

Create or edit /etc/httpd/conf.d/mod_fastcgi.conf

LoadModule fastcgi_module modules/mod_fastcgi.so
<IfModule mod_fastcgi.c>
FastCgiIpcDir /tmp/fcgi_ipc/
</IfModule>

The /tmp/fcgi_ipc/ directory needs to be writable to the apache user:

chown -R apache.apache /tmp/fcgi_ipc/
chmod -R 777 /tmp/fcgi_ipc/

Note: I had to do this more than once.. It created directories which it then didn't own.. ??

Download and install fcgi (for fcgi gem)

wget http://www.fastcgi.com/dist/fcgi-2.4.0.tar.gz
tar -zxvf fcgi-2.4.0.tar.gz
cd fcgi-2.4.0
./configure
make
make install

Install fcgi gem:

gem install fcgi

Configuring redmine to use fastcgi:

In your redmine/public/ directory, copy dispatch.fcgi.example to dispatch.fcgi

Note: Mine was shebanged to "#!/usr/bin/env ruby", which is fine. I found a reference or two that seemed to indicate the 'env' bit is preferable to calling ruby directly. If this doesn't work, then you'll need to change it to wherever your ruby is as above.

./public/.htaccess

#<IfModule mod_fastcgi.c>
#       RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
#</IfModule>
#<IfModule mod_fcgid.c>
#       RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
#</IfModule>
#<IfModule mod_cgi.c>
#       RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
#</IfModule>
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

The default .htaccess will use cgi if it's available, so we need to force fcgi. You could perhaps rearrange the directives to prefer fcgi -- I just commented out the others and forced it with RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] You can see which one is actually in use with ps gaux

Give it a whirl:

/etc/init.d/httpd configtest
/etc/init.d/httpd restart

Additional Apache Configuration

When I first fired up apache with redmine, apache started very slowly and sucked up a significantly larger chunk of RAM than normal. Further investigation revealed that it had fired off 8 ruby .../redmine/public/dispatch.fcgi processes! No wonder it was slow.

I was running redmin under the apache default VirtualHost, and the default StartServers, MinSpareServers, etc. applied. You can adjust the defaults in /etc/httpd/conf/httpd.conf or even better is to run redmine under a NameVirtualHost or a different VirtualHost. This prevents apache from firing off a bunch of extraneous processes, and NameVirtualHost should allow you to configure multiple redmine environments on the same IP without wasting a bunch of resources.

If you're having issues with apache virtual hosts, this can be very helpful:

/usr/sbin/httpd -t -D DUMP_VHOSTS

mod_fcgid

fcgid from Apache

Official Apache mod_fcgid this is the Apache version, seems newer and we had more luck with this than the Coremail hosted version below.

cd /usr/local/src/
wget http://apache.mirrors.hoobly.com/httpd/mod_fcgid/mod_fcgid-2.3.5.tar.gz
tar zxvf mod_fcgid.2.3.5.tgz
cd mod_fcgid.2.3.5

Configure and Install

./configure.apxs
make
make install
service httpd restart

fcgid from China Coremail service

mod_fcgid seems newer and preferable to mod_fastcgi.

cd /usr/local/src/
wget http://apache.mirrors.hoobly.com/httpd/mod_fcgid/mod_fcgid-2.2.tar.gz
tar zxvf mod_fcgid.2.2.tgz
cd mod_fcgid.2.2

Edit Makefile

#top_dir      = /usr/local/apache2
top_dir      = /usr/lib/httpd

Build it..

make
make install

Edit/create /etc/httpd/conf.d/mod_fcgid.conf

LoadModule fcgid_module /usr/lib/httpd/modules/mod_fcgid.so

<IfModule mod_fcgid.c>
    SocketPath /tmp/fcgid_sock/
    AddHandler fcgid-script .fcgi
</IfModule>

Now you should be able to switch between mod_fastcgi and mod_fcgid by renaming one of them to other than *.conf in /etc/httpd/conf.d/

cd /etc/httpd/conf.d/
mv mod_fastcgi.conf mod_fastcgi.conf.not
/etc/init.d/httpd restart

Either Version, Permissions

With either fcgid version you may run into problems with the fcgid service starting. Make sure the socks parent directory (typically /var/log/httpd) has proper permissions. The default directory permissions for /var/log/httpd is for a standard non-fcgid install of Apache. You need to add execute permissions for Apache to read/write to the directory properly while it is running fcgid.

chmod 755 /var/log/httpd
service httpd restart

Installation Sources

In the above steps, I installed from sources only where I didn't find any RPM's in common repo's. I'm rather surprised that one can't simply yum install mod_fastcgi, mod_fcgid, fcgi, etc., but there we are. If you find better methods or sources for any of the above, please feel free to update.

Ubuntu Server (Version ?) (This not don't work for 8.04 LTS)

Install passenger

sudo aptitude install libapache2-mod-passenger

This did switch the type of apache server to worker from prefork but in my case that was acceptable.

I had installed the redmine tarball into /opt/redmine as redmine-0.8.5 and made a symlink named current.
Then make a link to the redmine public directory from the apache DocumentRoot (see /etc/apache2/config.d/*).

ln -s /opt/redmine/current/public /var/www/redmine

Updated /etc/apache/config.d/redmine (or wherever your virtualhost is defined) with the following:

RailsEnv production
RailsBaseURI /redmine

Restart apache.

For FreeBSD (and possibly others)

I found the current instructions to be lacking on some way. With the information above, the scripts and css might not appear correctly, the link get broken and such. Also, some hacks seems to have been lost to history (the #!/bin/bash/ruby hack, wich is not required with this technique). Here is how I got it going.

Make sure 'Apache 2.2', 'Ruby', 'fastcgi' (including the gem) are installed.
First, putting redmine in a sub-directory requires more work and is left for the reader as an exercise to get properly (hint Rewrite is your friend), so from now on, I will assume that redmine will be the DocumentRoot.
So here it is, my httpd.conf :

LoadModule fastcgi_module     libexec/apache22/mod_fastcgi.so

DocumentRoot "/usr/local/www/redmine/public" 

FastCgiServer /usr/local/www/redmine/public/dispatch.fcgi -idle-timeout 120 -initial-env RAILS_ENV=production -initial-env PATH=/usr/local/bin -processes 2

<Directory /usr/local/www/redmine/public>
   AddHandler fastcgi-script fcgi
   Order allow,deny
   Allow from all
   AllowOverride all
   Options +FollowSymLinks +ExecCGI
   RewriteEngine On
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteRule ^(.*)$ dispatch.fcgi
</Directory>

Now let's explain what happens and why:
  1. AddHandler fastcgi-script fcgi: defines that when apache identifies a file with extension fcgi, if should be handled buy the fastcgi-script handler. This definition of a handler is created by the mod_fastcgi.so module (loaded through the LoadModule directive of couse).
  2. Options +FollowSymLinks +ExecCGI: tells apache that within this directory, CGI-ish script execution is allowed
  3. RewriteCond %{REQUEST_FILENAME} !-f: only rewrite if the file doesn't exist
  4. RewriteRule ^(.*)$ dispatch.fcgi: everything goes to dispatch.fcgi
  5. FastCgiServer /usr/local/www/redmine/public/dispatch.fcgi -idle-timeout 120 -initial-env RAILS_ENV=production -initial-env PATH=/usr/local/bin -processes 2: This is the main thing. As Scott Laird explains in this blog, running FastCGI can run in three modes (see post). This tells FastCGI how to handle our script, with the important part being the initial-env to define what variables should be set in the FastCGI context. As FastCGI starts, it will normally start with a blank (emtpy) environment variables, so yeah, your $PATH will be empty, and no /usr/bin/env will NOT find the ruby executable in the path and thus failing with the error env: ruby: No such file or directory. Also, ruby will not know that he is expected to start in production env. With this line, you don't have to fix your dispatch.fcgi shabang (the #!/usr/bin/env ruby line) nor will you have to change the config/environment.rb file with a ENV['RAILS_ENV'] ||= 'production'.

Restart apache and you should be set.

Updated by Matt Brown almost 13 years ago · 18 revisions