Two weeks ago, I’ve set up an extensive test suite for my Node.js package detect-character-encoding. Since the package’s main job is to compile ICU using GYP, it’s quite fragile when it comes to different operating systems and Node.js versions. To reduce the amount of manual testing, I’ve created Dockerfiles to cover various Node.js and Ubuntu versions.

Thanks to NodeSource’s installation scripts1, it’s quite easy to install Node.js on Ubuntu. For example, to install Node.js v6:

$ curl -sL | sudo -E bash -
$ sudo apt-get install -y nodejs

However, on Ubuntu 18.04, node --version will print v8.10.0.

As it turns out, Ubuntu 18.04’s main repositories include Node.js v8. When you instruct APT to install nodejs, it will install the newest version available: Node.js v8 (instead of v6).

To install Node.js v6 instead, you’ll need to use APT Pinning to prioritize NodeSource’s repositories over Ubuntu’s main ones. To do so, create /etc/apt/preferences.d/nodesource with the following contents:

Package: nodejs
Pin: origin
Pin-Priority: 600

Ubuntu’s main repositories have a lower priority of 500, therefore, the above configuration will cause to be preferred for the nodejs package. However, if a newer version is already installed, it will not be downgraded.

If you’d like to always install Node.js from NodeSource’s repository—even if doing so forces a downgrade—you can specify a priority of 1000. The apt_preferences man page explains these priorities in more detail.

You can find the final Dockerfile for detect-character-encoding on GitHub.

  1. If you’re not a fan of curl | sudo bash, there’s a manual installation method. Since this script is only executing inside Docker containers, I didn’t mind as much.