Engine Yard Developer Center

Upgrade NodeJS on the stable-v4 stack

Introduction

 

On the stable-v4 EY stack the default version of nodejs installed is net-libs/nodejs-0.10.38. While this version could be enough for some applications, a more up to date nodejs version is sometimes required. In this article we will outline the available options regarding nodejs.

The available versions of packages exist in the EY Gentoo portage tree. There, you can find and install the desired package. The tool to check which versions exist is eix. For example, in a stable-v4-2.0.129 instance the command eix net-libs/nodejs will output:

[U] net-libs/nodejs
Available versions:
(0) [M]~0.6.21-r1^t [M]~0.8.8-r1^t [M]~0.8.9^t [M]~0.8.11^t [M]~0.8.12^t [M]~0.8.14^t [M]~0.9.0-r2^t [M]~0.9.1^t [M]~0.9.2^t [M]~0.9.3^t
(0.6.21) 0.6.21-r2^t[1]
(0.8.16) 0.8.16^t[1]
(0.8.26) 0.8.26^t[1]
(0.8.28) 0.8.28^t[1]
(0.10.5) ~0.10.5^t[1]
(0.10.13) ~0.10.13^t[1]
(0.10.21) ~0.10.21^t[1]
(0.10.28) (~)0.10.28^t[1]
(0.10.30) ~0.10.30^t[1]
(0.10.38) (~)0.10.38^t{tbz2}[1]
(0.12.4) (~)0.12.4^t[1]
(0.12.6) (~)0.12.6^t[1]
{{debug icu +npm +snapshot (+)ssl}}
Installed versions: 0.10.38(0.10.38)^t{tbz2}[1](08:55:12 PM 11/09/2015)
Homepage: http://nodejs.org/
Description: Evented IO for V8 Javascript

* net-libs/nodejs-bin [1]
Available versions:
(4.2.1) 4.2.1 4.2.1-r1
(4.4.7) 4.4.7
(4.7.3) 4.7.3
Homepage: http://nodejs.org
Description: Ebuild for static binary build of nodejs

 

What this output actually means is that we have node-v0.10.38 installed (Installed versions: 0.10.38) and that other node versions are available for installation. At this point you may notice that there are 2 different packages for node: net-libs/nodejs and net-libs/nodejs-bin. These packages do the same work.

Their difference is that the net-libs/nodejs package will build nodejs from source while the net-libs/nodejs-bin comes as an already statically built package ready for use. Of course, as in most of our portage packages, the binary for net-libs/nodejs package already exists in our portage, so upon installation you will not have to wait for the source code to be built.

You can check if a binary for a package exists by executing for example emerge -pu =net-libs/nodejs-0.12.6. This will output:

Calculating dependencies... done!
[binary N ~] net-libs/http-parser-2.5.0 USE="-static-libs"
[binary N ~] dev-libs/libuv-1.5.0 USE="-static-libs"
[binary NS ~] net-libs/nodejs-0.12.6 [0.10.38] USE="npm snapshot ssl -debug -icu"

 

This output informs us that all the dependencies and the package itself exists as binaries in our portage tree. Lastly, you can check which node version the OS has selected by executing eselect nodejs list. The asterisk next to the version is the selected one. Of course node -v and npm -v are also useful for checking the node version.

 

Installing node versions that exist in portage

In order to install one of the above packages you can use the custom packages recipe. While this recipe will install the node package for the specific version you require, it won't select that version. For example, using the custom package recipe with the following content as packages/attributes/packages.rb:

default[:packages] = [{:name => "net-libs/nodejs-bin", :version => "4.7.3"}]

will install node-v4.7.3, but the default node-v0.10.38 will still be used. This can be checked via eselect nodejs list. While we can manually set the node version to the one we installed via eselect nodejs set 4.7.3, this version will change upon the next chef run, setting the node version back to the default node-v0.10.38. In order to make our changes persist the chef runs, we should add the following content in the cookbooks/packages/recipes/default.rb file:  

#
# Cookbook Name:: packages
# Recipe:: default
#

node[:packages].each do |package|

ey_cloud_report "package-install" do
message "Installing #{package[:name]}-#{package[:version]}"
end

enable_package package[:name] do
version package[:version]
end

package package[:name] do
version package[:version]
action :install
end

if package[:name]=== 'net-libs/nodejs' || package[:name] === 'net-libs/nodejs-bin'
execute "selecting #{package[:name]}-#{package[:version]} as default" do
command "eselect nodejs set #{package[:version]}"
action :run
end
end
end

 

Installing node versions that do not exist in portage

In this case we are going to utilise the portage in order to add an ebuild that will install a statically built node package. In order to check the available versions of node/npm we can check here, since npm comes bundled with node. The package we are after is a version of net-libs/nodejs-bin because an already statically built node is the safest (in regards to dependencies) and quickest (since it will not require building) approach. To do so we will need a custom chef recipe. The recipe is the custom_nodejs .

After the recipes apply, the verification of the node version installed shows:

ip-10-0-3-82 ~ # node -v
v10.12.0

ip-10-0-3-82 ~ # npm -v
6.4.1

ip-10-0-3-82 ~ # eselect nodejs list
Available Node.js symlink targets:
  [1]   0.10.38
  [2]   10.12.0 *

 

Considerations

While the above option will let you install the required node version, it is still an approach of upgrading only the needed part of the platform (just the node package). In many cases this may not suffice, since node modules often need compiling their cli tools, where other platform packages get involved, like gcc or media packages.

The way to overcome such dependency issues is by migrating your environment to our newer stable-v5 stack. This upgrade needs effort but regarding node, it will give you the following advantages:

  • out of the box node support up to version node-v10.10.0
  • more recent stable gcc version
  • existing yarn package
  • maintainable package dependencies due to updated ecosystem  

These advantages ensure that a stable-v5 environment will be able to keep up with the ever-changing node requirements.

Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

Please sign in to leave a comment.

Powered by Zendesk