Last Updated: May 15, 2019
·
15.46K
· anthonator

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.

13 Responses
Add your response

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?

over 1 year ago ·

Agree with @hasghari - the postinstall component should be something like:

"postinstall": "./node_modules/bower/bin/bower install"

over 1 year ago ·

Thanks for the heads up. Fixed.

over 1 year ago ·

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 :)

over 1 year ago ·

@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;
}
over 1 year ago ·

Thanks for this material!

over 1 year ago ·

@amedr Looks awesome! Does it work with Heroku?

over 1 year ago ·

I can confirm this works with Dokku 0.2.3, but there are two things that need to be changed before pushing to Dokku.

  1. Create a .npmrc file with unsafe-perm = true
  2. 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.

over 1 year ago ·

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

over 1 year ago ·

Locally precompiling doesn't work. It may be that file size is too large. No solutions on so or readme.

over 1 year ago ·

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

over 1 year ago ·

Thank you!

over 1 year ago ·

Just amazing article!

over 1 year ago ·