Deploying Redmine 1.4.1 in a Cpanel Shared Hosting Environment

If you run a low volume website, your best value will be shared hosting and the odds are that it will use Cpanel for management. Consider this website, which I host, along with a few others for 2.99 USD per month. My hosting package includes a plethora of features, all of which I can use little to no knowledge of running a webserver. However, effectively using these technology as an experienced user can be a bit more challenging.

I recently deployed a Ruby on Rails application (Redmine) for a website I host. My hosting provider supports Ruby on Rails, but cpanel management makes the deployment workflow a bit different from a dedicated host. When I upgraded to the latest Redmine (1.4.1), I ran into further problems, but I eventually got it working.

The tips in this article were derived from my experience with Redmine, but should apply well beyond just Redmine to any Ruby on Rails application.

To get started, Cpanel provides a Ruby on Rails item in the control panel, allowing you to create a new rails application. Creating an application through this interface will populate ~/rails_apps with a new subdirectory containing your app. This will be a fresh Rails app, but this can be easily deleted and replaced with your own. Note that this process is necessary because it sets up other infrastructure to make it possible to run your Rails app.

Ruby Gems

Your shared hosting provider should provide a system-wide installation of some common Ruby gems needed for Rails deployment. These can be critical because you likely won’t be able to compile native extensions like mysql yourself.

To add additional gems, you’ll be provided a ~/ruby/gems directory. There is a cpanel interface for this, but you’re better off using the command line via ssh. To install a new gem, you’ll need to set up your environment:

$ export PATH=$PATH:~/ruby/gems/bin
$ export GEM_HOME=~/ruby/gems

At this point, you will be able to install gems as normal with the gem command. If you don’t set GEM_HOME, you’ll end up trying to install gems into the system path, which won’t go well.

Working with Bundler

Redmine 1.4.1 switched to using Bundler, which initially made deployment trickier than prior versions. Bundler is intended to make things easier for developers, but it can try to force you to install gems you cannot use. In a shared environment, you are unlikely to be able to build native extensions because of a lack of build tools or development libraries. For native extensions that are required, you’ll need to ask your hosting provider to install it at a system level. For Redmine, this is probably the mysql gem.

Redmine is capable of using other database systems like postresql or sqlite, but it doesn’t require them. If you run bundler as specified, you’ll end up trying to build and install these gems. Fortunately, there is an option to exclude specific gems. For my environment, I used the following command:

$ bundle install --without development test postgresql sqlite rmagick

This command removed development and test requires as recommended by the documentation. It also removes unneeded database gems and the optional rmagick gem. Keep in mind, you ultimately need certain gems to run the application, so this mechanism is only suitable for exlcuding optional gems. If I excluded mysql, for example, I wouldn’t be able to connect to the database, and Redmine would not run.

Starting and Stopping the App

You’ll need to start the app via the cpanel Ruby on Rails control panel. This will start an instance of mongrel and your app will be accessible via some high-numbered port (e.g. 12001). Each app will be deployed in a separate mongrel instance on a different port. If the app does not start, you’ll need to check the mongrel log in ~/rails_apps/<app>/log/mongrel.log

You may find that the control panel gets out of sync with mongrel sometimes and you won’t be able to stop your rails app. In this case, you can check the ~/rails_apps/<app>/log/mongrel.pid and kill this process. Alternatively, search for the mongrel process manually:

$ ps aux | grep mongrel

username 1234 0.1 1.1 228588 136644 ? S 00:51 1:41 /usr/bin/ruby /usr/bin/mongrel_rails start -p 12003 -d -e production -P log/mongrel.pid

You can also delete mongrel.pid to force the control panel to show it in the stopped state.

Gem Environment

When you work with gems on the command line, you can set the environment as needed. When Cpanel launches mongrel, however, you have no control over the environment in which it is launched. To set up the environment, you can override the GEM_HOME variable in config/environment.rb:

ENV['GEM_HOME'] = '/home/<user>/ruby/gems'

Note: if you use a string literal for the path, you’ll need a fully expanded path, as Ruby will not interpolate ~ to your home directory.

With Redmine 1.4.1, I found that this no longer worked. Redmine had switched to Bundler for gem management. Without bothering to understand all the details, I found a workaround that will reload rubygems with the correct environment:

ENV['GEM_PATH']= "/home/<user>/ruby/gems"

require 'rubygems'; Gem.clear_paths;
Gem.instance_variable_set(:@searcher, nil)

For Redmine, I found that config/preinitializer.rb was actually loaded before this, and so I added this code prior to require 'rubygems' in that file.

If you don’t do this correctly, you’ll see entries in mongrel.log indicating that bundler is required:

Redmine requires Bundler. Please install it with gem install bundler.
** Daemonized, any open files are closed. Look at log/mongrel.pid and log/mongrel.log for info.
** Starting Mongrel listening at 0.0.0.0:12001
** Starting Rails with production environment...

If you are still having trouble, make sure you do a sanity test with your environment set in the shell. You can start the ruby interpreter (irb) and run require "rubygems"; require "bundler" to verify they load correctly.

Running Rake Tasks

If you’re lucky, you’ll be able to run the required rake commands on your host. Unfortunately, I wasn’t so lucky with my hosting provider as they appear to enable fork bomb protection in cpanel. The result is a segmentation fault and a stack trace that will give you little clue as to what is going on.

To work around this, you can set up a local environment to run the rake tasks. I used rvm to install the same version of ruby as on my hosting provider on a Linux vm. This method is quite useful as it will let you create multiple Ruby environments to meet your needs without cluttering your system installation.

Use of rvm is fairly self-explanation. Just follow the instructions on the rvm website to install your ruby version:

$ curl -L get.rvm.io | bash -s stable
$ source ~/.rvm/scripts/'rvm'
$ rvm install 1.8.7

At this point, you have a fresh ruby installation and it will be activated in your path. You can install Redmine again on your local system. Then, run your database migrations locally after modifying your config/database.yml to point to your remote host. You can allow remote access (restricted to your IP) from the Mysql cpanel pages.

This entry was posted in web and tagged , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

13 Comments

  1. Luc
    Posted April 23, 2012 at 6:16 pm | Permalink

    Hi, and a big thank you for your post
    I would have saved me hours if onlyI had seen it fews days before :(
    BTW, Im’ trying to succeed in my Redmine application on my hoster cpanel environnement. But I’m stuck despite of your advices. My Mongrel log is still showing:

    ** Starting Mongrel listening at 0.0.0.0:12002
    ** Starting Rails with production environment…
    Some gems may need to be installed or updated.
    Please run `bundle install –without development test`.

    from the irb interpreter, require “rubygems” return ‘false’ and require “bundler” return true.

    What can I do?

    Cheers,

    luc

    • Posted April 23, 2012 at 10:45 pm | Permalink

      It looks like a false return to `require “rubygems”` indicates that it has already been loaded. I’m not sure why that would be the case when you run irb.

      Have you followed the normal installation instructions for redmine? You need to install the required gems via bundler, with the command indicated. One thing I omitted in my post is that you can exclude additional gems that you don’t want to or can’t build in your environment. So, for example, I installed the required gems via:

      bundle install –without development test postgresql sqlite rmagick

      • Luc
        Posted April 24, 2012 at 2:53 am | Permalink

        Yes I’ve followed the normal installation instructions. I had some problems at the beginning with the “bundle” command, due to GEM_PATH/GEM_HOME variables, but I finally fixed it and the bundle install was ok.

  2. Luc
    Posted April 24, 2012 at 3:25 am | Permalink

    For information, I’ve no “config/preinitialization.rb” file but I have a “config/preinitializatier.rb” file.
    I’ve added the following code into both “config/preinitializatier.rb” and “config/environment.rb” files (in top of files):

    ENV[‘GEM_PATH’]= “/home//ruby/gems”
    require ‘rubygems'; Gem.clear_paths;
    Gem.instance_variable_set(:@searcher, nil)

    is that ok?

    • Posted April 25, 2012 at 3:11 am | Permalink

      That looks about right, assuming you set GEM_PATH correctly. Here’s an exact snippet from my config/preinitializer.rb:

      begin
      ENV[‘GEM_PATH’] = ‘/home//ruby/gems’
      require “rubygems”; Gem.clear_paths;
      Gem.instance_variable_set(:@searcher, nil)
      require “rubygems”
      require “bundler”
      rescue LoadError
      $stderr.puts “Redmine requires Bundler. Please install it with `gem install bundler`.”
      exit 1
      end

      The second require “rubygems” is redundant, but I didn’t try removing it.

  3. Luc
    Posted April 24, 2012 at 11:06 am | Permalink

    Note: read ENV[‘GEM_PATH’]= “/home//ruby/gems” above

  4. afatac
    Posted August 21, 2012 at 9:32 am | Permalink

    Hi,

    Currently, I am trying out to install Redmine (and Chiliproject) in a cPanel shared hosting server. I always get stuck at this command

    RAILS_ENV=production bundle exec rake db:migrate
    or
    RAILS_ENV=production rake db:migrate

    The returned message is

    /home//ruby/gems/gems/i18n-0.4.2/lib/i18n/core_ext/string/interpolate.rb:90: [BUG] Segmentation fault
    ruby 1.8.7 (2011-02-18 patchlevel 334) [x86_64-linux]

    Do you have any idea what has gone wrong?

    All the required gems are installed successfully in /home//ruby/gems using command
    bundle install –without development test postgresql sqlite

    • Posted August 22, 2012 at 9:36 pm | Permalink

      I believe this is caused by forkbomb protection in cpanel. You won’t be able to change this unless you can administrate cpanel (WHM) or contact your hosting provider. I had the same problem, and so I replicated the ruby environment in a local linux vm and did the db migration there, as I described. It’s a big pain, but it works.

  5. afatac
    Posted August 27, 2012 at 11:08 am | Permalink

    Hi Dan,

    Thanks for the reply. After I had made the previous post, I install rvm and reinstall Redmine 2.0.3. With some helps from the web hosting company on executing step 6 and 7 (http://www.redmine.org/projects/redmine/wiki/RedmineInstall#Installation-procedure), I come to the stage of starting Redmine in cPanel.

    Before starting Redmine, I inserted the following codes as the first 3 lines in config/environment.rb

    ENV[‘GEM_PATH’]= “~/.rvm/gems/ruby-1.9.2-p320″
    require ‘rubygems'; Gem.clear_paths;
    Gem.instance_variable_set(:@searcher, nil)

    However, Redmine cannot be started in cPanel. I look into redmine/log/mongrel.log.

    ** Daemonized, any open files are closed. Look at log/mongrel.pid and log/mongrel.log for info.
    ** Starting Mongrel listening at 0.0.0.0:12002
    ** Starting Rails with production environment…
    /usr/lib/ruby/gems/1.8/gems/bundler-1.1.5/lib/bundler/dsl.rb:12:in `evaluate': There was an error in your Gemfile, and Bundler cannot continue. (Bundler::GemfileError)
    from /usr/lib/ruby/gems/1.8/gems/bundler-1.1.5/lib/bundler/definition.rb:18:in `build’
    from /usr/lib/ruby/gems/1.8/gems/bundler-1.1.5/lib/bundler.rb:135:in `definition’
    from /usr/lib/ruby/gems/1.8/gems/bundler-1.1.5/lib/bundler.rb:123:in `load’
    .
    .
    .

    It seems that gems path is not pointing to what I have defined in environment.rb

    Any suggestion?

    • Posted August 28, 2012 at 1:57 am | Permalink

      Before we dive into the details, I’m not sure that cpanel supports Rails 3 (or of it does, it is only in very recent versions). So, you may be headed down the wrong direction with Redmine 2.x. You may want to try 1.4 first.

      Secondly, your GEM_PATH implies you are trying to use ruby 1.9.2 (assuming it is correct), but mongrel is using 1.8 gems. Do you have a ruby 1.9.2 binary that you can get cpanel to run? I’m not sure if it uses your local user PATH? Since you added your local directory last, it is going to find the system ruby first. You need to add ~/bin to the beginning of PATH.

      This is a good bit beyond what I suggested in my post. The way cpanel works to run rails apps is a bit opaque to me, so I don’t really know how to debug this. My suggestion was to replicate the ruby environment on a local system (in my case, ruby 1.8.7), using rvm, and execute db commands over the network to your remote mysql database.

  6. afatac
    Posted August 27, 2012 at 11:28 am | Permalink

    I am not sure if this is helpful. Here are the codes in .bashrc and .bash_profile

    ======================================
    # .bashrc

    # Source global definitions
    if [ -f /etc/bashrc ]; then
    . /etc/bashrc
    fi

    # User specific aliases and functions

    export GEM_HOME=~/.rvm/gems/ruby-1.9.2-p320
    export GEM_PATH=~/.rvm/gems/ruby-1.9.2-p320:~/.rvm/gems/ruby-1.9.2-p320@global

    export PATH=$PATH:~/.rvm/bin # Add RVM to PATH for scripting
    ========================================

    ========================================
    # .bash_profile

    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
    . ~/.bashrc
    fi

    # User specific environment and startup programs

    PATH=$PATH:~/bin

    export PATH

    [[ -s “~/.rvm/scripts/rvm” ]] && source “~/.rvm/scripts/rvm” # Load RVM into a shell session *as a function*
    ========================================

  7. Posted February 7, 2013 at 2:15 am | Permalink

    I still have a problem to install redmine on a cpanel environment. I don’t have SSH (Shell) available. Do you think it’s possible to install redmine on such an environment. ruby on rails is available.

    Greetings

    • Posted February 7, 2013 at 7:29 pm | Permalink

      While perhaps it could be possible, I doubt it is worth trying. You’d need to install ruby gems via cpanel and then run all commands remotely as I described in the article. This would allow you to do the database migration and other tasks. The procedure above is already convoluted enough, but good luck if you want to try :)

      I would suggest you check whether your provider can give ssh access, or look for another provider. There is no shortage of hosts that will provide the access you need. My hosting service, for example, allows ssh access after a one-time $1 fee.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>