How to Add Heroku Buildpacks to Build in Node.js, Ruby on Rails Order

Tadashi Shigeoka ·  Sun, August 27, 2017

I’ll introduce how to add Heroku buildpacks to build in Node.js → Ruby on Rails order.

Heroku

Why Change Buildpack Order? - Background

This time, an error occurred where Webpacker 3 couldn’t be installed due to an old Yarn version.

For Ruby on Rails apps, frontend package management uses yarn by default.

Since yarn tasks don’t depend on Ruby, prioritizing the Node.js (Yarn) buildpack over the Ruby buildpack should eliminate dependency issues like this.

Checking heroku buildpacks

First, use the heroku buildpacks command to check what’s set in the buildpacks.

heroku buildpacks
=== yourapp Buildpack URLs
1. heroku/ruby

Configuring Heroku buildpacks in app.json

Referring to the official documentation at app.json Schema | Heroku Dev Center, simply add “heroku/nodejs” before “heroku/ruby” as follows to complete the configuration:

diff --git a/app.json b/app.json
--- a/app.json
+++ b/app.json
   ],
   "buildpacks": [
     {
+      "url": "heroku/nodejs"
+    },
+    {
       "url": "heroku/ruby"
     }
   ]

Creating Heroku App with Modified buildpacks

Heroku Production app Edition

For Production, do git push heroku master.

git push heroku master

Counting objects: 34, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (34/34), 4.28 KiB | 0 bytes/s, done.
Total 34 (delta 15), reused 1 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Node.js app detected
remote: 
remote: -----> Creating runtime environment
remote:        
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NPM_CONFIG_PRODUCTION=true
remote:        NODE_VERBOSE=false
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote: 
remote: -----> Installing binaries
remote:        engines.node (package.json):  unspecified
remote:        engines.npm (package.json):   unspecified (use default)
remote:        engines.yarn (package.json):  unspecified (use default)
remote:        
remote:        Resolving node version 6.x...
remote:        Downloading and installing node 6.11.2...
remote:        Using default npm version: 3.10.10
remote:        Resolving yarn version (latest)...
remote:        Downloading and installing yarn (0.28.4)...
remote:        Installed yarn 0.28.4
remote: 
remote: -----> Restoring cache
remote:        Skipping cache restore (not-found)
remote: 
remote: -----> Building dependencies
remote:        Installing node modules (yarn.lock)
remote:        yarn install v0.28.4
remote:        [1/4] Resolving packages...
remote:        [2/4] Fetching packages...
remote:        warning [email protected]: The platform "linux" is incompatible with this module.
remote:        info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
remote:        [3/4] Linking dependencies...
remote:        warning "[email protected]" has incorrect peer dependency "ajv@>=5.0.0".
remote:        [4/4] Building fresh packages...
remote:        Done in 28.46s.
remote: 
remote: -----> Caching build
remote:        Clearing previous node cache
remote:        Saving 2 cacheDirectories (default):
remote:        - node_modules
remote:        - bower_components (nothing to cache)
remote: 
remote: -----> Build succeeded!
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.4.1
remote: -----> Installing dependencies using bundler 1.15.2

(Rest omitted)

Heroku Review app Edition

For Heroku Review apps, you could rebuild the app, but to be safe, I deleted it first and then created a new Review App.

Heroku Create Review App

Checking Heroku buildpacks Order

Heroku Buildpacks

From the Heroku app management screen, you can confirm the buildpacks are configured in the following order:

  1. Node.js app detected
  2. Ruby app detected

Adding with heroku buildpacks:add When app.json Doesn't Exist

If there’s no app.json file, add buildpacks using the heroku buildpacks:add command.

heroku buildpacks:add --index 1 heroku/nodejs

Buildpack added. Next release on yourapp will use:
  1. heroku/nodejs
  2. heroku/ruby
Run git push heroku master to create a new release using these buildpacks.

If app.json exists, you need to modify app.json itself, otherwise the buildpack settings won’t be inherited when copying apps with the Heroku Review apps feature from Production app.

In my case, I only did heroku buildpacks:add —index 1 heroku/nodejs first without modifying the buildpacks section in app.json, and the Heroku Review app’s buildpacks remained at the previous settings, which caused me to struggle for about an hour.

When using Heroku, if there’s an app.json file, don’t forget to maintain it.

That’s all from the Gemba.