Close and Go BackBack to Viget

RubyInline in Shared Rails Environments

David Eisinger
David Eisinger, Web Developer, May 23, 2008 11

As an end-to-end web production company, we have a vested interest in making Rails applications easier to deploy for both development and production purposes. We’ve developed Tyrant, a Rails app for running Rails apps, and we’re eagerly watching as new solutions are created and refined.

But it’s a new market, and current solutions are not without their share of obstacles. In working with both Tyrant and Phusion Passenger, we’ve encountered difficulties running applications that use RubyInline to embed C into Ruby code (e.g., ImageScience, my image processing library of choice). Try to start up an app that uses RubyInline code in a shared environment, and you might encounter the following error:

/Library/Ruby/Gems/1.8/gems/RubyInline-3.6.7/lib/inline.rb:325:in `mkdir':
Permission denied - /home/users/www-data/.ruby_inline (Errno::EACCES)

RubyInline uses the home directory of the user who started the server to compile the inline code; problems occur when the current process is owned by a different user. “Simple,” you think. “I’ll just open that directory up to everybody.” Not so fast, hotshot. Try to start the app again, and you get the following:

/home/users/www-data/.ruby_inline is insecure (40777). It may not be group or world writable. Exiting.

Curses! Fortunately, VigetExtend is here to help. Drop this into your environment-specific config file:

temp = Tempfile.new('ruby_inline', '/tmp')
dir = temp.path
temp.delete
Dir.mkdir(dir, 0755)
ENV['INLINEDIR'] = dir

We use the Tempfile library to generate a guaranteed-unique filename in the /tmp directory, prepended with “ruby_inline.” After storing the filename, we delete the tempfile and create a directory with the proper permissions in its place. We then store the directory path in the INLINEDIR environment variable, so that RubyInline knows to use it to compile.

Clinton R. Nixon said on 05/23 at 02:46 PM

I ran into this exact same problem today while using monit to monitor Mongrel processes. Monit doesn’t run in a shell environment, and so you don’t have ENV[’HOME’] or ENV[’INLINEDIR’] set when you start Mongrels. This tip got me working again.

Zach Hale said on 05/26 at 12:41 PM

I ran into this a few days ago while trying to move an application to a new Passenger setup and kept getting random errors I couldn’t debug. I had a feeling it had something to do with ruby_inline and this did the trick!

Thanks!

Jose said on 07/27 at 10:33 PM

Thanks a lot for this tip...when I saw the log I was scratching my head so hard…

Jose said on 07/27 at 11:12 PM

After using this patch I got another error surprisingly, go here to read about it:
http://groups.google.com/group/attachment_fu/t/bf52c81006f163e4

Patrick Reagan said on 07/28 at 08:36 AM

@Jose: This may seem obvious, but have you confirmed that the path exists and is writable by the user that Apache is running as (e.g. www)?  It’s quite possible that the ‘tmp’ directory is there but that ‘attachment_fu’ was missing in the deployment (especially if you’re using git for SCM).

Jose said on 07/28 at 08:37 PM

What I did was to make all directories inside my RAILS_ROOT (including it) and “/www” to be managed by root:root and I’m still getting the same error. I only have one user which is root, I deployed my app with Passenger using root user, now how can I see which user is running Apache? My httpd.conf file is empty by the way.

Any thoughts? How would be a good way to redeploy? by the way I’m just uploading my files, I’m not using a SCM. :S

Patrick Reagan said on 07/29 at 08:08 AM

@Jose: Try running ‘ps aux | grep -e [a]pache -e [h]ttpd’ and check the leftmost column to see which user your Apache process is running as.  You’ll need to make sure that ‘tmp/attachment_fu’ under your RAILS_ROOT directory is writable by this user.  The easiest, but not necessarily the best, way to make sure this is the case is to make that directory world-writable.

As for deployment, I’d recommend using an SCM (either git or Subversion) and Capistrano to automate the process for you.  You’ll thank yourself later.

Jose said on 07/29 at 09:01 PM

@Patrick: It worked! Thanks a lot really, thank you for your time and patience.

Patrick Reagan said on 07/29 at 09:04 PM

@Jose: My pleasure - I’ve been there before, so I’m happy to help out.  I’m glad that both David and myself could help you get your app running smoothly.

Take care.

Valentin P said on 08/05 at 01:35 PM

You are a god among men. I’ve spent the past 18 hours trying to get damn image_science to work with passenger. THANK YOU<3

PabloC said on 08/18 at 12:58 PM

Thanks! This fixed my problem too.

Trackback URL: http://www.viget.com/trackback/1130/

Comments for this entry were closed after 60 days.

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I think that polymorphic_url(@commentable, :anchor => “comment_#{@comment.id}") should work. You can also refactor the “comment_#{@comment.id}” to a separated method, like dom_id, which returns the dom identifier of the comment.