Deploy a rails app to bluehost without SSH

rails on bluehost

I’ve been doing a little free-lance web development again lately. It’s been a while and the landscape’s changed in the 2 or 3 years since I was last freelancing. Specifically the ‘minimum requirements’ for a public facing site and the quality of the ‘cheap’ generic hosts have both increased (for the better). In light of these two factors I’ve been having a go at making some basic ‘web-presence’ sites using ruby on rails.

Learning enough rails to make a simple site was easy enough, but the deployment turned out to be a bit of a puzzle. Particularly as bluehost, whose control panel is otherwise excellent, just doesn’t seem to have its rails story sorted. To make matters worse, every “rails bluehost” tutorial out there starts with “you need SSH access” and bluehost now requires a faxed or emailed copy of the account-holder’s drivers license to grant SSH access. Seeing as my clients are generally the hosting account holders, this wasn’t an option for me.

After a bit of trial and error I’ve discovered that you can indeed deploy a basic Ruby on Rails site to bluehost without SSH access (assuming you have ftp access). Here’s how:

  1. Create rails directory.Use your ftp client to create a directory alongside the {app} directory to which the domain/sub-domain points.I’ve called mine {app}_rails, but it can be called anything.

  2. Upload rails app.Upload your rails app into the newly created {app}_rails directory.

  3. Symlink to rails public directory using temporary PHP.We need to symlink the {app} directory (to which the domain/sub-domain points) to the {app}_rails/public directory. Ordinarily we’d use the trusty ln -s command, but we can also do it without SSH access by using PHP’s symlink function.

    Create a php script on your local machine (I’ve called mine symlink.php) with the following contents (replacing the {account} and {app} tokens with your own). Make sure the {app} directory doesn’t already exist (rename/move/delete it if it does).

    <?php symlink('/home/atfraser/public_html/maketimelapse_rails/public', '/home/atfraser/public_html/maketimelapse'); ?>

    Upload the symlink.php to an accessable directory and then browse to it in your browser. If the script succeeds you’ll be greeted with a blank page (otherwise you’ll get errors). Once run successfully, you can delete the symlink php script (it’s no longer needed).

  4. Ensure dispatch.fcgi exists.To run under apache, a rails app needs fcgi dispatchers. My understanding is that rails 2.3 no longer fcgi dispatchers by default so if you didn’t use the --with-dispatches option when you created your app (I didn’t) you’ll need to create them on your local machine using the following command:

    rake rails:update:generate_dispatchers

    Then upload the created dispatch.fcgi, dispatch.cgi and dispatch.rb files from your localpublic directory to {app}_rails/public directory on bluehost.

  5. Enable dispatch.fcgi in .htaccess.Create a .htaccess file inside your {app}_rails/public directory with the following contents:

    AddHandler fcgid-script .fcgi
    AddHandler cgi-script .cgi

    RewriteEngine On

    RewriteBase /
    RewriteRule ^$ index.html [QSA]
    RewriteRule ^([^.]+)$ $1.html [QSA]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

    ErrorDocument 500 <h2>Application error</h2>Rails application failed to start properly
  6. Check permissions using FTP client.We need to check/set some permissions. Again, we can’t use the standard chmod command without SSH access but luckily most modern ftp clients can also view/set permissions (select the file/directory then ⌘-i in Transmit or ‘right-click > File permissions’ in FileZilla). Set the appopriate permissions for the following files/directories (list courtesy Jack Danger Canty):

    File/Directory Permission
    {app}_rails/public 755
    {app}_rails/public/.htaccess 755
    {app}_rails/public/dispatch.fcgi 755
    {app}_rails/public/dispatch.cgi 755
    {app}_rails/log 775
    {app}_rails/tmp 775
  7. Handling rails gems version issues.If you're app still isn't working, check the error logs in cpanel. It may be that the version of the rails version you built against isn't available on the shared host. In this case,you'll need to either freeze the gems into your app locally (then upload the vendor/gems directory) or comment out the following line in environment.rb which refers to their specific version (risky).

    rake rails:freeze:gems

That should be it!

6 Responses to “Deploy a rails app to bluehost without SSH”


  • thanks for this post. I have SSH access to the my server but found your information useful as the cPanel initiation of a rails app didn’t generate the necessary dispatch.fcgi files. I was stuck banging my head against the wall for about five hours before finding your post. I then generated the files and viola!

    I sent them a bug report and would like to thank you for the time you took to write this article.

    cheers!

    Doug

  • Thanks for this post. I try to make a rails skeleton app work on my web space (Hosteurope WebPack M 3.0). That web pack offers ruby (versions 1.8.7 & 1.9.0, installed in /usr/bin/ruby & /usr/bin/ruby1.9) but not rails. Now I think it should be possible with freezing rails and dependencies to the project’s vendor directory to run the rails application on this Apache 2.2 server. I only have access via FTP.
    Basically I followed the steps provided here apart from 3 (I get a security error in the Apache logs if I try to create a symlink via PHP but I think the symlink is not needed since I already point my web root to the rails_app\public folder via the hoster’s configuration web interface. Btw, am I right here?)
    Also I can create .htaccess files via FTP but it seems they are disobeyed by the server. What I have done is I have registered .fcgi (together with the already present .cgi .pl .py .sh .rb) as recognizable script extensions for every folder using the configuration web interface.
    I am aware of the mod_rewrite directives in .htaccess have to be activated to make the rails app work but is there any way for me to know for sure before I upgrade my WebPack M to L (which has full .htaccess features) my rails app will work then? The hoster says mod_rewrite is availabe then. Is FastCGI always available on today’s Apache? Nevertheless, it should work with only (the slower) CGI, right?
    What I am getting now when I browse my domain is the rails sample app page (“Welcome aboard”) but when I click the “About your application’s environment” link I get error 404 (not found). No log entry is produced in rails_app/logs, all I get is an error line in the Apache log files that says “File does not exist: /is/htdocs/XXX/www/app_rails/public/rails, referer: http://YYY.com/“. I wonder what should exist in ../public/rails or is this error due to a wrong redirection?!

    Any help is greatly appreciated..

  • Update:
    Meanwhile I got a few steps further. Now I am facing the exact error tracked in the Redmine ticket database:

    Defect #4610: undefined method `env_table’ for nil:NilClass (NoMethodError) with rev 3335
    http://www.redmine.org/issues/4610

    There seems to be no solution yet. Since I do not use Redmine I think this problem is not directly connected to Redmine, but rather to rails / active_support itself.

    I strictly have to use CGI for dispatching (no FastCGI available on the web server, as well as no other modules installations are allowed). If anybody has news on how the described issue can be resolved please post.

  • thanks a plenty, would not dispatch before your post, it’s not clear enough in the bluehost page.

  • Where should i enter the “rake rails:update:generate_dispatchers” Comand ???

  • @Balakrishna run the rake command using a shell on your local machine. Assuming you’re using a mac:

    - open Terminal
    - cd to your rails app directory
    - run the command rake rails:update:generate_dispatchers

Leave a Reply