Rails 3.1 and asset pipeline problems with Apache

Rails 3.1 comes in with hell lot of new features and some of them can be confusing, even for some advanced rails devs. Beside jQuery revolution, introduced CoffeeScript, there is also asset pipeline - a nice, nifty feature (based on sprocets library), that will totally mess up the way, you're creating layouts for your apps. But that's not the topic of this post.

Yesterday I've tried to deploy new version of application for our client. Everything went smooth, without any problems, I've run assets:precompile successfully and hoped, that this will end deploy process. Well, no.

As I've mentioned above, Rails 3.1 is using asset pipeline. And it completelly depends on XSendfile module / headers, so YOU HAVE to remember to include this in your apache / vhost config. And I kinda forgot. Issue was very strange - compiled stylesheets and javascripts were loading just fine, but none of background images defined in styles were loaded. Even, that I was using new helpers (image-url, etc). At this point it started to be very confusing - everything was configured properly, but still something was wrong. After googling for a while, I've found few clues, that combined together will help you create your apache config properly.

  1. 1. First of all - remember to load xsendfile and headers modules
  2. 2. Tell XSendFile module to load itself - put
    XSendFile On
    in vhost config
  3. 3. Enable sending files from parent dirs -
    XSendFileAllowAbove On
  4. 4. Restart your apache server
The most important part of this, is point 3. I really wasn't aware of need for such configuration directive and rails guides did not even provide any clue. I hope that this blog post will help save a lot of time for some people.

Full apache vhost config:

<VirtualHost *:80>
    ServerAdmin admin@galdomedia.pl
    ServerName rails3_1app.wedothestuff.com
    DocumentRoot /var/www/rails3_1app/public
    XSendFile On
    # This does not work for me.
    # XSendFilePath /var/www/rails3_1app/public
    PassengerMinInstances 3
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory /var/www/rails3_1app/public>
        AllowOverride All              
        Options -MultiViews   
        ## THIS IS REALLY IMPORTANT         
        XSendFileAllowAbove on
    </Directory>
    <Directory /var/www/rails3_1app/>
        Options FollowSymLinks 
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>

    ErrorLog /var/log/apache2/rails3_1app.error.log
    LogLevel warn
    CustomLog /var/log/apache2/rails3_1app.access.log combined
        
    <LocationMatch "^/assets/.*$">
        # Some browsers still send conditional-GET requests if there's a
        # Last-Modified header or an ETag header even if they haven't
        # reached the expiry date sent in the Expires header.
        Header unset Last-Modified
        Header unset ETag
        # This required etag module to be enabled. Comment out
        FileETag None
        # RFC says only cache for 1 year
        ExpiresActive On
        ExpiresDefault "access plus 1 year"
    </LocationMatch>

</VirtualHost>

blog comments powered by Disqus

Fork me on Github And spread the word!