Heroku + Rails + Bower
1. Install nodejs and npm
I like to use nvm by creationix.
2. Install Bower
Make sure to install Bower into your projects local node_modules. This is a best practice encouraged by Heroku. You should add node_modules to source control.
npm install bower
3. Using .bowerrc
tell Bower to install all assets into vendor/assets/components
:
{
"directory": "vendor/assets/components"
}
4. In application.rb
tell Rails to add vendor/assets/components
to the precompile load path:
config.assets.paths << Rails.root.join('vendor', 'assets', 'components')
5. Added vendor/assets/components
to .gitignore
6. Create a bower.json
file and add your dependencies:
{
"name": "my-project",
"dependencies": {
"bootstrap": "~> 3.0"
}
}
7. Install dependencies using Bower:
bower install
8. Add your dependencies to your Rails asset manifest files:
// app/assets/javascripts/application.js
//
// ...
//= require bootstrap
// ...
/* app/assets/stylesheets/application.css
*
* ...
*= require bootstrap
* ...
*/
9. Register the extensions for the files that are meant to be precompiled in application.rb
:
# via https://gist.github.com/afeld/5704079
# We don't want the default of everything that isn't js or css, because it pulls too many things in
config.assets.precompile.shift
# Explicitly register the extensions we are interested in compiling
config.assets.precompile.push(Proc.new do |path|
File.extname(path).in? [
'.html', '.erb', '.haml', # Templates
'.png', '.gif', '.jpg', '.jpeg', '.svg', # Images
'.eot', '.otf', '.svc', '.woff', '.ttf', # Fonts
]
end)
Note that I usually take out the template extensions. These generally compile things my app doesn't need from frontend dependencies. To each their own.
10. Make sure your assets precompile locally:
$ RAILS_ENV=production rake assets:precompile -v
11. Configure Heroku to use ddollar's multi-buildpack:
$ heroku config:add BUILDPACK_URL=https://github.com/ddollar/heroku-buildpack-multi.git
12. Add the heroku-nodejs buildpack and heroku-ruby buildpack to .buildpacks
:
$ cat .buildpacks
https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-ruby
Make sure that the ruby buildpack is the last one in the list. This will allow you to access the Rails console when running heroku run console
.
13. Create package.json
:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"bower": "~1.2"
},
"engine": {
"node": "0.10.x",
"npm": "1.3.x"
},
"scripts": {
"postinstall": "./node_modules/bower/bin/bower install"
}
}
Note that the dependencies
option is where you will add all your nodejs dependencies. Heroku will run npm install
on deploy.
Also note the postinstall script. This will tell Bower to pull down your assets. This is important otherwise your rake assets:precompile
won't have anything to compile.
14. Push to Heroku
git push heroku master
15. Sit back and marvel at how you will never have to manually manage your frontend dependencies again.
Written by Anthony Smith
Related protips
13 Responses
For the postinstall script, are you relying on the bower binary being present globally in the Heroku environment or should this be pointing to the binary in node_modules?
Agree with @hasghari - the postinstall component should be something like:
"postinstall": "./node_modules/bower/bin/bower install"
Thanks for the heads up. Fixed.
Hi Anthony, thanks for sharing this useful tutorial.
I encountered a nasty error on Heroku (and according to Google I'm not the only one) : glyphicons not showing up (404s)
I had to update my application.css with this gist https://gist.github.com/EtienneDepaulis/9089678 (which is based on this solution http://rvg.me/2013/11/using-bootstrap-3-with-rails-4/)
How did you managed this on your side ?
I hope it can help others :)
@etiennedepaulis That's actually a really good question. The solutions you provided are similar to what I use.
@font-face {
font-family: 'FontAwesome';
src: font-url('components-font-awesome/fonts/fontawesome-webfont.eot?v=4.0.3');
src: font-url('components-font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.0.3') format('embedded-opentype'),
font-url('components-font-awesome/fonts/fontawesome-webfont.woff?v=4.0.3') format('woff'),
font-url('components-font-awesome/fonts/fontawesome-webfont.ttf?v=4.0.3') format('truetype'),
font-url('components-font-awesome/fonts/fontawesome-webfont.svg?v=4.0.3#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
Thanks for this material!
@amedr Looks awesome! Does it work with Heroku?
I can confirm this works with Dokku 0.2.3, but there are two things that need to be changed before pushing to Dokku.
- Create a
.npmrc
file withunsafe-perm = true
- Change the
package.json
post-install script to run this command instead:./node_modules/bower/bin/bower install --allow-root
This is due to Dokku using Docker containers with root users to run the apps.
This can help, if you need to populate your dev environment with multiple ENV variables before doing a production rake
export $(cat .env | xargs) && RAILS_ENV=production && rake assets:precompile -v
the export $(cat .env | xargs)
will do the populating
Locally precompiling doesn't work. It may be that file size is too large. No solutions on so or readme.
Thanks for the article, it solved my Elixir with Brunch deployment problem (the multi-buildpack hint did it). I found a typo in your package.json, "engine" should read "engines"...
Thank you!
Just amazing article!