Redmine on Apache December 19, 2007
Posted by Björn in : software , trackbackRuby on Rails and Apache, it sounds great but it can be frustrating. It was for me. After hours of trial and error (and Googling) it finally worked. In the spirit of contributing something back to the Redmine project this article summarizes how I got it running through Apache on Mac OS X. I’m also including a few dead ends and things that went wrong. That part that is missing from most of the documentation I found and leads to frustration. That being said, I can’t guarantee a stress-free experience. This is just my own experience with the installation and there can be differences with your particular setup.
What is this Redmine you speak of?
For a bunch of small personal projects I need something to keep track of tasks and documentation. Redmine is a tool for issue tracking and project management I discovered recently.
I’ve been using Trac for a while and I like the idea of including a wiki and interacting with the source repository. I could have installed Trac again but Redmine offers the same features and more. Built-in support for multiple projects on a single database is my personal killer feature. And it’s written in Ruby. Figuring out why people are making such a big fuss about Ruby was still on my to-do list. So I decided to switch.
After checking out the latest version from the Subversion repository it was up and running in no time thanks to the built-in web server. Apparently that’s a Ruby on Rails feature.
A built-in web server is an advantage for quick deployment but because I was already running Apache on port 80 for Subversion, it became a problem. So I decided to put everything on a single server to make it easier to manage. Or so I thought. Making Rails play nice with Apache was a wee bit harder than expected.
What you need
There are a couple of things you need. The good news is that Leopard provides most of it out of the box.
- Ruby: version 1.8 is included with Leopard
- Ruby on Rails: version 1.2.3 is bundled with Leopard
- Subversion: Leopard has 1.4.4
- Apache 2: Leopard again, just enable it in the System Preferences. It also has all the necessary modules.
- MySQL: you can download 5.0.45 for Mac OS X here
- Redmine of course. I used the 0.6.3 release.
- Your favorite terminal and a root shell
- Time…
Getting Redmine
You should set up Redmine using the built-in server first. If something doesn’t work it’s probably not because of the web server. I recommend you get the latest (stable) release straight from Subversion instead of using an archive. I mention this because the archive has DOS line endings, which messes up things. The Redmine Subversion repository uses native line endings so it doesn’t matter. You’ll see what I mean in a minute.
Apache’s document root on Leopard is /Library/WebServer/Documents. To keep it simple we’re going to put Redmine in /Library/WebServer/redmine and link to it. You put it in any directory you want, just make sure Apache has access. I’ll use an SVN export which means there is no version information. If you want to update from SVN regularly you should check out the trunk.
First get the application:
# cd /Library/WebServer/
# svn export http://redmine.rubyforge.org/svn/tags/0.6.3 redmine
If you’re using a tarball and are wondering about the line endings, run the CGI script from the command line. Running a CGI script from the shell is a good trick to get better error messages than what you find in the server logs.
# redmine/public/dispatch.cgi.example
-sh: redmine/public/dispatch.cgi.example: /usr/bin/ruby^M: bad interpreter: No such file or directory
The ^M means the line endings are wrong. Don’t worry about other errors for now. If you skip this check and later see errors in the Apache logs like the one below it’s probably the same thing.
[error] [client 127.0.0.1] Premature end of script headers: dispatch.cgi, referer: http://localhost/redmine/
For the final step you need to create a link to direct Apache to the application. We’re not going to use a virtual host.
# ln -s /Library/WebServer/redmine/public /Library/WebServer/Documents/redmine
More information about using symlinks is available on this wiki page.
Once that’s settled you can set up your database and configure Redmine following these instructions. Or watch the video.
Apache configuration for CGI
Now Redmine works. Time to move it over to Apache. Let’s start with the CGI approach. It may not be the fastest way to run Rails but it’s very basic and the RoR wiki has bit of documentation on it. I have found this is a good way to weed out most of the problems.
Mac OS X stores the Apache configuration in /private/etc/apache2/. In httpd.conf make sure these lines are not commented out.
LoadModule env_module libexec/apache2/mod_env.so
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
LoadModule cgi_module libexec/apache2/mod_cgi.so
Next, create a file redmine.conf in /private/etc/apache2/other. By default, anything in that directory is loaded as part of the configuration. This keeps the main httpd.conf clean and the Redmine stuff is easier to find. Note that I say Redmine, and not Ruby on Rails. For another RoR application you’ll need to add a new configuration file. This is what my file looks like:
SetEnv RAILS_ENV production
<Directory "/Library/WebServer/Documents/redmine">
AllowOverride all
Order allow,deny
Allow from all
</Directory>
Note that I refer to /Library/WebServer/Documents/redmine and not /Library/WebServer/redmine/. If you use the wrong directory the AllowOverride directive won’t work. It has to work because Redmine uses an .htaccess file. Some examples also include an AddHandler directive. I have found that it’s not necessary because it’s already taken care of in .htaccess.
Apache is now configured and has to be restarted:
# apachectl restart
Directory permissions
The web server is ready but it can’t do anything yet. First it needs a CGI script. In Redmine’s public directory rename the example script dispatch.cgi.example to dispatch.cgi.
In addition write access is required for the tmp and log directories under /Library/WebServer/redmine. Run chmod 666 on them.
Now you should see Redmine’s home page when you open http://localhost/redmine in your browser.
Route problems
At this point the front page works but you’re could be getting errors when you click on a link.
no route found to match "/account/login" with {:method=>:get}
If, like me, you don’t know Ruby this is very confusing. If you check the Apache error log, you see that there is something wrong with the paths in the Ruby application. Thanks to this blog entry there is a solution. In config/boot.rb replace
root_path = Pathname.new(root_path).cleanpath(true).to_s
with
root_path = Pathname.new(root_path).cleanpath(true).realpath().to_s
Can you make this thing go faster?
Redmine works now but it’s very slow. This is where FastCGI comes in. First disable mod_cgi in httpd.conf and enable mod_fastcgi. FastCGI also needs a temporary directory with full access.
# mkdir /tmp/fcgi_ipc
# chmod 777 /tmp/fcgi_ipc
And then add this to httpd.conf:
<IfModule mod_fastcgi.c>
FastCgiIpcDir /tmp/fcgi_ipc/
</IfModule>
Apache will need a restart again.
You also need to enable
ENV['RAILS_ENV'] ||= 'production'
in redmine/config/environment.rb. For some reason I couldn’t pass the environment variable to FastCGI so it has to be fixed in Ruby.
Browse to your Redmine URL and enjoy the quick response time.
Comments»
Thanks for the info. Couple of notes…
You forgot to mention renaming the dispatch.fcgi.example file in the redmine config directory to dispatch.fcgi. Of course, if someone misses that, it’s pretty obvious when you hit the server.
Also, regarding using the current binaries on MySQL.com – there are a variety of pages online which discuss the issue of the prefs pane and startup item not working. I used the leopard-preferred method detailed on a few pages to get MySQL to start on boot:
http://hivelogic.com/articles/installing-mysql-on-mac-os-x/
The instructions there are for compiling MySQL from source but the launch on boot info is still relevant.
use “DefaultInitEnv RAILS_ENV production” instead “SetEnv RAILS_ENV production” to pass the environment variable to FastCGI
Thanks, this was very helpful.
Couldn’t get fastcgi working though, couldn’t find blahblah dispatch.fcgi
I just found your reference to my blog. Thanks for the link and glad my research helped another!
I don’t run mac, but your guide was very helpful (with a few adaptations) in getting me set up with apache+fastcgi+redmine 0.7.3 on debian. Thanks!
This setup is pretty similar to setting up redmine on apache2 on Debian Lenny.
Couple of remarks:
* you can disable mod_cgi by deleting the symbolic link in /etc/apache2/mods_enabled/cgi.load
* you can enable fastcgi.conf by using a2enmod /etc/apache2/fastcgi.load
Just managed to get it running, and works like a charm now.
Thanks for the tutorial!
I can’t get this to work on my system. I get an error that the application fails to start property and the apache logs tell the problem. I just don’t know how to fix it.
log snippet…
/Library/WebServer/Documents/redmine/../config/environment.rb:20
/Library/WebServer/Documents/redmine/dispatch.cgi:3:in `require’
/Library/WebServer/Documents/redmine/dispatch.cgi:3
Based on that, it appears that the dispatch file is telling it to go to the wrong path.
Since /Library/WebServer/Documents/redmine is a link to my redmine/public dir, it cannot go up one dir (..) and go to the config dir.
Is there a fix for this problem?
Looking at the linked site below, it appears I’m not the only one with the problem..
http://www.redmine.org/boards/2/topics/show/3452#message-3656
About the RAILS_ENV variable. I think an even better way to pass it to Redmine is to use this directive:
FastCgiServer /path/to/redmine/public/dispatch.fcgi -initial-env RAILS_ENV=production
It also allows to tweak other FastCGI parameters for this instance.
I figured some of this out!
you need: the fast cgi module for both ruby and Apache!
in the virtual host file, the syntax to set the environment variable was:
DefaultInitEnv RAILS_ENV production
the other syntax did NOT work for me! (SetENV)
good luck!