Superpatterns Pat Patterson on the Cloud, Identity and Single Malt Scotch

15Nov/1113

Running Your Own Node.js Version on Heroku

UPDATE (3/3/12) - there's a much easier way of doing this now - see 'Specifying a version of Node.js / npm' in the Heroku Dev Center. The mechanism described below still works, but you should only go to all this trouble if you want something really custom.

Here's a completely unofficial, unsupported recipe for running your own Node.js version on Heroku. These instructions are based on those at the Heroku Node.js Buildpack repository, with some extra steps that I found were necessary to make the process work. Note that buildpack support at Heroku is still evolving and the process will likely change over time. Please leave a comment if you try the instructions here and they don't work - I'll do my best to keep them up to date.

Before you start, update the heroku gem, so it recognizes the --buildpack option:

gem update heroku

(Thanks to 'tester' for leaving a comment reminding me that using an out of date heroku gem can result in the error message ! Name must start with a letter and can only contain lowercase letters, numbers, and dashes.)

Note: If you just want to try out a completely unofficial, unsupported Node.js 0.6.1 on Heroku, just create your app with my buildpack repository:

$ heroku create --stack cedar --buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git

Otherwise, read on to learn how to create your very own buildpack...

First, you'll need to fork https://github.com/heroku/heroku-buildpack-nodejs. Now, before you follow the instructions in the README to create a custom Node.js buildpack, you'll have to create a build server (running on Heroku, of course!) with vulcan and make it available to the buildpack scripts. You'll have to choose a name for your build server that's not already in use by another Heroku app. If vulcan create responds with 'Name is already taken', just pick another name.

$ gem install vulcan
$ vulcan create YOUR-BUILD-SERVER-NAME

Now you can create your buildpack. You'll need to set up environment variables for working with S3:

$ export AWS_ID=YOUR-AWS-ID AWS_SECRET=YOUR-AWS-SECRET S3_BUCKET=AN-S3-BUCKET-NAME

Create an S3 bucket to hold your buildpack. I used the S3 console, but, if you have the command line tools installed, you can use them instead.

Next you'll need to package Node.js and NPM for use on Heroku. I used the current latest, greatest version of Node.js, 0.6.1, and NPM, 1.0.105:

$ support/package_node 0.6.1
$ support/package_npm 1.0.105

Open bin/compile in your editor, and update the following lines:

NODE_VERSION="0.6.1"
NPM_VERSION="1.0.105"
S3_BUCKET=AN-S3-BUCKET-NAME

Now commit your changes and push the file back to GitHub:

$ git commit -am "Update Node.js to 0.6.1, NPM to 1.0.105"
$ git push

You can now create a Heroku app using your custom buildpack. You'll also need to specify the Cedar stack:

$ heroku create --stack cedar --buildpack http://github.com/YOUR-GITHUB-ID/heroku-buildpack-nodejs.git

When you push your app to Heroku, you should see the custom buildpack in action:

$ cd ../node-example/
$ git push heroku master
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (11/11), 4.02 KiB, done.
Total 11 (delta 1), reused 0 (delta 0)

-----> Heroku receiving push
-----> Fetching custom build pack... done
-----> Node.js app detected
-----> Fetching Node.js binaries
-----> Vendoring node 0.6.1
-----> Installing dependencies with npm 1.0.105

Dependencies installed
-----> Discovering process types
Procfile declares types -> web
-----> Compiled slug size is 3.3MB
-----> Launching... done, v6
http://strong-galaxy-8791.herokuapp.com deployed to Heroku

To git@heroku.com:strong-galaxy-8791.git
cd3c0e2..33fdd7a  master -> master
$ curl http://strong-galaxy-8791.herokuapp.com
Hello from Node.js v0.6.1

w00t!

Note: Due to an incompatibility between the default BSD tar on my Mac and GNU tar on Heroku, I saw many warnings while pushing my Node.js app to Heroku, of the form

tar: Ignoring unknown extended header keyword `SCHILY.dev'
tar: Ignoring unknown extended header keyword `SCHILY.ino'
tar: Ignoring unknown extended header keyword `SCHILY.nlink'

These are annoying, but benign - the push completes successfully. If you're on a Mac and you want to get rid of them, add the line

alias tar=gnutar

just after the opening #!/bin/sh in both package scripts.

Comments (13) Trackbacks (1)
  1. I have problem in this line. I am pretty stuck. Could you give me a hand?

    heroku create –stack cedar –buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git
    ! Name must start with a letter and can only contain lowercase letters, numbers, and dashes

    Then I added a name here
    heroku create –stack cedar MYAPP –buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git

    This just create an blank nodejs app for me.

    But when I compile it, It doesnt show node is in the right version
    —–> Heroku receiving push
    —–> Node.js app detected
    —–> Fetching Node.js binaries
    —–> Vendoring node 0.4.7
    —–> Installing dependencies with npm 1.0.94
    express@2.2.0 ./node_modules/express
    ├── qs@0.3.2
    ├── mime@1.2.4
    └── connect@1.7.3
    Dependencies installed
    —–> Discovering process types
    Procfile declares types -> web
    —–> Compiled slug size is 3.2MB
    —–> Launching… done, v3

  2. Hi tester – the problem is that the version of the heroku gem you are using does not recognize the ‘–buildpack’ option. Updating your heroku gem should fix it:

    gem update heroku

    Thanks for letting me know – I’ll add a note to the article.

  3. Hi,

    there are some missing steps that i found out too. Sounds like “heroku update” is required when your client is too old?

    Thank you for your help

    ————————first time i tried (does not work)———————————
    gem list

    *** LOCAL GEMS ***

    mime-types (1.17.2)
    multipart-post (1.1.3)
    rest-client (1.6.7)
    thor (0.14.6)
    vulcan (0.1.3)

    sudo gem install heroku
    [sudo] password for administrator:
    Successfully installed term-ansicolor-1.0.7
    Successfully installed addressable-2.2.6
    Successfully installed launchy-2.0.5
    Successfully installed rubyzip-0.9.4
    Successfully installed heroku-2.14.0
    5 gems installed
    Installing ri documentation for term-ansicolor-1.0.7…
    Installing ri documentation for addressable-2.2.6…
    Installing ri documentation for launchy-2.0.5…
    Installing ri documentation for rubyzip-0.9.4…
    Installing ri documentation for heroku-2.14.0…
    Installing RDoc documentation for term-ansicolor-1.0.7…
    Installing RDoc documentation for addressable-2.2.6…
    Installing RDoc documentation for launchy-2.0.5…
    Installing RDoc documentation for rubyzip-0.9.4…
    Installing RDoc documentation for heroku-2.14.0…

    sudo gem update heroku
    [sudo] password for administrator:
    Updating installed gems
    Nothing to update

    heroku create –stack cedar –buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git
    ! Name must start with a letter and can only contain lowercase letters, numbers, and dashes
    —————————-

    ————————–second time———————-

    heroku update
    —–> Updating to latest client… done

    gem update heroku
    Updating installed gems
    Nothing to update

    heroku create –stack cedar –buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git
    Creating high-mountain-8460… done, stack is cedar
    http://high-mountain-8460.herokuapp.com/ | git@heroku.com:high-mountain-8460.git

    ——————————————————————

  4. Interesting – gem update heroku worked for me. In any case, you need heroku client version 2.11.0 or later:

    $ heroku version
    heroku-gem/2.14.0
  5. I do:

    heroku create –stack cedar –buildpack http://github.com/metadaddy-sfdc/heroku-buildpack-nodejs.git
    Creating afternoon-lightning-2887… done, stack is cedar
    http://afternoon-lightning-2887.herokuapp.com/ | git@heroku.com:afternoon-lightning-2887.git

    AND

    git push heroku master
    Counting objects: 5, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 285 bytes, done.
    Total 3 (delta 2), reused 0 (delta 0)

    —–> Heroku receiving push
    —–> Node.js app detected
    —–> Fetching Node.js binaries
    —–> Vendoring node 0.4.7
    —–> Installing dependencies with npm 1.0.94

    Dependencies installed
    —–> Discovering process types
    Procfile declares types -> app
    —–> Compiled slug size is 11.7MB
    —–> Launching… done, v271
    http://xxx deployed to Heroku

    To git@heroku.com:xxx
    298a809..837363d master -> master

    So versions are not updating, any ideas?

  6. Hi mmstud – the most likely problem is that your Heroku client needs an update – what does heroku version tell you? You need version 2.11.0 or later. In most cases, gem update heroku will update the Heroku gem to the latest version; if that doesn’t work, then try heroku update.

  7. Hi Pat,

    Thanks for the post. I’m running into trouble with the support/package_node 0.6.1 step in your instructions. I’m using a direct clone of your repo and getting what appears to be an error in the ‘vulcan build’ portion of the script. It’s error-ing out with the following: https://gist.github.com/1543157.

    Any ideas?

    Thanks.

  8. Hi Matt – apologies for the delay in replying – I was away for the holidays. I’ll ping one of the Heroku gurus on this, see what I can turn up.

  9. Hey Matt – David Dollar, the Vulcan maintainer got back to me – the issue should be fixed in the latest Vulcan gem. Update and let me know how it goes.

  10. Would you think of making more updated unofficial nodejs versions, because it updates quite fast and it would be really helpful and time saving.

    btw Do you know if there is any way to keep an app that is running the newest nodejs version? Instead of creating a new cedar everytime.

  11. Hi Paul – Yes, I’ll create a new buildpack from time to time, but I don’t really have the bandwidth to keep up with the Node.js release train – as you say, it updates quite fast! The recipe is here for anyone to create their own, though.

    As for keeping an app running the newest nodejs version… You don’t need to create a new cedar. Just set the BUILDPACK_URL config var to a different git URL with heroku config:add and redeploy the app. I don’t think this is something you would want to do automatically, though, since Node can change significantly between versions…

  12. You can save a lot of time by just looking if the heroku team already prepared your node version:

    http://heroku-buildpack-nodejs.s3.amazonaws.com/manifest.npm
    http://heroku-buildpack-nodejs.s3.amazonaws.com/manifest.nodejs

    will show you the available versions in the official heroku repository. Now just clone the heroku buildpack repo, edit bin/compile and change the version numbers of node and npm accordingly. Commit and push and use this repo as your buildpack.

    I was unable to compile it myself but am still able to use node 0.6.8 with this approach.

  13. Nice one, Gregor!


Leave a comment