I ran across an issue in production recently where my Rails app assets weren’t being served correctly through the Asset Pipeline. It brought back to my attention the fact that I didn’t really understand how all of the Asset-Pipeline-related configuration settings work together.
I got so frustrated that I decided to write out a truth table and test out all possible combinations, and I’d like to share my findings. Hopefully this will help you better understand error messages you may receive, and maybe even show you a setup you’d like to use.
Here’s the tl;dr for if you’re getting a certain error:
- If you’re getting a 404 for assets at an
/assets/path, make sure you have
config.serve_static_files = true, or that you are running inside a web server that will serve these files.
- If you’re getting a 404 for assets at a
config.assets_compile = false), and some other settings are incorrect. If you want assets to be precompiled, make sure all your settings match row 6 above.
Here are the settings I investigated:
config.assets.compile: allows Rails to generate assets at runtime.
config.assets.debug: disables concatenating files, instead creating separate
<script>tags for each.
config.assets.digest: appends fingerprints to asset URLs to bust cache.
config.serve_static_files: allows Rails to serve up files in
/public/, including precompiled assets.
rake assets:precompile: generates assets at build time and stores them in
Here are the effects of enabling and disabling these settings in different combinations, as to whether the asset loads (HTTP status 200) or can’t be found (404):
A few observations:
- If you have
config.assets.compile = true, every other combination of settings works.
rake assets:precompiledon’t make a difference because the application will always fall back to compiling the assets on the fly. But you can change
config.assets.digestto control concatenation and fingerprinting, respectively.
- If you have
config.assets.compile = false, there are only two combinations of settings that work.
config.assets.debugmust be set to
config.assets.digestmust be set to
true, and you must run
rake assets:precompile. Your setting for
config.serve_static_filesis the only one that can vary, and the setting you want depends on how you’re running Rails. If it’s running behind a web server like Apache or Nginx, you can set
config.serve_static_filesto false, because the web server will serve up those files. If Rails is not running behind a web server, you will need to set
config.serve_static_filesto true, so that Rails will serve these files.
- Note that Heroku precompiles your assets if it doesn’t already see the compiled assets committed to Git. If you move off of Heroku to another host, you may need to start precompiling yourself.
If you’ve seen the Asset Pipeline behave differently or there’s another setting I should be testing against, let me know!