Installing Redmine on Mac OS X 10.6: The Correct Way
- Ce post est aussi disponible en français
Yes, it’s a rather pretentious title, considering that it’s my first time succeeding at installing a Rails application, and no, I don’t care. It was a pain in the ass so I need to document how I did it, and it might help other people, so if it really bothers you, read it as ‘the correct way for me’.
Redmine (1.2.1 of 2011-07-11 as of this writing) is pretty touchy about its requirements: gems (and Ruby and RubyGems as well) cannot be too old, some cannot be too recent, and one (i18n) even cannot be anything other than the specified version (0.4.2).
The Redmine installation page says it requires:
- Ruby 1.8.6 or 1.8.7, not 1.9;
- RubyGems 1.3.7 or higher, but not 1.5.0 and not 1.7.0 or higher, because Rails 2.3.11 fails with it;
- Rails 2.3.11 (then later tells you that 2.3.14 works as well);
- Rack 1.1.1;
- Rake 0.8.7 (not 0.9.x because it’s not supported by Rails);
- i18n 0.4.2 (the current version 0.6.0 will give you an error that 0.4.2 cannot be found).
Moreover, Redmine comes with Rails 2.3.11 bundled in the vendor directory, and will use it unless you remove it from there and change the version you want in config/environment.rb
. This is neatly documented on the install page with a very thorough explanation: “read config/environment.rb
first”. Just changing the version won’t help: if Redmine finds rails in its vendor directory, it will use that one.
The reality of Redmine requirements is a bit different. Rake 0.9.x is supported by Rails 2.3.14 (it installs 0.9.2 as part of its dependencies), but RubyGems 1.7.0 or higher still isn’t. So to minimise the number of obsolete and buggy software that I run and the fuss that ensues, I am going to use Rails 2.3.14.
Using RVM
Ruby Version Manager, or RVM, allows you to use a different version of Ruby and a different set of gems for different projects, without installing said gems system-wide. It is similar to Python’s virtualenv. In my opinion, it is absolutely vital to use it right from the start. You never know what other software you might want to install later, software that might have requirements as tricky as Redmine’s, yet different in the actual versions.
RVM can be found at http://beginrescueend.com/ and is installed thusly (it apparently requires git, which is kind of a bummer if you don’t use it. But you should give it a try, it’s awesome once you start grokking it):
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
Then add the following to your .bash_profile
or .zshrc
(obviously you want to switch to zsh and use oh-my-zsh, because they’re awesome too) as the install script will tell you (personalised with your $HOME
path):
# This loads RVM into a shell session.
[[ -s "/Users/olivier/.rvm/scripts/rvm" ]] && source "/Users/olivier/.rvm/scripts/rvm"
Next we need to install the latest pre-1.9 Ruby to use with RVM. RVM will build it from source, but it doesn’t take too long (if you find it does, just head over to 9gag.com. We can list the available Ruby versions, and then install the one we want, namely 1.8.7 (that will result in ruby-1.8.7-p352
):
$ rvm list known
# MRI Rubies
[ruby-]1.8.6[-p420]
[ruby-]1.8.6-head
[ruby-]1.8.7[-p352]
[ruby-]1.8.7-head
[ruby-]1.9.1-p378
[ruby-]1.9.1[-p431]
[ruby-]1.9.1-head
[ruby-]1.9.2-p180
[ruby-]1.9.2[-p290]
[ruby-]1.9.2-head
[ruby-]1.9.3[-preview1]
[ruby-]1.9.3-head
ruby-head
...
$ rvm install 1.8.7
...
$ rvm use 1.8.7
Once done, we will create a gemset for Redmine, where RubyGems will install the gems we need in the versions we need, without interfering with the system installation.
$ rvm gemset create redmine
'redmine' gemset created (/Users/olivier/.rvm/gems/ruby-1.8.7-p352@redmine).
$ rvm gemset use redmine
Notes:
The Ruby version and gemset in use are tied to the shell session, so you have to switch every time you start a new shell. It can be done in one step:
$ rvm use 1.8.7@redmine Using /Users/olivier/.rvm/gems/ruby-1.8.7-p352 with gemset redmine
The current environment can be queried with
rvm-prompt
:$ rvm-prompt ruby-1.8.7-p352@redmine
You can switch back to the system Ruby with:
$ rvm use system Now using system ruby.
You do not need
sudo
to install gems in an RVN gemset, because all the files are contained in your home directory.Rake commands while using a gemset should be prefixed by rvm:
$ rvm rake blah blah
Installing gems
First of all, let us speed up gem installs 10x, as suggested by The Budding Rubbyist. Add the following to your ~/.gemrc
file, creating it if needed:
gem: --no-ri --no-rdoc
That will omit installing the documentation (that we will never read as we’re only interested in using Ruby software, not developing some) when installing gems, a step that is inexplicably very lengthy as it usually takes longer than the “Building native extensions. This could take a while…” step of some gems.
Next, make sure we are using the Ruby and gemset we created earlier:
$ rvm use 1.8.7@redmine
Then install Rails 2.3.14 and i18n 0.4.2 (Rails installs i18n 0.6.0, but remember, Redmine wouldn’t see this one if we forced it into its thick skull with a [we]brick):
gem install rails -v=2.3.14
gem install i18n -v=0.4.2
Note: To figure out that it was Rails 2.3.14 that I wanted, I listed all the versions available and picked the latest 2.3.x:
$ gem query --all --remote -n '^rails$'
*** REMOTE GEMS ***
rails (3.1.0, 3.0.10, 3.0.9, 3.0.8, 3.0.7, 3.0.6, 3.0.5, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 2.3.14, 2.3.12, 2.3.11, 2.3.10, 2.3.9, 2.3.8, 2.3.7, 2.3.6, 2.3.5, 2.3.4, 2.3.3, 2.3.2, 2.2.3, 2.2.2, 2.1.2, 2.1.1, 2.1.0, 2.0.5, 2.0.4, 2.0.2, 2.0.1, 2.0.0, 1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.6, 1.1.5, 1.1.4, 1.1.3, 1.1.2, 1.1.1, 1.1.0, 1.0.0, 0.14.4, 0.14.3, 0.14.2, 0.14.1, 0.13.1, 0.13.0, 0.12.1, 0.12.0, 0.11.1, 0.11.0, 0.10.1, 0.10.0, 0.9.5, 0.9.4.1, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.5, 0.8.0)
The list
command is simpler, but it will list everything that starts with rails
, which is a bit of a bother:
$ gem list --all --remote rails
*** REMOTE GEMS ***
rails (3.1.0, 3.0.10, 3.0.9, 3.0.8, 3.0.7, 3.0.6, 3.0.5, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 2.3.14, 2.3.12, 2.3.11, 2.3.10, 2.3.9, 2.3.8, 2.3.7, 2.3.6, 2.3.5, 2.3.4, 2.3.3, 2.3.2, 2.2.3, 2.2.2, 2.1.2, 2.1.1, 2.1.0, 2.0.5, 2.0.4, 2.0.2, 2.0.1, 2.0.0, 1.2.6, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.6, 1.1.5, 1.1.4, 1.1.3, 1.1.2, 1.1.1, 1.1.0, 1.0.0, 0.14.4, 0.14.3, 0.14.2, 0.14.1, 0.13.1, 0.13.0, 0.12.1, 0.12.0, 0.11.1, 0.11.0, 0.10.1, 0.10.0, 0.9.5, 0.9.4.1, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.5, 0.8.0)
rails-3-settings (0.1.1)
rails-action-args (0.1.1, 0.1.0)
rails-admin (0.0.0)
rails-and-solid (0.9.1, 0.9.0)
...
I wanted to use SQLite (I couldn’t make the mysql gem build against Zend Server’s MySQL, and I don’t care), so I installed the sqlite3 gem:
gem install sqlite3
We also need to downgrade RubyGems from the latest version (1.8.10 as of writing) to a version that is at least 1.3.7 but not 1.5.0 and not 1.7.0 or later. The version we want can be determined the same way as for Rails, by querying the rubygems-update gem:
$ gem list --all --remote rubygems-update
*** REMOTE GEMS ***
rubygems-update (1.8.10, 1.8.9, 1.8.8, 1.8.7, 1.8.6, 1.8.5, 1.8.4, 1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.2, 1.7.1, 1.7.0, 1.6.2, 1.6.1, 1.6.0, 1.5.3, 1.5.2, 1.5.0, 1.4.2, 1.4.1, 1.4.0, 1.3.7, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.0, 1.1.1, 1.1.0, 1.0.1, 1.0.0, 0.9.5, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.11, 0.8.10, 0.8.8, 0.8.6, 0.8.5, 0.8.4, 0.8.3)
So we want 1.6.2:
$ gem update --system 1.6.2
...
$ gem -v
1.6.2
Note that some older version of the gem
command, like the 1.3.7 recommended by Redmine, do not support specifying the version in the gem update --system
command. In that case, you would need to get the most recent version and then downgrade it:
$ gem update --system
$ gem update --system 1.6.2
Now let’s proceed to installing Redmine.
Installing Redmine
Download the latest stable release (1.2.1 of 2011-07-11 as of this writing) and unpack it.
We need to disable the built-in Rails 2.3.11 and tell Redmine to use our 2.3.14 version. In config/environment.rb
, change these lines:
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.3.11' unless defined? RAILS_GEM_VERSION
to:
# Specifies gem version of Rails to use when vendor/rails is not present
RAILS_GEM_VERSION = '2.3.14' unless defined? RAILS_GEM_VERSION
Next, move rails out of the vendor directory. If you don’t, Redmine will use the old version no matter what the above line says. I do this:
mv vendor/rails vendor.rails.disabled
By the way, it’s the “read config/environment.rb first” bit in the requirements list and the “when vendor/rails is not present” in the comment above that tell us that we must remove rails from the vendor directory. As I said, a very thorough explanation.
Next, proceed with installation. With SQLite, database.yml
looks like this:
production:
adapter: sqlite3
database: db/redmine.db
development:
adapter: sqlite3
database: db/redmine.db
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/redmine_test.db
Note: The following commands for me were littered with deprecation warnings like this one:
rake/rdoctask is deprecated. Use rdoc/task instead (in RDoc 2.4.2+)
Please install RDoc 2.4.2+ to generate documentation.
WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead.
at redmine-1.2.1/lib/tasks/email.rake:170
As far as I know they don’t matter, apart from the fact that they render it quite difficult to determine whether the task succeeded or not.
Generate a session store secret (don’t forget to rvm rake
instead of just rake
):
rvm rake generate_session_store
Create the database structure:
RAILS_ENV=production rvm rake db:migrate
Insert default configuration data in database:
RAILS_ENV=production rvm rake redmine:load_default_data
Then test your installation:
ruby script/server webrick -e production
or
ruby script/server -p 3000 webrick -e production
It takes a little while to start. The first two lines appear quite quickly and let you check that Redmine is running the correct Rails version:
=> Booting WEBrick
=> Rails 2.3.14 application starting on http://0.0.0.0:3000
Then the server is ready when you see this:
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2011-09-25 14:28:09] INFO WEBrick 1.3.1
[2011-09-25 14:28:09] INFO ruby 1.8.7 (2011-06-30) [i686-darwin10.8.0]
[2011-09-25 14:28:09] INFO WEBrick::HTTPServer#start: pid=39670 port=3000
Running Redmine under Unicorn
Disclaimer: I have no idea if using Unicorn to run Redmine is a good idea. I just know that WEBrick is not for production and that Passenger is an Apache module, and I’d rather not bother with it if I can avoid it. After all, we reached thus far without need admin privileges.
I found the instruction at Install Redmine on Ubuntu Server from the Redmine HowTo’s list, except the part about the RVM wrapper that comes from Brandon Tilley.
Install Unicorn, still under RVM:
$ gem install unicorn
Create a wrapper for unicorn_rails
. The wrapper will run unicorn_rails
with the correct Ruby version and gemset:
$ rvm wrapper ruby-1.8.7-p352@redmine redmine unicorn_rails
This creates a redmine_unicorn_rails
command that uses the ruby-1.8.7-p352@redmine
environment.
Create the unicorn configuration file unicorn.conf
, for example in Redmine’s config
directory:
# /var/www/redmine/config/unicorn.conf
# Number of CPU Cores
worker_processes 2
# Same Redmine User
user "redmine", "redmine"
working_directory "/var/www/redmine"
# Listen on Both UNIX and TCP Sockets for Testing
listen "/var/www/redmine/tmp/sockets/.sock", :backlog => 64
listen 8080, :tcp_nopush => true
# Default Timeout
timeout 30
# Pid/Logging Config
pid "/var/www/redmine/tmp/pids/unicorn.pid"
stderr_path "/var/www/redmine/log/unicorn.stderr.log"
stdout_path "/var/www/redmine/log/unicorn.stdout.log"
# Preload Rails App for Performance
preload_app true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
This assumes that you unpacked redmine in /var/www/redmine
and that you have a redmine
user belonging to a redmine
group. If needed, change all occurrences of /var/www/redmine
to where you installed Redmine and user "redmine", "redmine"
to the user and group you want Redmine to run as. For testing, I used my user account, but it’s certainly not recommended:
user "olivier", "staff"
Then start unicorn using the wrapper, which means we don’t need to enter the RVM environment. This should come in handy if you use launchd or another service system to launch Redmine:
$ sudo -u redmine redmine_unicorn_rails -c /var/www/redmine/config/unicorn.conf -D -E production
If like me you used your own user account for testing purposes, then you don’t need the sudo
part:
$ redmine_unicorn_rails -c /var/www/redmine/config/unicorn.conf -D -E production
From the config file, Unicorn runs on port 8080. If you have an Apache web site on port 80 and would like Redmine to appear under a given prefix, and have mod_proxy enabled, then you can probably use a proxy rewrite rule to achieve this.
To stop Unicorn, kill the unicorn_rails master
process.
Conclusion
That’s it for today, I hope this helps. As I already mentioned, I am new to Rails applications, so I probably made mistakes. Don’t hesitate to point them out in the comments, I’ll try and update this post accordingly. I might also add something about using launchd to run Redmine under Unicorn and mod_proxy to integrate with an existing web site.