3.1 asset pipeline + Capistrano troubles

Hello,

I’m having a bit of trouble with the asset pipeline and, I think, Capistrano.

In my app layout I have:

<%= stylesheet_link_tag “application”, “bootstrap” %>

And the relevant bits of the app dir structure are:

app/assets/stylesheets/application.css.scss # Contains ‘require_self’ and ‘require_tree .’ as usual

vendor/assets/stylesheets/bootstrap.css

I’m using Capistrano’s asset pipeline support (load ‘deploy/assets’) in my Capfile. When I’m deploying the app using cap deploy it’s precompiling the assets correctly and copying them into the shared/assets directory for the app on the server.

The problem seems to be that the bootstrap.css file is plain old CSS so it doesn’t get compiled (obviously) but this means that it doesn’t end up in the shared/assets directory (which is symlinked to public/assets in the app directory). Maybe there’s something I’m missing as I’m still getting to grips with the asset pipeline. Anyway, there’s no problem with this locally - I’ve tested with asset compression enabled - but then it’s not the same setup that we end up with on Capistrano deploys.

Anyone have any ideas?

Thanks

Check out the guide on pre-compiling:

http://guides.rubyonrails.org/asset_pipeline.html#precompiling-assets

The default matcher for compiling files includes application.js, application.css and all files that do not end in js or css

If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the precompile array:

config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']

Thanks to you

This should be expanded to:

/* comment

*= require_self

*= require_tree .

*= require bootstrap

*/

Peter

Yes this can be but

config.assets.manifest = '/path/to/some/other/location'

Thanks Tim. Perhaps theres something I’m missing…

  • Do plain CSS/JS files need to go through pre-compilation? And if so, do they really have to be manually specified in application config?
  • Shouldn’t Rails’ stylesheet_link_tag helper be looking in /vendor/assets/stylesheets as well as public/assets/stylesheets? The error I get in production is: ActionView::Template::Error (bootstrap.css isn’t precompiled)

Surely bootstrap.css will never be precompiled and end up in public/assets if it’s just plain old CSS?

Thanks again

config.serve_static_assets = true

in production.rb

I think this is a really bad idea. With this setting, the assets are served

from the rails server (running ruby code) while these are static files

(with cache buster names) that can be server much more efficiently

directly by the web server from the public/assets/ file system.

From:

http://spreecommerce.com/documentation/server_configuration.html

"…config.serve_static_assets = true

There is a good reason why this is disabled by default in Rails which is that Rails is not a general purpose web server. Servers such as Apache and Nginx are optimized for rapidly serving up static content. You should consider the advice of the Rails core team and let your webserver do what it does best (as described in the next section.) "

Peter

Agreed. I must say this is extremely confusing. There seem to be no decent explanations in the docs or anywhere else. Why would config.serve_static_assets need changing to be true when we are told “Apache or nginx will already do this”? Should I actually be setting up Nginx to serve the files in the vendor/assets directory? I don’t know how this would work when the helper appears to believe it’s going to find bootstrap.css in public/assets/.

If you include the bootstrap in .css form (e.g. from arunagw/css-bootstrap-rails as I have done),

It is not “precompiled” in the sense of LESS, but there is some processing in that the

bootstrap.css is joined with my customer .css and some whitespace is removed in a single file:

application-c77014c7bfe7a5dbbc172cd8a685b53a.css

So for the aspect of removing the number of asset files, there is certainly some processing

that is done.

Peter

  • Adding “*= require bootstrap” to app/assets/stylesheets/application.css.scss

  • making sure precompilation (bundle exec rake asset:precompile) happens

at the time of deployment

will produce a single application-cache-buster.css file in publis/assets/ where the

web server expects to find it.

As a simple reference, this is the commit where I activated bootstrap working with the

asset pipeline:

https://github.com/petervandenabeele/base_app/commit/d866a356abb8d07d9d782065573272a6ce45c981

HTH,

Peter

If you have config.assets.compile set to true (typical for development) the stylesheet_link_tag will attempt to look in your app/assets directory and compile the css file if necessary. But the stylesheet_link_tag doesn’t look outside public/assets in when config.assets.compile is set to false (which is typical for production). Actually, it reads from the manifest.yml to determine which file path to return.

When an asset is precompiled, it gets put into the public/assets directory and an entry is put in manifest.yml like so:

application.css: application-ccb8034635849c44627859332fda6a01.css

When you use stylesheet_link_tag(“application”) in production, it checks to see if an entry exists in manifest.yml with that name. if so, it returns the hashed filename specified in the manifest. Otherwise it would just return the unhashed file name like “assets/application.css”

So one option is to add bootstrap.css to config.assets.precompile. This will in fact send it through the pipeline and dump it in public/assets with the name bootstrap-digest.css and put an entry in manifest.yml.

However, plain CSS files don’t really *need *to be pre-compiled since they don’t contain SASS/ERB. If it doesn’t need to be compiled, you can just put them directly in public/assets without adding it to config.assets.precompile and you’re done.

So to sum it up: in production, all assets need to be under public/assets. How they get there depends on whether they need to be pre-processed or not.

Hopefully that’s not too confusing. It sounds complicated but once you understand what’s going on it’s really kind of nifty.

Thanks Tim - that has definitely cleared it up in my mind. It’s a shame it’s not explained like this in the Rails guide. I never had this much trouble when I was just using Jammit before Rails 3.1 :slight_smile: