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:

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

Yes this can be but

config.assets.manifest = ‘/path/to/some/other/location’

On Mon, Sep 19, 2011 at 5:17 PM, Peter V.

On Mon, Sep 19, 2011 at 1:19 AM, Alistair Holt
[email protected]wrote:

And the relevant bits of the app dir structure are:

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

This should be expanded to:

/* comment
*= require_self
*= require_tree .
*= require bootstrap
*/

Peter

config.serve_static_assets = true

in production.rb

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

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/.

On Mon, Sep 19, 2011 at 2:23 PM, Rajarshi [email protected] wrote:

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

On Mon, Sep 19, 2011 at 2:10 PM, Alistair Holt
[email protected]wrote:

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

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

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:

On Mon, Sep 19, 2011 at 2:43 PM, Alistair Holt
[email protected]wrote:

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/.

  • 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